Genesis2

From Genesis2
Revision as of 07:09, 18 April 2012 by Shacham (talk | contribs) (Working On Stanford Machines)

Jump to: navigation, search

Contents

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.


The rest of this page describes Genesis2 and how to use it.

Comments are welcome: Ofer Shacham, Ofer Shacham

Installing Genesis2

The following are instructions for installing genesis2 on your machine. If you're at Stanford however, skip this section because Genesis2 is already installed on /cad and the environment is sourced though the modules system.

If you are not at Stanford, send me an email to get the tar ball and then:

  1. Save the file. Say you put it at $GENESIS2_HOME
  2. unzip the file:
 cd $GENESIS2_HOME
tar -xjf Genesis2--r#####.tar.bz2 -C ./
  1. Now you should see a folder named r##### that contains two sub folders: demo and PerlLibs. The demo contains a few small design examples for you to play with/get started, including makefiles. The PerlLibs folder contains the Genesis2 source code.
  2. Add Genesis2 to your execution path -- Simply type (or add to the end of your .cshrc file)
 setenv GENESIS2_LIBS "$GENESIS2_HOME/r#####/PerlLibs"
set path=($GENESIS2_LIBS/Genesis2 $path)
  1. 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 $GENESIS2_HOME/MyGenesisLocalLibs, just add the following line to your environment so that Genesis knows where to look for them:
 setenv GENESIS2_PROJECT_LIBS $GENESIS2_HOME/MyGenesisLocalLibs

Working On Stanford Machines

Genesis2 is available at Stanford through the common module load system just like any other cad tool. To load Genesis2 do the following: 1. If you have not already done so, source the module loader by typing (depending on your machine):

source /cad/modules/init_modules.csh  ---- For neva / neva-2 users
OR
source /cad/modules/tcl/init/<yourFavoriteShell>  ----  For kiwi / cyclades / hotbox users 

2. Load the Genesis2 module

module load genesis2

That's it. You are good to go.

Getting Started With Genesis2

Setting Your Environment

Setting Genesis2 Mode for Xemacs/Emacs

If you use emacs or xemacs and would like to use genesis2-mode.el, download BOTH File:Multi-mode.el and File:Genesis2-mode.el, and then...

To set xemacs such that it starts in genesis2 mode, add the following code to your ~/.xemacs/init.el file. OR...

To set emacs such that it starts in genesis2 mode, add the following code to your ~/.emacs file:

;; Add the path to your genesis2-mode.el file
(prepend-path "/path/to/genesis2-mode.el")

