Synopsis

As power constraints continue to impact traditional chip design, and custom design costs become prohibitively expensive, the only economic way for companies to produce new ASICs is to embed and reuse designers’ knowledge. In fact, most companies are already doing exactly that by creating in-house “generator” scripts.

We have developed an extension to SystemVerilog for designing digital and mixed-signal chip generators. This chip generator technology (“Genesis2”) changes the programming paradigm to allow designers to embed their knowledge when constructing RTL design modules. Genesis2 enables the designer to simultaneously code in two interleaved languages for a rich, extensible software environment: one language generically describes the hardware proper and the other one decides what specific hardware to instantiate. This process allows for greater flexibility in the initial construction and later elaboration of the design without compromising strict synthesizability rules for the functionality of the module. Moreover, Genesis2 maintains the same object-oriented, hierarchical system and instance scopes of the design hierarchy.

Put differently, Genesis2 enables not only an easier, standardized method for creation of module generators, but also aggregates those unit level generators together into a full chip generator. Ultimately, Genesis2 enables users to design an entire family of chips at once using a chip template that is then elaborated into multiple different per-application customized chips.

Download and save the file. Say the tarball is called r#####.tar.bz2 and you put it in a folder called $GENESIS/

Unzip the file:

cd $GENESIS
tar -xjf r#####.tar.bz2 -C ./

Now you should see a folder named r#####/Genesis2Tools that contains three sub-folders: bin, demo, gui, Info, PythonLibs and PerlLibs. The demo contains a few small design examples for you to play with/get started, including makefiles.

Add Genesis2 (and GUI) to your execution path, and some key libraries that it uses: simply type (or add to the end of your .cshrc file)

Getting Started With Genesis2

Setting Your Environment

Setting Genesis2 Mode for Emacs/Xemacs

If you use emacs or xemacs and would like to use genesis2-mode, download File:Mmm.tar.bz2 and then...

Unpack the mmm files and directory:

tar xjf Mmm.tar.bz2

Install the new code in your .emacs and/or .xemacs/init.el file(s):

./mmm-install.csh

Note that mmm depends on the pre-existence and availability of
verilog-mode and perl-mode (not cperl-mode) in your emacs. Most
versions of emacs already have these built-in. Otherwise, e.g. google
"verilog-mode" and download from one of the places that offer it.

If you don't like genesis2 mode, you can just as easily make .vp files
open in verilog mode, in which case perl lines will simply appear as
comments.

Example

In case of failure

Check your emacs init file(s) ~/.emacs and/or ~/.xemacs/init.el file
to see if the following code got added correctly at the end.
Particularly check to see that the correct directory was added in
place of /home/mydir/mmm and that
e.g. /home/mydir/mmm/mmm-genesis2-mode-init.el exists is readable.

This version changes the highlighting of //; and `, and with the latest vim-perl file it improves the highlighting of Perl code slightly.

Missing Perl Libraries?

Genesis2 is written in Perl. However not all Linux distributions are born equal and as a result, some machines lack certain Perl Libraries needed by Genesis2. In all cases reported to us, we added the missing libraries as part of the distribution so theoretically, you should not need to do anything. So far, libraries that I have seen missing include XML::Simple and PAR and their dependencies.

All the libraries used in Genesis2 are libraries that are freely available from CPAN. To install these libraries simply follow the steps below.

Ubuntu (requires root/sudo permission):

apt-get install libxml-simple-perl

Or

apt-get install libpar-perl

Generic Method:

Login as root

If you cannot login as root you may also install these modules locally, but you first need a your cpan distribution to be 1.9463.

Alternatively you can also follow the instructions here: "Installing Perl modules without root access". This webpage teaches how to create a local::lib, which sets everything up so you can install distributions from CPAN into your home directory. This means you won't need root access, and ensures that anything you install will not interfere with the either the system Perl or any other users.

Open a CPAN shell:

perl -MCPAN -e shell

Install a package:

Example 1: Install the library XML::SAX (required by XML::Simple). Make sure to answer yes for installing all library dependencies!

cpan> install XML::SAX

Install the library XML::Simple

cpan> install XML::Simple

Example 2: Or Install the library PAR::Packer