;; Load genesis2 and/or verilog mode when needed
(autoload 'verilog-mode "verilog-mode" "Verilog mode" t )
(autoload 'genesis2-mode "genesis2-mode" "Genesis2 mode" t )

;; Any files that end in .v should be in verilog mode but .vp should be genesis2 mode
(setq auto-mode-alist
      (append '(
                ("\\.v\\'" . verilog-mode);; for verilog files
                ("\\.vh\\'" . verilog-mode);; for verilog header files
                ("\\.sv\\'" . verilog-mode);; for system verilog files
                ("\\.svh\\'" . verilog-mode);; for system verilog header files
                ("\\.vp\\'" . genesis2-mode);; for pre-processed Genesis files
                ("\\.vph\\'" . genesis2-mode);; for pre-processed header Genesis files
                ("\\.svp\\'" . genesis2-mode);; for pre-processed Genesis files
                ("\\.svph\\'" . genesis2-mode));; for pre-processed Genesis header files
               auto-mode-alist))
  • Note that a loader for verilog mode may have already been defined and most emacs distributions come with verilog-mode.el built-in. Otherwise, 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.

Setting Genesis2 Mode for Vim

"Vim users unite..." Thanks to James Mao, there is now a Genesis2 syntax highlighting mode for Vim. To install it:

  1. Download [[File::vim-genesis2.tar]]
  2. Extract the files
  3. Call "make install"

That's it.

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. So far, libraries that I have seen missing include XML::Simple and XML::SAX / XML::Parser (you only need one of SAX or Parser).

These libraries 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

Generic Method:

  1. 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.
  2. Open a CPAN shell:
     perl -MCPAN -e shell
  3. Install the library XML::SAX (required by XML::Simple). Make sure to answer yes for installing all library dependencies!
     cpan> install XML::SAX 
  4. Install the library XML::Simple
     cpan> install XML::Simple 

Adding Genesis2 To Your Execution Path

Working Locally On Your Own Server/Machine

First, install the Genesis2 files. For example, you can put them under $USER/bin/PerlLibs/Genesis2. It should look something like this:

vlsi: ~/bin/PerlLibs/Genesis2> ls -R

.:
Auxiliary/ Genesis2.pl Manager.pm UniqueModule.pm

./Auxiliary:
TypeConv.pm

Then, to add Genesis2 to your execution path, simply type (or place at the end of your .cshrc file):

setenv GENESIS_LIBS "~USER/bin/PerlLibs"
set path=($GENESIS_LIBS/Genesis2 $path)

With time, you may want to add more Perl libraries (i.e., .pm files). Say you place those under $USER/bin/Genesis2LocalLibs, just add the following line to your environment so that Genesis knows where to look for them:

setenv GENESIS_PROJECT_LIBS $USER/bin/Genesis2LocalLibs

Genesis2 File Types

Main File Types

SomeModule.vp And SomeIncludeFile.vph Files (or .svp and .svph for noting SystemVerilog)

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.

'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.

SomeModule.v Files (or .sv for .svp files)

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:

  • There are a few reserved element names: HierarchyTop, BaseModuleName, SynonymFor, InstanceName, Parameters, ImmutableParameters, ParameterItem, Name, Val, Doc, Range, List, Min, Max, Step, Opt, SubInstances, SubInstanceItem, UniqueModuleName, CloneOf, HashType, HashItem, Key, ArrayType, ArrayItem, InstancePath. Avoid using these key words in any context other than the one explained here or in the output xml representation section.
  • 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!
Example of top level:
<HierarchyTop>
    <!-- Optional: -->
    <Parameters>
        <!-- List zero or more ParameterItem elements-->
    </Parameters>
    <SubInstances>
        <!-- List zero or more SubInstanceItem elements-->
    </SubInstances>
</HierarchyTop>
Example for internal node
<SubInstances>
    <SubInstanceItem>
        <!-- Mandatory: -->
        <InstanceName>someInstanceName</InstanceName>

        <!-- Optional: -->
        <Parameters>
            <!-- List zero or more ParameterItem elements-->
        </Parameters>
        <SubInstances>
            <!-- List zero or more SubInstanceItem elements-->
        </SubInstances>
    </SubInstanceItem>
    ...
    <!-- More SubInstanceItem elements-->
    ...
</SubInstances>
  • 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.
<SubInstances>
    <SubInstanceItem>
        <InstanceName>someInstanceName_A</InstanceName>
        ...
    </SubInstanceItem>
    <SubInstanceItem>
        <InstanceName>someInstanceName_B</InstanceName>
        ...
    </SubInstanceItem>
    ...
    <!-- More SubInstanceItem elements-->
    ...
</SubInstances>
  • 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:
<Parameters>
    <ParameterItem>
        <Name>myParam</Name>
        <Val>>myValue</Val>
    </ParameterItem>
    ...
    <!-- More ParameterItem elements-->
    ...
</Parameters>
  • 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"
<Parameters>
    <ParameterItem>
        <Name>myArrayParam</Name>
        <ArrayType>
            <ArrayItem>
                <Val>1</Val>
            </ArrayItem>
            <ArrayItem>
                <Val>2</Val>
            </ArrayItem>
            <ArrayItem>
                <Val>3</Val>
            </ArrayItem>
            ...
            <!-- More ArrayItem elements-->
            ...
        </ArrayType>
    </ParameterItem>
    <ParameterItem>
        <Name>myHashParam</Name>
        <HashType>
            <HashItem>
                <Key>somekey</Key>
                <Val>someval<Val>
            </HashItem>
            <HashItem>
                <Key>anotherkey</Key>
                <Val>anotherval</Val>
            </HashItem>
            ...
            <!-- More HashItem elements-->
            ...
        </HashType>
    </ParameterItem>
    <ParameterItem>
        <Name>myRefToAnotherInstance</Name>
        <InstancePath>name_of_top_module.name_of_sub_instance_1</InstancePath>
    </ParameterItem>
</Parameters>
  • Example of full hierarchical XML program input example:
<HierarchyTop>
   <Parameters>
      <ParameterItem>
         <Name>some_param_name_1</Name>
         <Val>>12</Val>
      </ParameterItem>
      <ParameterItem>
         <Name>some_param_name_2</Name>
         <Val>>15</Val>
      <ParameterItem>
   </Parameters>
   <SubInstances>
      <SubInstanceItem>
         <InstanceName>name_of_sub_instance_1</InstanceName>
         <Parameters>
            <ParameterItem>
               <Name>some_param_name_1</Name>
               <Val>5</Val>
            </ParameterItem>
            <ParameterItem>
               <Name>some_param_name_2</Name>
               <Val>3</Val>
            </ParameterItem>
            <ParameterItem>
               <Name>my_empty_array</Name>
               <ArrayType></ArrayType>
            </ParameterItem>
            <ParameterItem>
               <Name>my_empty_hash</Name>
               <HashType></HashType>
            </ParameterItem>
            <ParameterItem>
               <Name>some_array_param_name</Name>
               <ArrayType>
                  <ArrayItem>
                     <Val>element_1</Val>
                  </ArrayItem>
                  <ArrayItem>
                     <Val>element_2</Val>
                  </ArrayItem>
               </ArrayType>
            </ParameterItem>
            <ParameterItem>
               <Name>some_hash_param_name</Name>
               <HashType>
                  <HashItem>
                     <Key>some_key_1</Key>
                     <Val>val_1</Val>
                  </HashItem>
                  <HashItem>
                     <Key>some_key_2</Key>
                     <Val>val_2</Val>
                  </HashItem>
               </HashType>
            </ParameterItem>
         </Parameters>
      </SubInstanceItem>
      <SubInstanceItem>
         <InstanceName>name_of_sub_instance_2</InstanceName>
         <Parameters>
            <ParameterItem>
               <Name>some_param_name_1</Name>
               <Val>73</Val>
            </ParameterItem>
            <ParameterItem>
               <Name>some_param_name_1</Name>
               <Val>45</Val>
            </ParameterItem>
            <ParameterItem>
               <Name>some_instance_ref</Name>
               <InstancePath>
                  name_of_top_module.name_of_sub_instance_1
               </InstancePath>
            </ParameterItem>
         </Parameters>
         <SubInstances>
            <SubInstanceItem>
               <InstanceName>name_of_sub_sub_instance_1</InstanceName>
               <Parameters>
                  <ParameterItem>
                     <Name>some_param_name_1</Name>
                     <Val>1</Val>
                  </ParameterItem>
                  <ParameterItem>
                     <Name>some_param_name_2</Name>
                     <Val>2</Val>
                  </ParameterItem>
               </Parameters>
               <SubInstances>
               </SubInstances>
            </SubInstanceItem>
         </SubInstances>
      </SubInstanceItem>
   </SubInstances>
</HierarchyTop>

Additional Output File Types

Genesis2 produces some additional outputs, on top of the Verilog files: 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).

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) 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.

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.
    • InstanceName: The name of the instance that was generated
    • ImmutableParameters: A list of zero or more ParameterItem elements. ImmutableParameters has the exact same structure as that of the Parameters element. However, while Parameters can be altered and re-fed into Genesis2 using the input xml program to create new RTL, ImmutableParameters are parameters that where already assigned a value, either using parameter(Name=>'prm', Val=>..., Force=>1) call or at instantiation using the generate(TemplateName, InstanceName, prm=>val) call.
    • 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.