cpan> install PAR::Packer

Genesis2 File Types

Main File Types

SomeModule.vp And SomeIncludeFile.vph Files

These are the user's files. That is, when you come to write a hardware module that you want Genesis2 to elaborate, you should write it in a file named base_module_name.vp (or base_module_name.svp if you like the SystemVerilog suffix notation better). For example, if the module name is onehotmux, it should be placed in a file named onehotmux.vp.

Included files should be named whatever.vph. In fact, this requirement is not real and whatever.anything or even whatever would work. However, for nice coding style, and for xemacs verilog mode to work nicely, the whatever.vph is recommended.

New Feature -- Special File Extensions For SystemVerilog C and TCL :

Use file.svp and file.svph for SystemVerilog files and headers

Use file.cp or file.cph for C files and headers (for High Level Synthesis)

Use file.tclp or file.tclph for TCL files and headers

'genesis_work' Directory And SomeModule.pm Files

Genesis2 generates intermediate Perl module files (Given the file filename1.vp, Genesis2 would generate filename1.pm). These files are generated into a newly created folder named 'genesis_work'. Typically there is no reason to look at these files, except for extreme cases for debugging of parsing errors that had abscured error messages.

Note that Genesis2 works in two stages: First all the .pm files are generated. These files are, in fact, a complete object oriented program in Perl, where each module represents a module generator. Then, after all the Perl modules are created, Genesis2 executes the newly created Perl program that in turn generates Verilog.

The final type of file of interest is the generated verilog file. This code should consist of only verilog, and will eventually be fed to VCS/dc_shell/other tools.

Note: For every somemodule.vp input file, there may be more than one verilog file generated. If somemodule is instantiated in different places using different parameters, each different instance would be uniquified. The resulting verilog files would be named somemodule_unq0.v, somemodule_unq1.v, etc.

Program.xml File

The XML input program has a very simple structure. Yet, one has to remember that XML is best if read/written by machine and not human. The absolutly best way to get started is to let Genesis2 run with the -hierarchy outfile.xml flag set. This will create a "small_" output xml representation which can serve as a template for creating the input XML program. It will also generate a complete output xml representation which is a superset of the input xml representation, with much more information, and can also serve as a program template (when used as input, Genesis ignores the extra meta-information). The "small_" version is more useful for human manipulation, but when GUI or optimization tools are added to the flow, the latter version is usually preferred. See Genesis2SchemaXSD for a complete XML schema!

Having said that, the following is a description of the input XML schema:

HierarchyTop: There is a single root element which represents the top module of the design (since the top module is never instantiated, it is referred to by HierarchyTop and not by an instance name). A minimal (but legal) input XML structure would contain the following text:

<HierarchyTop></HierarchyTop>

General tree structure: For each module instance in the hierarchy (including HierarchyTop) the following recursive structure can be used. It must have an InstanceName element (except for the HierarchyTop), and it can optionally have Parameters and SubInstances elements. Omitting the Parameters or the SubInstances element is ok. However, omitting the InstanceName will result in an error!

SubInstances: (Optional) A list of zero or more SubInstanceItem elements that represent the sub-instances in the current hierarchy level. The same rules apply recursively for each of these elements. Note that if an instance is encountered during elaboration, but the corresponding SubInstanceItem is missing from the XML tree, it will be assumed that that instance uses the default parameters or the instantiation line parameters, as noted in the .vp files. If a SubInstanceItem element that does not correspond to any instance in the design is encountered, than it is simply ignored.

Parameters: (Optional) A list of zero or more ParameterItem. Note that if a ParameterItem is missing from the list, it is assumed that its value is not overwritten by XML. If ParameterItem exists for a parameter that is not defined in the .vp file, it is simply ignored. Of course, two ParameterItem elements carrying the same Name will produce an error. Each myValue of a parameter myParam would be written as:

For Parameters, note that more complicated data structures are also supported. Simply replace the Val element with the HashType to show that a parameter is a hash rather than a string/scalar or with the ArrayType to show that a parameter is an array rather than a string/scalar. Array of hashes and hash of arrays (or any recursive combination) is also supported. Finally, an InstancePath element can be used to express that a parameter represents a reference to a particular instance in the design hierarchy (i.e., it is a pointer to another object).