<HierarchyTop>
  <BaseModuleName>top</BaseModuleName>
  <ImmutableParameters></ImmutableParameters>
  <InstanceName>top</InstanceName>
  <Parameters>
    <ParameterItem>
      <ArrayType>
        <ArrayItem>
          <Val>32</Val>
        </ArrayItem>
        <ArrayItem>
          <Val>64</Val>
        </ArrayItem>
      </ArrayType>
      <Doc></Doc>
      <Name>WALLACES_WIDTHS</Name>
    </ParameterItem>
  </Parameters>
  <SubInstances>
    <SubInstanceItem>
      <BaseModuleName>wallace</BaseModuleName>
      <ImmutableParameters>
        <ParameterItem>
          <Doc>This is the bit width of the partial products</Doc>
          <Name>N</Name>
          <Range>
            <List>8</List>
            <List>16</List>
            <List>32</List>
            <List>64</List>
          </Range>
          <Val>32</Val>
        </ParameterItem>
      </ImmutableParameters>
      <InstanceName>wallace_32</InstanceName>
      <Parameters>
        <ParameterItem>
          <Name>COND</Name>
          <Doc>the value can be true or false</Doc>
          <Range>
            <List>false</List>
            <List>true</List>
          </Range>
          <Val>false</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMin</Name>
          <Doc></Doc>
          <Range>
            <Min>106</Min>
          </Range>
          <Val>107</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMax</Name>
          <Doc></Doc>
          <Range>
            <Max>210</Max>
          </Range>
          <Val>200</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMinStep</Name>
          <Doc></Doc>
          <Range>
            <Min>300</Min>
            <Step>3</Step>
          </Range>
          <Val>309</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMaxStep</Name>
          <Doc></Doc>
          <Range>
            <Max>410</Max>
            <Step>2</Step>
          </Range>
          <Val>404</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMinMax</Name>
          <Doc></Doc>
          <Range>
            <Max>510</Max>
            <Min>500</Min>
          </Range>
          <Val>505</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMinMaxStep</Name>
          <Doc></Doc>
          <Range>
            <Max>630</Max>
            <Min>610</Min>
            <Step>2</Step>
          </Range>
          <Val>622</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParamExamplePointerToMe</Name>
          <Doc></Doc>
          <InstancePath>top.wallace_32</InstancePath>
        </ParameterItem>
        <ParameterItem>
          <Name>ParamHash</Name>
          <Doc></Doc>
          <HashType>
            <HashItem>
              <Key>alma</Key>
              <Val>4</Val>
            </HashItem>
            <HashItem>
              <Key>neta</Key>
              <Val>2</Val>
            </HashItem>
            <HashItem>
              <Key>ofer</Key>
              <Val>1</Val>
            </HashItem>
            <HashItem>
              <Key>ori</Key>
              <Val>3</Val>
            </HashItem>
          </HashType>
        </ParameterItem>
        <ParameterItem>
          <Name>ParamComplexStruct</Name>
          <Doc></Doc>
          <ArrayType>
            <ArrayItem>
              <Val>value</Val>
            </ArrayItem>
            <ArrayItem>
              <ArrayType>
                <ArrayItem>
                  <Val>1</Val>
                </ArrayItem>
                <ArrayItem>
                  <Val>2</Val>
                </ArrayItem>
                <ArrayItem>
                  <Val>3</Val>
                </ArrayItem>
                <ArrayItem>
                  <Val>4</Val>
                </ArrayItem>
              </ArrayType>
            </ArrayItem>
            <ArrayItem>
              <HashType>
                <HashItem>
                  <Key>a</Key>
                  <Val>1</Val>
                </HashItem>
                <HashItem>
                  <Key>b</Key>
                  <Val>2</Val>
                </HashItem>
                <HashItem>
                  <Key>c</Key>
                  <Val>3</Val>
                </HashItem>
                <HashItem>
                  <ArrayType>
                    <ArrayItem>
                      <Val>a</Val>
                    </ArrayItem>
                    <ArrayItem>
                      <Val>b</Val>
                    </ArrayItem>
                    <ArrayItem>
                      <Val>c</Val>
                    </ArrayItem>
                    <ArrayItem>
                      <Val>x</Val>
                    </ArrayItem>
                  </ArrayType>
                  <Key>d</Key>
                </HashItem>
              </HashType>
            </ArrayItem>
          </ArrayType>
        </ParameterItem>
      </Parameters>
      <SubInstances></SubInstances>
      <UniqueModuleName>wallace_unq1</UniqueModuleName>
    </SubInstanceItem>
    <SubInstanceItem>
      <BaseModuleName>wallace</BaseModuleName>
      <CloneOf>
        <InstancePath>top.wallace_32</InstancePath>
      </CloneOf>
      <InstanceName>clone_of_wallce_32</InstanceName>
      <UniqueModuleName>wallace_unq1</UniqueModuleName>
    </SubInstanceItem>
    <SubInstanceItem>
      <BaseModuleName>wallace</BaseModuleName>
      <ImmutableParameters>
        <ParameterItem>
          <Doc>This is the bit width of the partial products</Doc>
          <Name>N</Name>
          <Range>
            <List>8</List>
            <List>16</List>
            <List>32</List>
            <List>64</List>
          </Range>
          <Val>64</Val>
        </ParameterItem>
      </ImmutableParameters>
      <InstanceName>wallace_64</InstanceName>
      <Parameters>
        <ParameterItem>
          <Name>COND</Name>
          <Doc>the value can be true or false</Doc>
          <Range>
            <List>false</List>
            <List>true</List>
          </Range>
          <Val>false</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMin</Name>
          <Doc></Doc>
          <Range>
            <Min>106</Min>
          </Range>
          <Val>107</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMax</Name>
          <Doc></Doc>
          <Range>
            <Max>210</Max>
          </Range>
          <Val>200</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMinStep</Name>
          <Doc></Doc>
          <Range>
            <Min>300</Min>
            <Step>3</Step>
          </Range>
          <Val>309</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMaxStep</Name>
          <Doc></Doc>
          <Range>
            <Max>410</Max>
            <Step>2</Step>
          </Range>
          <Val>404</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMinMax</Name>
          <Doc></Doc>
          <Range>
            <Max>510</Max>
            <Min>500</Min>
          </Range>
          <Val>505</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParWithMinMaxStep</Name>
          <Doc></Doc>
          <Range>
            <Max>630</Max>
            <Min>610</Min>
            <Step>2</Step>
          </Range>
          <Val>622</Val>
        </ParameterItem>
        <ParameterItem>
          <Name>ParamExamplePointerToMe</Name>
          <Doc></Doc>
          <InstancePath>top.wallace_64</InstancePath>
        </ParameterItem>
        <ParameterItem>
          <Name>ParamHash</Name>
          <Doc></Doc>
          <HashType>
            <HashItem>
              <Key>alma</Key>
              <Val>4</Val>
            </HashItem>
            <HashItem>
              <Key>neta</Key>
              <Val>2</Val>
            </HashItem>
            <HashItem>
              <Key>ofer</Key>
              <Val>1</Val>
            </HashItem>
            <HashItem>
              <Key>ori</Key>
              <Val>3</Val>
            </HashItem>
          </HashType>
        </ParameterItem>
        <ParameterItem>
          <Name>ParamComplexStruct</Name>
          <Doc></Doc>
          <ArrayType>
            <ArrayItem>
              <Val>value</Val>
            </ArrayItem>
            <ArrayItem>
              <ArrayType>
                <ArrayItem>
                  <Val>1</Val>
                </ArrayItem>
                <ArrayItem>
                  <Val>2</Val>
                </ArrayItem>
                <ArrayItem>
                  <Val>3</Val>
                </ArrayItem>
                <ArrayItem>
                  <Val>4</Val>
                </ArrayItem>
              </ArrayType>
            </ArrayItem>
            <ArrayItem>
              <HashType>
                <HashItem>
                  <Key>a</Key>
                  <Val>1</Val>
                </HashItem>
                <HashItem>
                  <Key>b</Key>
                  <Val>2</Val>
                </HashItem>
                <HashItem>
                  <Key>c</Key>
                  <Val>3</Val>
                </HashItem>
                <HashItem>
                  <ArrayType>
                    <ArrayItem>
                      <Val>a</Val>
                    </ArrayItem>
                    <ArrayItem>
                      <Val>b</Val>
                    </ArrayItem>
                    <ArrayItem>
                      <Val>c</Val>
                    </ArrayItem>
                    <ArrayItem>
                      <Val>x</Val>
                    </ArrayItem>
                  </ArrayType>
                  <Key>d</Key>
                </HashItem>
              </HashType>
            </ArrayItem>
          </ArrayType>
        </ParameterItem>
      </Parameters>
      <SubInstances></SubInstances>
      <UniqueModuleName>wallace_unq2</UniqueModuleName>
    </SubInstanceItem>
    <SubInstanceItem>
      <BaseModuleName>wallace</BaseModuleName>
      <CloneOf>
        <InstancePath>top.wallace_64</InstancePath>
      </CloneOf>
      <InstanceName>clone_of_wallce_64</InstanceName>
      <UniqueModuleName>wallace_unq2</UniqueModuleName>
    </SubInstanceItem>
  </SubInstances>
  <UniqueModuleName>top</UniqueModuleName>
</HierarchyTop>

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 ;-))

Compilable example:

assign verilog_wire = some_other_verilog_wire;
// I am a verilog comment line
//; my $to_be_perl_var = "This is Perl";
Part-Of-Line Escape ( ‘ Perl text between left-single-quotes ‘ )
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.

Example:

//; my $width = 5;
assign some_wire[`$width-1`:0] = some_other_wire[`$width+9`:10];

//; foreach my $idx (0,1,2,3){
assign wire_`$idx` = wire_`($idx+1)%4`;
//; }

Which will produce:

assign some_wire[4:0] = some_other_wire[14:10];

assign wire_0 = wire_1;
assign wire_1 = wire_2;
assign wire_2 = wire_3;
assign wire_3 = wire_0;
  • 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".

Special Built-in Methods

As mentioned before, the entire effort of creating a tool like this is to enable scopes, enhanced parametrization 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_subinst
Returns a pointer to the object of a sub instance (by name)
//; my $subinst_of_someinst = $someinst->get_subinst($subinst_name); 
sub get_subinst_array
Returns a handle to an array of sub instance objects that match a pattern
//; my $subinsts_of_someinst = $someinst->get_subinst_array($pattern); 
sub get_instance_path
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:
//; synonym("adder", "simple_adder");
//; synonym("adder", "fancy_adder");
OR as method call:
//; $self->synonym("adder", "simple_adder");
//; $self->synonym("adder", "fancy_adder");
A synonym of a synonym is also ok:
//; synonym("fancy_adder", "super_fancy_adder");
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:
//; my $obj1 = generate('adder', 'adder_u1', WIDTH=>4);
//; my $obj2 = generate('adder', 'adder_u2', WIDTH=>8);
//; my $obj3 = generate('simple_adder', 'adder_u3', WIDTH=>4);
//; my $obj4 = generate('super_fancy_adder', 'adder_u4', WIDTH=>8);
//; my $obj5 = generate('super_fancy_adder', 'adder_u5', WIDTH=>12);
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.
//; my $obj1 = generate_base('adder', 'adder_u1', WIDTH=>4);
//; my $obj2 = generate_base('simple_adder', 'adder_u2', WIDTH=>4);
//; my $obj3 = generate_base('super_fancy_adder', 'adder_u3', WIDTH=>4);
//; my $obj4 = generate_base('super_fancy_adder', 'adder_u4', WIDTH=>8); <-- This will create an ERROR message because generate_base does not create unique modules.