Each ArrayType contains a list of zero or more ArrayItem elements. An empty array is an ArrayType with no internal ArrayItem. Each ArrayItem must contain a Val OR HashType OR ArrayType OR InstancePath element. (see example next)

Each HashType contains a list of zero or more HashItem elements. An empty hash is a HashType with no internal HashItem. Each HashItem must contain a Key element AND a Val OR HashType OR ArrayType OR InstancePath element. Of course, two HashItem elements carrying the same Key will produce an error. (see example next)

InstancePath is a string that represents a complete path such as "top.dut.unit1"

Config File Via Perl Script

XML config files are the official and formal representation of the design. However, it is sometimes useful to have an easy method of overriding a parameter value here and there. For these purpose, it is often convenient to be able to write a short script that manipulates those values. Genesis2 accept those scripts using the -cfg command line flag as described here. Many configuration scripts may be applied one after the other to cover different aspects of the configuration. If a parameter value binding is overridden, a warning is issued. Note that parameters values that are configured through the configuration file will NOT override definitions by the XML file (actually XML definitions override the Perl configuration scripts). Also note that parameter values that are configured through the config file will NOT override parameters that were already bound using the generate statement in the .vp files, since that assignment has higher priority. For a complete explanation of parameters override priorities see here.

Basic Config Files

Basic configuration files are any simple Perl script which uses the following predefined functions:

configure($path_to_param, $override_value) is the main function to enable overriding parameters. Example:

exists_configuration('path.to.param') quarries weather 'param' exists in path 'path.to.param'. It returns 1 if exists and 0 otherwise. Exists here means that that parameter configuration was previously defined through the configuration scripts. Since configuration scripts are executed long before the design is elaborated, it does check the existence of the parameter in the actual design. See get_configuration (next) for an example.

get_configuration('path.to.param') returns the value of a previously configured parameter. Note that 'previously configured' means it was previously configured via the configuration script. If the parameter was not previously configured, an error will be thrown (because parameters can be defined to have an 'undef' value, the only way to check if a parameter was previously configured is through the exists_configuration function as described above).

error("error message") print the error message as well as the line number and file, then exits with error code 7

Config Libraries

It is sometimes desireable to create project-specific API. For example, create a few high level functions that can configure many internal parameters. Doing that with Genesis2 is super simple: Simply create your favorite package that holds the project specific configuration functions (e.g. CMP_Builder.pm), and from your configuration script use Perl's 'use' mechanism to call it. To allow CMP_Builder access to the same configuration methods as described above in Genesis2#Basic_Config_Files, CMP_Builder must use the predefined Genesis2 base package 'Genesis2::UserConfigBase'. Example:

Additional Output File Types

Genesis2 produces some additional outputs, on top of the Verilog files: A log file (using the -log name.log flag), a dependent list (using the -depend depend_file_name flag), a product list (using the -product product_file_name flag), and an xml hierarchy representation of the design (using the -hierarchy hierarchy_file_name flag).

Log File

By default, Genesis2 produces a log file called genesis.log. The name can be modified using the -log filename switch. On top of capturing all messages from Genesis2, the log file includes both Genesis2's release information and the complete command used for that run.

Depend List

List of the source .vp files and included .vph files that were used by Genesis2

Product List

This very important list is a list of the generated verilog (.v or .sv) files. This list is convenient, for example for use as input to downstream tools such as VCS, or for use in makefiles. Note that the list is arranged in reverse hierarchical order which means the lowest level modules are listed first, and the top module last. The reason for this reversed order is so that it can be used for compilation by downstream tools.

Genesis2 produces three lists: one for all files generated (for validation/simulation); one for synthesis subset; and one with testbench only (for gate level simulation). The synthesis subset is determined by the -synthtop flag as described here. The name of the 'product' list of generated files is set by the -productcommand line flag and defaults to genesis_vlog.vf. The name of the 'for-synthesis' product list is set by taking the name of the 'product' list, and adding .synth. between the file name and its suffix. The name of the 'verif-only' product list is set by taking the name of the 'complete' list, and adding .verif. between the file name and its suffix. For example, for the default 'product' file name genesis_vlog.vf, the 'for-synthesis' file name would be genesis_vlog.synth.vf and the 'verif-only' file is genesis_vlog.verif.vf'.

Hierarchy Out

The XML hierarchy output representation is almost identical to the input XML program. It also has a very simple structure, but it adds more information about source and target modules and files. In addition to providing useful feedback to the designer, the hierarchical XML was designed to be used as a template for the XML input program.

To avoid duplicate instructions, and since the output XML is strictly a superset of the input XML, please refer to the input xml program section for the basic structure of the XML tree. This section will highlight the additional information that is provided in the output XML schema. An example of a hierarchical outfile follows. Note that structure-wise:

General tree structure: For each module instance in the hierarchy (including HierarchyTop) the following recursive structure is used. It has a BaseModuleName, SynonymFor, InstanceName, ImmutableParameters, Parameters, SubInstances, UniqueModuleName

BaseModuleName: The name of the template module before uniquification

SynonymFor: If the base module (or template) is just a synonym for some other base module (created by using the synonym function), the field SynonymFor appears in addition to the BaseModuleName. The SynonymFor value is the base module name for which this module is synonym. If module ModuleC is synonym to ModuleB which is in turn synonym to ModuleA, than the value of SynonymFor is the basis of the chain---ModuleA.

Parameters: A list of zero or more ParameterItem elements. In addition to the Name and Val fields as described for the input xml schema, the output XML schema also has a Doc and a Range elements, but only for simple Val parameters (i.e., simple parameters that are numbers or strings but not arrays or hashes or pointers).

Doc: A documentation or description of a parameter.

Range: An allowed range for a parameter value. The Range element support two mutually exclusive options:

List: A list of allowed values. Or,

Min and/or Max and/or Step: At least on of Min or Max element and optionally a Step element.

Opt: This field may only show up if a Range<i> field was used. It is optional however. Allowed values are {Yes, No, Try} when it shows in the <i>Parameters list. Allowed values are {No, NotRightNow} when it shows in the ImmutableParameters list.

SubInstances: A list of SubInstanceItem elements that represent the sub-instances in the current hierarchy level. See more in the input xml schema section.

UniqueModuleName: The name of the generated module after uniquification

CloneOf: If the instance is a clone of another instance, the field CloneOf appears instead of the fields Parameters, ImmutableParameters and SubInstances. CloneOf would then have a sub-element, InstancePath, that holds the a text path to the original instance (e.g., top.dut.subinst.subsubinst).

"small_" Hierarchy Out

Tools need the complete XML (hierarchy_out.xml), but for humans it is quite annoying... right?
So Genesis produces both the hierarchy_out.xml (for tools) and small_hierarchy_out.xml (for more human tools). The "small_" version, still contains the entire hierarchy, but only prints tweakable parameters (i.e. skips ImmutableParameters) and also skips other meta data that most humans don't care about (thus probably half the size or less).

The result is a minimalistic XML file that conforms with the input xml structure. Refer to the input xml program section for the basic structure of the XML tree.

"tiny_" Hierarchy Out

The "tiny_" version of the XML (e.g., tiny_hierarchy_out.xml) is an even more minimalistic structure than the "small_" file. It contains only information about parameters and nothing else, but it contains only information about parameters whose value, during the last round of generation, was set from the input xml. That is, it contains only parameters that are not at their default value. In most cases, this is
equivalent to the input XML file, unless the input actually contained unused parameters (eg for modules that no longer exist in this round of generation).

The result is a minimalistic XML file that conforms with the input xml structure. Refer to the input xml program section for the basic structure of the XML tree.

Example of Full Hierarchy Out

Next is an example of a complete XML hierarchy. In this example, the top level instantiate 2 Wallace trees. In addition, it instantiate two clones of those Wallace trees (only for the purpose of this example). In addition, (again, for the example only) each Wallce module has numerous parameter definitions of various kinds.

genesis_clean.cmd

This file contains commands to clean all files generated by Genesis2. To use it simply source it:

>> source genesis_clean.cmd

Source Code Structure For Using Genesis2

The code structure for using Genesis2, just like in Genesis 1, is whatever target language your code should generate annotated with directives that tell Genesis2 how to expand the text.