Parametrization 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.
  • This API method/function is in fact syntactic sugar for the older parameter definition methods $self->define_param, $self->force_param, $self->doc_param</i>, $self->param_range.
  • List of older style parameter definition methods here.
//; my $prmVal = parameter(name=>'prmName', # required
//;                        val=>$prmVal,    # required
//;                        force=>0/1,      # Optional. Default is 0. param
//;                                         # Setting to 1 will create an immutable param, 
//;                                         # exactly like $self->force_param
//;                        doc=>'message'   # Optional
//;                        min=>$minVal, max=>$maxVal, step=>$step # Optional. Can also use min only, 
//;                                                                # max only, min and step only or
//;                                                                # max and step only.
//;                        OR 
//;                        list=>[$valA, $valB, ...],
//;			   Opt=>'Yes'/'No'/'Try');                 # Optional -- Will pass info to external optimizer

Or
//; my $prmVal = $self->parameter(name=>'prmName', 
//;                               val=>$prmVal,
//;                               force=>0/1,
//;                               doc=>'message' 
//;                               min=>$minVal, max=>$maxVal, step=>$step OR list=>[$valA, $valB, ...],
//;			          Opt=>'Yes'/'No'/'Try');


sub exists_param
API method for checking whether a certain parameter exists in a module (without defining it). Can operate on $self or any template $obj that was previously generated.
//; 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');
and also if you don't want to define a value but you want to force someone else (either an instantiator module or an xml entry) to define this parameter (since if neither of them define the parameter prior to you extracting it, an error would be thrown).
//; my $val = $self->get_param('prm_name');
sub get_top_param
API method for extracting a parameter's value from the top level parameter's registry.
//; my $val = $self->get_top_param('prm_name');

This is equivalent (but much shorter) to:

//; $tmp = $self;
//; while (defined $tmp1){
//;   $tmp2=$tmp1;
//;   $tmp1=$tmp1->get_parent();
//; }
//; my $val = $tmp2->get_param('prm_name');

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.
//; my $newObj = generate(base_module_name, inst_name, prm1 => val1, prm2 => val2, ...);

Example: Before (SystemVerilog)

Adder#(.w(8),.n(4)) MyAdder(.in1(a),.in2(b),.out(c));

Example: After (Genesis2)

//; my $my_adder = generate('Adder', 'MyAdder', w=>8, n=>4);
`$my_adder->instantiate` (.in1(a), .in2(b), .out(c));
sub clone
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.
//; my $MyAnalog_obj = generate_base('Analog', 'MyAnalog', w=>8, n=>4);
`$MyAnalog_obj ->instantiate` (.in1(a), .in2(b), .out(c));

Auxiliary Methods

sub include
includes a (header) file inline with your text
//; include("some_header_file.vph");
sub iname
Returns the name of the current instance. Syntactic sugar for the older style get_instance_name()
//; my $inst_name = iname();
OR
//; my $someObj_inst_name = $someObj->iname();

Example for using iname to instantiate a module. In SystemVerilog we might do something like:

Adder#(.w(8),.n(4)) MyAdder(.in1(a),.in2(b),.out(c));

In Genesis2 we can do something like this:

//; my $my_adder = generate('Adder', 'MyAdder', w=>8, n=>4);
`$my_adder->mname()` `$my_adder->iname()` (.in1(a), .in2(b), .out(c));

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
module `mname` (input logic Clk, ... );

// parameterized module code comes here 
endmodule
sub instantiate
Syntactic sugar for $obj->mname() obj->iname() --- I.e., the module and instance name of $obj for the purpose of instantiating that module.
module `mname`(input clk, ...);
// some parameterized module code comes here 

// Let's generate and instantiate an ALU module:
//; my $ALU = generate('ALU', 'ALU_U', param1=>val1, param2=>val2,...);
  `$ALU->instantiate` (.clk(clk), 
                       .arg1(vector1), 
                       .arg2(vector2), 
                       .cmd(operation),
                       .result(result));

// more parameterized module code comes here 
endmodule: `mname`
sub bname
Returns the base module name from which an object was generated. This is the name of the template, before uniquification. Note that this is syntactic sugar for the older style method get_base_name
//; my $BaseName = bname();
//; my $SomeObj_BaseName = $SomeObj->bname();
sub sname
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
//; my $SourceName = sname();
//; my $SomeObj_SourceName = $SomeObj->sname();
sub error
Prints an error message and exits with a printout of the current file and line
//; $self->error("some error message");
sub warning
Prints a warning message and a printout of the current file and line. Does NOT exit.
//; $self->warning("some message");

Useful Debug Hints

Debug level
In order to see more verbose messages from Genesis during elaboration use the flag -debug n where n is the verbosity level.
Error and warning messages
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

Genesis2 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.)

Parametrization is also quite simple: 1) A parameter can be defined in a module using the define_param method mentioned above. 2) Parameters can be either added or overwritten by the external XML/configuration file. 3) Finally, parameters can also be added or overwritten at instantiation time (this is similar to Verilog 2001). This means that:

  1. Defining a parameter inside the module code using define_param has the lowest priority (GENESIS2_DECLARATION_PRIORITY => 1)
  2. External input priority overrides the original module code (GENESIS2_EXTERNAL_CONFIG_PRIORITY => 2)
  3. A parameter that is assigned at instantiation is assumed to be highest priority to make sure that the instantiated module is compatible with the instantiating module (GENESIS2_INHERITANCE_PRIORITY => 3)

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).

  • 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 constants 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 unique module 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

Genesis2 is located in $SMASH/bin/PerlLibs/Genesis2/Genesis2.pl. For help on using the script 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.

Usage:
        ./Genesis2.pl [-option value, ...]

Parsing Options:
        [-parse]                        # Parse input file and generate perl modules
        [-sources|srcpath dir]          # Where to find source files
        [-includes|incpath dir]         # Where to find included files
        [-input file1 .. filen]         # List of files to process
        [-inputlist filelist1 .. filelistn]     # List of files that each contain a list of files to
                                                # process (use # to comment lines out in this format)
        [-depend filename]              # Generate a dependency file list (list of input files)
        [-perl_modules modulename]      # Additional perl modules to load

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.

Usage:
        ./Genesis2.pl [-option value, ...]

Generating Options:
        [-generate]                     # Generate a verilog hierarchy
        [-top topmodule]                # Name of top module to start generation from
        [-product filename]             # Generate a product file list (list of output files)
        [-hierarchy filename]           # Generate a hierarchy representation tree
        [-xml|cfg filename]                 # Input XML representation of definitions
        [-perl_modules modulename]      # Additional perl modules to load

Help and Debugging

Usage:
        ./Genesis2.pl [-option value, ...]

Help and Debuging Options:
        [-debug level]                 # Set debug level
        [-help]                        # prints the script's usage message
        [-man [extension_name]]        # prints the complete man page for Genesis2 or the
                                       # specified extension (e.g. -man Math)
  • I have not written the man content yet. So it is likely to print zip.

Sample Graphical User Interface and Demo

Click here for interactive chip generator GUI and demo based on Genesis2.

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):

//; # More Perl Libraries
//; use POSIX;
//; my $reg_list = $self->define_param(REG_LIST => [	{name => 'regA', width => 5, default => 17, IEO => 'ie'}, 
//;							{name => 'regB', width => 10, default => 27, IEO => 'o'}, 
//;							{name => 'regC', width => 15, IEO => 'ieo'},
//;							{name => 'regD', width => 31, IEO => 'ieo'},
//;							{name => 'regE', width => 32, IEO => 'ieo'},
//;						    ]);
//; my $num_regs = scalar(@{$reg_list});
//; my $num_addr_bits = POSIX::ceil(log($num_regs)/log(2));

// Verilog code for the module
module `$self->get_module_name()` (
    input                               Clk,
    input                               Reset,
    input [`$num_addr_bits-1`:0]        Addr,
    ...
    );

endmodule // `$self->get_module_name()`

Adding Your Own Perl Library

Assuming your homemade Perl package is called MyLib.pm, place it in the folder Path/To/MyGenesisProjectLibs. Then add the environment variable GENESIS_PROJECT_LIBS to your environment setup file by adding this line:

setenv GENESIS_PROJECT_LIBS Path/To/MyGenesisProjectLibs

There are two ways for your Genesis2 modules to get the functions of a home-made library into their name space:

  1. Typical Perl "use" system: (preferred way for not polluting the name space)
    In your module (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 to be embedded in the name space, you can also add their names to the EXPORT or EXPORT_OK lists. (As an example, the file $GENESIS_LIBS/Genesis2/Auxiliary/TypeConv.pm has these lists marked with "METHOD 1 FOR INHERITING ALL METHODS"
  2. Inheritance:
    You can tell all Genesis2 modules to inherit methods from this module. In order to do that, we force the UniqueModule (which is the base class of all Genesis2 modules) to inherit from this module. Then, given a method with name methodName, each and every module in Genesis would be able to call it by invoking $self->methodName. To activate this inheritance follow these two steps:
    1. Push the current package into the ISA inheritance array of the base module UniqueModule. (As an example, see in the file $GENESIS_LIBS/Genesis2/Auxiliary/TypeConv.pm, the Perl lines that are annotated as "METHOD 2 FOR INHERITING ALL METHODS").
    2. Either add "use MyLib;" to your Genesis2.pl script at the appropriate location, which would force this library to always be used. Or, use the Genesis2 flag "-perl_modules MyLib" on your command line.

Behind The Genesis2 Curtain

The Genesis2::Manager and Genesis2::UniqueModule Objects

One day I'll find the time to write this. Not today though :-))

Shacham 14:33, 11 March 2011 (PST)