In our case, the target language is Verilog or System Verilog. The meta language that is used on top is simply Perl. You now have the strength of Perl in your hands when you write verilog. Use it wisely.

Perl Escapes

There are two types of Perl escapes that can be used:

Full Line Escape ( //; Perl text 'til end of line )

This escape sequence tells Genesis2 that the entire line is Perl. To use it, simply type ' //; ' (i.e. line comment followed by a semi-colon) at the beginning of the line (white space before is also allowed).

Note that this would look like a comment to the xemacs's (or any other editor's) Verilog mode. Hence, coloring and indentations would not be influenced.

Descriptive example:

This is regular (though not legal Verilog) text that would go directly to output.
// This is also regular text that would go directly to the output as a Verilog comment.
//; This is text that would be evaluated as a Perl script (and generate a syntax error ;-))

This escape sequence tells Genesis2 that a part of the line, which is delimited in-between two ' ‘ ' (i.e. grave accent) signs, is to be evaluated using the Perl interpreter. Unlike the full line escape, in the partial line escape, the result of the Perl evaluation is to be printed to screen.

Note that this would look like a "tick-define" to the xemcas's (or any other editor's) Verilog mode. Hence, coloring and indentations would not be influenced.

Note About The Perl print Function: It is some times convenient to use the built-in Perl print function. Note that for convenience, printing is done by default to the output file (i.e. the Verilog modulename.v file). If you wish to print progress or debug statements that need to go to the screen use print STDOUT "your text here\n" or print STDERR "your text here\n".

Old Verilog Style Macros Escapes

Using old style tick macros from Verilog/System Verilog is highly un-recommended for many reasons. Instead one should either use variables or genesis2 parameters. If you still must use them, I guess you can but don't say I didn't warn you! Simply escape your tick as follows:

`this is a perl escape`
\`but this is a verilog old style tick

Special Built-in Methods

As mentioned before, the entire effort of creating a tool like this is to enable scopes, enhanced parameterization and most importantly uniquification of modules. For this reason, there are a handful of pre-built Perl methods that were defined.

There are no other directives you need to remember. It is all Verilog annotated with Perl from here on.

Data Structure Related Methods

sub get_parent

Returns a pointer to the parent instance

//; my $parent = $self->get_parent();

sub get_top

Returns a pointer to the top level of the hierarchy

//; my $top_module = $self->get_top();

sub get_subinst

Returns a pointer to the object of a sub instance (by name)

//; my $subinst_of_someinst = $someinst->get_subinst($subinst_name);

sub exists_subinst

Returns a 1 if a sub instance (by name) exists. Zero otherwise.

//; my $subinst_exists = $someinst->exists_subinst($subinst_name);

sub get_subinst_array

Returns a handle to an array of sub instance objects that match a pattern

Return only instances that has a parameter who's name matches the regular expression The HasParamRegex arg can be either a string (e.g., 'Width') or an a string array ref (e.g., ['Width', 'Radix']). Note that in the string array case, we search for instances that has a param that matchs regex1 AND a param that matches regex2 AND...

ApplyMap

If you have some complex way of determining if an instance should be returned, you can create your own function that accept/reject an objects. Your function must return 0/1. E.g., sub func{ my $obj = shift; return ($obj-iname eq 'ofer'); }

API method that returns a complete path to the given instance object. An instance path has the strict format of <top_module>.<subinst>.<subsubinst>.... For example: top.dut.regfile.addr_flop.

//; my $inst_path = $inst_obj->get_instance_path();

get_instance_obj

API method that accepts an instance path (or an instance object) and returns the corresponding instance object. An instance path has the strict format of <top_module>.<subinst>.<subsubinst>.... For example: top.dut.regfile.addr_flop.

//; my $inst_obj = $self->get_instance_obj($inst_path);

synonym

API function/method call that helps you make fancy names for your module templates.

NOTE: This function manipulates the names of templates, and therefore the names of the generated modules and the generated verilog files). Not the names of instances of those modules.

//; synonym("sourceTemplateName", "renamedTemplateName");

For example, say you have addr.vp that has a bunch of parameters. And say you want to create multiple versions of it that you can easily grep for (e.g., in your physical design scripts). So you don't want those elaborated modules to be called adder_unq1, addr_unq2, and so on. Instead you want fancy_adder and simple_adder. For the case stated above this would be:

Therefore the following code will result in the generation the verilog modules adder_unq1, adder_unq2 but also simple_adder_unq1, super_fancy_adder_unq1 and super_fancy_adder_unq2, even though simple_adder_unq1 is functionally equivalent to adder_unq1 and super_fancy_adder_unq1 is functionally equivalent to adder_unq2:

Note that you could also create adder, simple_adder and so on (i.e., without the "_unq1" suffix) by using the generate_base call (see below), as long as you only generate those once in your design. Otherwise Genesis will through an error message and stop.

Parameterization Methods

sub parameter

This is the main call for defining a new parameter (just like defining a parameter in SystemVerilog), and specifying its default value, documentation and range. Note that using the parameter, parameters can only be defined inside the module to which they belong (i.e., a call to $someOtherInst->parameter(...arguments...) will cause a genesis generation error). Much like SystemVerilog, parameters can also be overridden at instantiation using the generate method as shown below. Definition at instantiation time overwrites definitions done within the module (just like in Verilog). As a middle ground, parameter definitions that are not bounded by instantiation can be set using the input XML configuration file. More details can be found here.

Notes:

The call to parameter can be done in either method- or function-call format.

Style tip: Often, we would like to declare a parameter that MUST be overridden at instantiation or from external configuration. One way to do that is to provide a default value which is out of range. If the parameter value is not overridden, Genesis will issue an error. For example:

API method for checking whether a certain parameter has been defined in a module (without defining it). Can operate on $self or any template $obj that was previously generated. Note that specifying a parameter within a generate call, from the XML, or configuration file, is not the same as defining it, and exists_param will evaluate to false in that case.

//; my $exists = $self->exists_param('SomePrmName');

sub list_params

API method for extracting a list of params defined in a module. Can operate on $self or any template $obj that was previously generated.

//; my @list = $self->list_params();

sub get_param

API method for extracting a parameter's value from the parameter's registry. This sort of definition is useful if your module needs to read a parameter from a different module:

//; my $val = $other_module->get_param('prm_name');

It should be defined with 'parameter' call (not just in the XML) or you will get an error.

sub get_top_param

API method for extracting a parameter's value from the top level parameter's registry.

Module Instantiation Methods

sub generate

The main function call for generating (and later instantiating) a new module. Note that this call on its own would not print anything to the output module. Rather, it will return a pointer to the instance module ($newObj in the code bellow). Use the $newObj->instantiate() and other methods as described above to query this new module and then decide what to print to the generated module code.

Note: This function is syntactic sugar for $self->unique_inst(...)---the main method call for generating (and later instantiating) a new module.

This is syntactic sugar for $self->clone_inst(...)---A method for replicating a module based on an existing instance.

//; my $clonedObj = clone($src_inst, 'new_inst_name');

sub generate_base

It turns out that some people want to generate only the base module. For example, Mrs. F. in her mixed signal chip wanted to generate only one type of her analog.vp module as that module needs to be replaced with an analog macro at PNR. Furthermore, she prefers if it remains with the name analog and not be renamed to analog_unq1 as genesis generally does at elaboration. To facilitate that, we created the new generate_base function. generate_base will generate the base module and not anything else.

Notes:

If you generate multiple instances of a module using generate_base, genesis is still smart enough to make sure that you are always generating exactly the same module, and otherwise through an error that you can't generate the same un-uniquified module twice in two different ways.

You CAN use both the unique instantiation (i.e., generate) and the non-unique instantiation (i.e., generate_base) in the same code. No contradictions here.

But it is actually better to use instantiate. See sub instantiate, below.

sub mname

Returns the uniquified module name. This task is especially important since whenever we declare a new module we don't really know whether or not it is going to be uniquified, and how many uniquifations of this module already happened. This enables us to leave the dirty work for Genesis. Note that this is syntactic sugar for the older style method get_module_name

Returns the source file name from which an object was generated. This is the name of the template, before uniquification and before synonyms were applied. Note that this is syntactic sugar for the older style method get_source_name

It is always a good habit to check the input (that can many times come from a user filling an xml form), and printing errors or warnings accordingly. See the section about Auxiliary Methods for the use of the error and warning predefined methods.

Debug messages to the verilog file

If you want to print debug messages during elaboration, such that they go to the output verilog file, one way is to just use simple text with inline Perl escapes, since simple text is printed to the verilog file by default. You can make these statements a verilog comment so they don't disturb compilation.

1. This text goes as is to the verilog file... but would cause a verilog compile error since it's not legal verilog
// 2. This text also goes to the verilog file... but no compile errors this time since for verilog it's a comment
//; print "3. This is a Perl print command that prints this line to the verilog file... expect verilog compile errors...\n";
//; print "// 4. This is also a Perl print command. This text also goes to the verilog file... no compile error this time\n";

Debug messages to the screen

If you want to print a debug message to the screen (printed during elaboration time), use one of the following...

//; print STDOUT "This message goes to standard output. It does NOT go to the verilog file\n";
//; print STDERR "This message goes to standard error output. It does NOT go to the verilog file\n";

A Word About Genesis2 Elaboration Order And Parameterization

Elaboration Order

Elaboration is done as a depth-first search of the hierarchy. That is, the top module would start to be elaborated, until the first generate call is encountered. Then Genesis2 will recursively turn to elaborate the module which is being instantiated. This process repeats recursively, until the leaf instances are elaborated. (Behind the scenes, this strategy makes it very easy to first generate the lower levels of the hierarchy, uniquify when needed, and then tell the upper levels what is the name of the uniquified module and instantiate it.)

Parameter Value Binding Priority

Parameters in Genesis2 are very similar to parameters in SystemVerilog but very much enhanced. For example, as shown next, a Genesis2 parameter type can be scalar, string, array, hash or pointer to some instance, and any combination of those. It is important however to understand the way parameters are bound to a value. In SystemVerilog for example, some of the binding mechanism is bad (defparam which will be deprecated according to the IEEE Standard).

Genesis2, as an extension of SystemVerilog for creating Generators, puts a lot of emphasis on late binding of parameters, even those that are buried deep in the design hierarchy. The following are the various ways to bind / override parameter values. Note the distinct (and unambiguous) order.

A parameter value is assigned by default to the value given in the parameter definition in the module (.vp file) using the parameter method mentioned above.

Parameters that were declared with one value (val1), can be overwritten by the external Perl configuration input file with a different value (val2), as described here

Parameters that where declared with val1, which may or may not been overridden with val2 from the Perl config file, can be further overridden with val3 from an XML configuration file as described here

Parameters that where declared with val1, which may or may not been overridden with val2 from the Perl configuration file, and may or may not been further overridden with val3 from an XML configuration file can be even further overridden from the command line with the command line directive -parameter top.dut.param=val4 as described here

Finally, parameters can also be added or overwritten at instantiation time (this is similar to Verilog 2001)

The rationale is that this enables the designer to give default values to parameters. It enables changing those values later from external configuration files (for example by picking them using an optimizer). But it also enables forcing of the parameter values by the instantiating module if compatibility is required (for example interface bit-widths).

The strongest parameter binding is when the declaration of the parameter in its module as described in (1), also annotates it with Force=>1. That makes it an immutable parameter for any of the methods enumerated above.

Note that these are the only ways to set parameters values! Querying the values of parameters can be done at any point, once the instance has been created of course (using the generate method.)

Note that parameters behave as constants! When you assign/get a parameter value, the value is being copied (deep copy if the parameter is a reference to a data structure).

Note that you can use parameters to communicate values to parent modules (not just to sub-instances)! Once a parameter is defined, it can be read from anywhere in the hierarchy using the instance object (e.g., //; my $param_from_someone_else = $someone_else_instance->get_param('param_name');).

Parameter Types

A parameter in Genesis2 can be either a string/scalar, an array, a hash, a pointer/handle of an object. Any combination nested to what ever level (silly example: hash of arrays of arrays of pointers) is also supported.

Important notes:

For hexadecimal numbers, use the notation 0x<0..9a..f> (e.g., 0xfff, 0xdeadbeef)

For binary, use the notation 0b<0..1> (e.g., 0b1100, 0b0011001)

No need to worry about pointers as parameters are always copied (using deep copy)

Please don't use weird parameters like "assign my_signal = your_signal". Try to make the leaf elements of any parameter simple strings or scalars.

For security reasons, parameters can only be composed out of alphanumeric characters, plus a few other characters like arithmetic +-/*, spaces, etc. No ; (semicolon) and no (parenthesis) and no {curly-braces}.

Invoking The Genesis2 Tool

If you followed the installation instructions, Genesis2 should be at $GENESIS_HOME/PerlLibs/Genesis2/Genesis2.pl.
At Stanford, that expends to /cad/genesis2/rxxxxx/PerlLibs/Genesis2/Genesis2.pl.
For help on invoking the tool type Genesis2.pl -help.

Note that though there are two distinct stages in Genesis2: parsing and generation. One can call the script once with both the -parse and the -generate flags on. Genesis2 would perform parsing and then move immediately to generating.

Parsing Mode

Parsing mode performs the first transformation, from Verilog annotated with Perl code (.vp files) to an object oriented set of Perl packages. Each Perl module (.pm file) is a code generator for its corresponding verilog module (.v file), but verilog generation is not yet done at this stage.

Generation Mode

Generation mode is the stage where Genesis2 is asked to start doing the actual elaboration starting from some specified top level (does not need to be the absolute top level of your design).
This is when the .pm files generate the .v files.

Graphical User Interface and Demo

Extending Genesis2 With Homemade Perl Libraries

One of the best things about using Perl as the language on top of Verilog, is that it is very easily extended. This means that one can use any Perl library in the world as part of the knowledge base that create a module's micro-architecture.

Adding A Perl Built-in Library

Simply put a "\\; use LibraryName;" in your text, just as you would do for any Perl script. Example of using the POSIX library (used for the mathematical ceiling function):

Adding Your Own Perl Libraries

Adding Libraries To The Path

With time, you may want to add more Perl libraries (i.e., .pm files) to extend genesis with functions you use often. Say (for example) you place those under /Path/To/MyGenesisLocalLibs/*.pm. To tell Genesis2 (and all your modules) where to search for those packages, do one of the following:

Just add the following line to your environment so that Genesis knows where to look for them:

setenv GENESIS_PROJECT_LIBS $GENESIS_HOME/MyGenesisLocalLibs

Dynamically notify Genesis2 by adding the command line flag -perl_libs /Path/To/MyGenesisLocalLibs as described here.

Adding Library Components to The Namespace

Once the library folder is in the path, there are two ways for your Genesis2 modules to get the functions of a home-made library into their name space. For example, if your library is MyLib.pm:

(Recommended Method -- Selective Inheritance of Selective Functions and Methods Via 'Use') Typical Perl "use" system: (preferred way for not polluting the name space)
In your module that requires the additional package MyLib (e.g., your file flop.vp) add a line that reads:

//; use MyLib;

Now you can call MyLib::funcName($args).

If you want, some (or all) of the functions may be embedded in the current namespace (so you can call funcName($args) without the MyLib:: prefix or even call inherited methods as $self->methodName($args)). To enable that, you need to use Exporter and add these function/method names to the EXPORT or EXPORT_OK lists in your MyLib.pm file using the syntax:

(Less Recommended -- Selective Inheritance of All Methods Via @ISA)
You can tell all Genesis2 modules to inherit ALL methods from the MyLib module. This will allow you to call MyLib functions and methods as your own using either MyLib::funcName(args), $self->methodName($args), or funcName($args). To do that, the code in MyLib.pm stays the same as described above, and you simply add to your module (.vp file) the following lines:

//; use MyLib;
//; push (@ISA, "MyLib");

(Only Do If You Know What You're Doing -- None Selective Inheritance via @ISA)
In rare cases, you will want all your modules (.vp files) to inherit some function or method from MyLib.pm.
In order to do that, we force the UniqueModule (which is the base class of all Genesis2 modules) to inherit from the MyLib package. Then, each and every module in Genesis would be able to call $self->methodName(args). To activate this inheritance your MyLib.pm code should read as follows: