BTF B05 - A progressive example

From: Tom Fitzpatrick (tfitz@cadence.com)
Date: Fri Jan 22 1999 - 08:58:01 PST


BAD MSG:
<x-rich><bigger>This new example is intended to show the capabilities of
onfiguration
X-Lines: 2468
Content-Length: 54893
X-Status: $$$$
X-UID: 0000000813
Status: RO

--=_AABYJQAANw43glcI
Content-Type: text/enriched; charset="us-ascii"
>From ???@??? Fri Jan 22 14:46:25 1999
Return-Path: <owner-btf@boyd.com>
Received: from pc-tfitz.cadence.com (d15814010531 [158.140.105.31])
        by rowlf.Cadence.COM (8.8.8/8.8.5) with SMTP id LAA06499;
        Fri, 22 Jan 1999 11:55:39 -0500 (EST)
X-Authentication-Warning: gw.boyd.com: majordomo set sender to owner-btf@boyd.com using -f
Message-Id: <3.0.5.32.19990122115801.009f65b0@rowlf.cadence.com>
X-Sender: tfitz@rowlf.cadence.com
X-Mailer: QUALCOMM Windows Eudora Pro Version 3.0.5 (32)
Date: Fri, 22 Jan 1999 11:58:01 -0500
To: btf@boyd.com, 1364core@ovi.org
From: Tom Fitzpatrick <tfitz@cadence.com>
Subject: BTF B05 - A progressive example
Mime-Version: 1.0
Sender: owner-btf@boyd.com
Precedence: bulk
Status: RO
<x-rich><bigger>This new example is intended to show the capabilities of
configuration
X-Sun-Content-Length: 53970

in a gradual way.

<p>1. Introduction

<p>In the old use-model the concept of a library was used to denote a set

of source descriptions which may or may not actually get included in

the design. In effect, these files are scanned for module names, and

if the proper module name is found, then that module definition is

parsed/compiled and included in the design. In the absence of a formal

configuration mechanism in the language, command files (using the '-f'

command line switch) have become the de facto standard for specifying

a design configuration. There are, however a number of shortcomings to

this approach:

<p>1) It is difficult to "package" a design and either transport it to a

   different user environment (different OS, file system, directory

   structure, etc.) or include it hierarchically in another design.

<p>2) It is difficult to specify different representations of a given

   module to be used for multiple instantiations of a module in the

   hierarchy.

<p>In the proposed new use-model, the concept of a library has changed

lightly to be more compatible with compiled-code technology. In the

new use-model, a library represents a set of compiled source

descriptions which may be used when building a design to simulate (or

for use by other verification tools). These compiled descriptions are

an abstraction separate from (but obviously related to) the actual

ource text descriptions on which they are based. In order to make

full use of this capability, there are two things which must be added

to the language: first, we must be able to map source descriptions to

libraries, and second we must be able to refer to library components

to be used in configurations

<p>The key advantage of creating a symbolic name for library components

eparate from the source description is that it greatly simplifies the

process of packaging a design for transport and/or hierarchical

inclusion in other designs, as we shall see. If we also introduce the

concept of a "view" of a design, which is essentially a different

representation of a given library component (rtl vs. gate, for

example), then we also have a powerful mechanism to address the second

limitation to the de facto configuration mechanism.

<p>2. Design Example

<p>We shall use a small design example to demonstrate each of the

configuration concepts being introduced.

<p>The design example is a simple graphics controller which consists of

the following modules:

<p>top: the top-level module which instantiates each subsystem

host: the host interface and main controller

gr: the graphics controller

fb: the frame buffer

mem: a memory subsystem

<p>There is also a dma controller instantiated in the host, gr and fb

blocks. The dma controller itself consists of a controller fsm module

and a buffer/fifo module.

<p>The hierarchy of the system looks like this:

<p>top()

 |

 + -- host

 | |

 | +-- dma // dma controller

 | | |

 | | +-- fsm // controller fsm

 | | +-- fifo // dma fifo buffer

 | |

 | +-- alu // alu

 | +-- arb // dma arbiter

 | +-- memctl // memory controller

 |

 |

 + -- gr

 | |

 | +-- dma // dma controller

 | | |

 | | +-- fsm

 | | +-- fifo

 | |

 | +-- alu

 | +-- memctl

 | +-- mem1 // data memory

 | +-- mem2 // graphics memory (same module as data memory)

 |

 + -- fb

 | |

 | +-- dma

 | | |

 | | +-- fsm

 | | +-- fifo

 | |

 | +-- mem // display memory

 |

 + -- mem

<p>The directory hierarchy being used is as follows:

<p>/root

  |

  +-- /company

  | |

  | +-- /library

  | |

  | +-- /memory

  | |

  | +-- /sram.v // company-approved memory

  |

  +-- /projects

        |

        +-- /proj5

              |

              +-- /gates

              | |

              | +-- /dma.vg

              | +-- /fsm.vg

              | +-- /fifo.vg

              | +-- /alu.vg

              | +-- /arb.vg

              | +-- /memctl.vg

              |

              +-- /tb

              | |

              | +-- /lib.map

              | +-- /run_old.f // old-style -f file

              | +-- /tb.v // Verilog testbench

              |

              +-- /vlog

              | |

              | +-- /top.v // design top-level

              | +-- /host.v // host interface rtl description

              | +-- /gr.v // graphics block rtl description

              | +-- /fb.v // frame buffer rtl description

              | +-- /mem.v // memory rtl description

              | +-- /dma.v // dma rtl including fsm and fifo (-v)

              |

              +-- /stuff // (-y)

                    |

                    +-- /alu.v // alu rtl description

                    +-- /arb.v // arbitrator rtl description

                    +-- /memctl.v // memory controller description

<p>//-------------------------------------------------------------

// This file: /root/projects/proj5/tb/tb.v

// testbench module

//-------------------------------------------------------------

module tb;

  ...

  top g1(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/vlog/top.v

// design top-level module

//-------------------------------------------------------------------

module top (...);

  ...

  host hostmod (...);

  gr grmod (...);

  fb fbmod (...);

  mem topmem (...);

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/vlog/host.v

// host interface block

//-------------------------------------------------------------------

module host (...);

  ...

  dma dma1(...);

  alu halu(...);

  arb harb(...);

  memctl mctl(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/vlog/gr.v

// graphics controller block

//-------------------------------------------------------------------

module gr(...);

  ...

  dma dma(...);

  alu galu(...);

  mem mem1(...);

  mem mem2(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/vlog/fb.v

// frame buffer block

//-------------------------------------------------------------------

module fb(...);

  ...

  dma dma1(...);

  mem fmem(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/vlog/mem.v

// memory subsystem

//-------------------------------------------------------------------

module mem(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/vlog/dma.v

// dma controller, including fsm and fifo

//-------------------------------------------------------------------

module dma(...);

  ...

  fsm fsm(...);

  fifo fifo(...);

  ...

endmodule

<p>module fsm(...);

  ...

endmodule

<p>module fifo(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/stuff/alu.v

// alu sub-block

//-------------------------------------------------------------------

module alu(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/stuff/arb.v

// dma arbitrator sub-block

//-------------------------------------------------------------------

module arb(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/stuff/memctl.v

// memory controller

//-------------------------------------------------------------------

module memctl(...);

  ...

endmodule

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/gates/dma.vg

// gate-level dma controller with fsm and fifo collapsed

//-------------------------------------------------------------------

module dma(...);

  ...

endmodule

//===================================================================

<p>In order to simulate the basic rtl description of this system using the

old use-model, we would use a -f file something like this:

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/tb/run_old.f

//-------------------------------------------------------------------

tb.v

../vlog/host.v

../vlog/gr.v

../vlog/fb.v

../vlog/mem.v

-v ./dma.v

-y ../stuff

+libext+.v

<p>and invoke the verilog simulator as:

<p>verilog -f run_old.f

<p>2.1 Old Use-Model Issues

<p>In the old use-model, this would cause the simulator to parse/compile

the explicitly named files (tb.v host.v gr.v fb.v mem.v), and then for

the module instances for which no module description was found, it

would scan the dma.v and ../stuff/*.v files for the appropriate module

declaration and parse/compile the source description and bind it to

the appropriate instance. One of the problems with this mechanism is

the confusing rules used to search the library files for these

descriptions. This confusion was particularly apparent if the same

module name appeared in two different library files. In fact, you

might get different results based simply on the order in which you

listed the -y/-v files on the command line!

<p>3. Library Mapping in the New Use-Model

<p>In the proposed new use-model, we are introducing a library mapping

file, which must be parsed before any verilog source is parsed, to

pecify the mapping of source description files into logical

libraries. By default, this file shall be named lib.map and either it

must appear as the first file on a parse command line, or the tool

must automatically locate and parse the file prior to parsing any

ource text files. It shall be up to the tool vendor to provide an

optional mechanism(i.e. command-line argument, environment variable,

tool-specific startup file, etc.) for the user to specify this

file. If the lib.map file is not explicitly specified, then the tool

hall look for ./lib.map and use it if it exists, else it shall use

$HOME/lib.map if it exists, otherwise it shall use a default library

for all components. The default library will also allow for backward

compatibility with existing designs and for situations where a design

is sufficiently simple not to need the additional benefit of

libraries. This default library shall be named "work". The name of a

component in a library shall be the name of the module/udp.

<p>The lib.map file serves two purposes. First, it specifies the mapping

of source files into specific libraries, via the library

declarations. Second, it specifies the set of libraries to be searched

to find components by the order in which the libraries are declared in

the lib.map file.

<p>3.1 Lib.map File Library Mapping Syntax

<p>The syntax for specifying libraries in the lib.map file is shown here:

<p>lib_view_text ::= library_declaration | include_specification

<p>library_declaration ::= library lib_identifier library_item
[{,library_item}];

<p>library_item ::= file_item | dir_item

<p>file_item ::= file "file_spec";

NOTE: `*' denotes multi-character wildcard,

`...' denotes hierarchical wildcard,

`?' denotes single character wildcard

<p>EXAMPLE: /proj/dir1/rtl/a.v /proj/dir2/gates/a.v

                /proj/dir1/rtl/b.v /proj/dir2/gates/b.v

        /proj/dir*/*/a.v = /proj/dir1/rtl/a.v, /proj/dir2/gates/a.v

        .../a.v = /proj/dir1/rtl/a.v, /proj/dir2/gates/a.v

        /proj/.../b.v = /proj/dir1/rtl/b.v, /proj/dir2/gates/b.v

        .../rtl/*.v = /proj/dir1/rtl/a.v, /proj/dir1/rtl/b.v

<p>dir_item ::= dir "file_spec";

<p>Components encountered in files that do not map to a library

pecification shall automatically be placed in the default work

library. This means that the following library specification is

identical to having no library specification at all:

<p>library work file "...";

<p>The actual method for specifying the set of files to be compiled into

libraries shall be implementation-specific. This proposal is intended

to be compatible with "single-pass" tools like Verilog-XL, and also

with tools which have an explicit compile step separate from the

imulation step. In fact, for these multi-pass tools, it is even more

critical to have a symbolic method of referring to library

components. There is no reason that a tool which implements this

proposal cannot continue to use the same run_old.f command file to

pecify the set of source modules to be considered. For old-style

library source files (-y/-v), they can either be parsed/compiled in

their entirety, or the individual modules may be parsed/compiled when

encountered in the process of building a design.

<p>3.2 Default Library Searching

<p>A lib.map file which could be used to run the same example design

above would look something like this:

<p>//-------------------------------------------------------------

// This file: /root/projects/proj5/tb/lib.map

// library mapping file

//-------------------------------------------------------------

library dmaLib file "./dma.v";

library stuffLib dir "../stuff";

library work file "./*"; // not needed - everything else goes into

                          // the work library by default

<p>This would put the dma, fsm and fifo modules in the dmaLib library,

the alu, arb and memctl modules in the stuffLib library, and

everything else in the work library. When searching for components to

instantiate, searching shall always begin with the first library

declared and proceed in declaration order. In this example, we only

have the rtl descriptions of each module in the library declarations,

o the search order doesn't really matter.

<p>Now, suppose that we've synthesized the alu module into a gate-level

representation in ../gates/alu.vg, and we want to instantiate the

gate-level alu in place of the rtl alu. We could do this simply by

changing the lib.map file as follows:

<p>//-------------------------------------------------------------

// This file: /root/projects/proj5/tb/lib.map

// library mapping file including alu.vg

//-------------------------------------------------------------

library dmaLib file "./dma.v";

library gateLib file "../gates/alu.vg";

library stuffLib dir "../stuff";

<p>This will cause gateLib always to be searched before stuffLib (which

contains the rtl alu), and thus each instance of alu will use the

gate-level representation. We could modify the .f file to include

alu.vg as follows:

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/tb/run_old.f

// Including alu.vg

//-------------------------------------------------------------------

tb.v

../vlog/host.v

../vlog/gr.v

../vlog/fb.v

../vlog/mem.v

-v ./dma.v

-y ../stuff

+libext+.v

../gates/alu.vg

<p>which simply adds alu.vg to the set of source files to be

parsed/compiled so that it gets into the library. The order for which

modules are searched is determined by the lib.map file.

<p>3.3 Limitations of Default Library Searching

<p>Of course, if we switch the order of gateLib and stuffLib in the

lib.map file, then we'll always get the rtl version of alu, which has

essentially the same problem as the old use-model, and is therefore

not sufficient to configure a design. Also, if we include other

components in gateLib, then we must either take all gate-level

instances if they exist or all rtl instances. There would be no way,

for example, to take the gate-level version of the alu and the rtl

version of the arb, and there certainly would be no way to use the

gate-level alu in one instance and the rtl alu in another. We need a

more specific method for configuring a design.

<p>4. Configuring a Design

<p>In order to configure a design properly, we need also to introduce the

concept of a "configuration" in Verilog (denoted with the new keyword

pair "config-endconfig"). A configuration is a set of rules to be

followed when instantiating components from a library.

<p>4.1 Configuration Syntax

<p>In order to refer to these library elements, we use the following

notation:

<p>lib.cell:view

<p>where 'lib' is the library name and 'cell' is the name of the

module. The name 'cell' was chosen to be a language-neutral term for

referring to design components. It includes modules, macromodules,

udps and configs, which are all elements that may be compiled into a

library. A config declaration looks like this:

<p><<config_declaration> ::= config <<config_identifier>;

        [<<design_statement>]

        [<<source_statement>]

        {<<config_rule_statement>}

        endconfig

<p>The 'view' specifies a specific representation of a design (rtl,

gate-level, timing, cycle-accurate, etc.). We will discuss this

capability in detail later. For now, it is not strictly necessary,

ince each of the different representations may be compiled into

eparate libraries. There are disadvantages to creating a

proliferation of libraries, and the view concept not only reduces the

number of libraries needed, but it adds significant flexibility to the

config functionality.

<p>We'll go through some of the examples of configurations, and summarize

the BNF at the end of this document. For these examples, let us assume

that each of the modules has been synthesized into a .vg file in the

../gates directory.

<p>The design statement is optional and is used to specify the top-level

module representation(s) to be used for the design. If the design

tatement is omitted, then the source code description for the

top-level module(s) must be given in addition to the configuration.

<p>4.2 Basic Configuration Examples

<p>//-------------------------------------------------------------

// This file: /root/projects/proj5/tb/lib.map

// library mapping file specifying all source files

//-------------------------------------------------------------

library dmaLib file "./dma.v";

library gateLib file "../gates/alu.vg";

library stuffLib dir "../stuff";

library myLib file "./*.v", file "../vlog/*.v";

<p>Example 1: all rtl modules used

//-------------------------------------------------------------------

// 1A: configuration not using a design statement

// This file: /root/projects/proj5/tb/config_1a.cfg

//-------------------------------------------------------------------

config config_1a;

  default liblist dmaLib stuffLib myLib;

endconfig

<p>invocation: verilog run_old.f config_1a.cfg

<p>The default statement specifies a configuration-specific global rule

that is to apply to all cells and instances that are not covered by a

more-specific selection clause. We shall take a closer look at

election clauses in a later section.

<p>File tb.v is parsed to find the top-level module, tb. The libraries

are searched in the order of the liblist statement: first dmaLib, then

tuffLib then myLib. If myLib.tb does not exist, it shall be compiled

from tb.v and instantiated. If it exists, the tool may either use the

existing compiled cell or may recompile myLib.tb. For each

instantiated cell in myLib.tb, the tool shall search the libraries, in

order, to find the cell. If the cell does not exist, the tool may

either issue an error and require the user to explicitly compile the

cell and reinvoke, or it may scan the source files in run_old.f for

the module declaration, match against the library specification, and

automatically compile it into the library and instantiate it.

<p>//-------------------------------------------------------------------

// 1B: configuration using a design statement

// This file: /root/projects/proj5/tb/config_1b.cfg

//-------------------------------------------------------------------

config config_1b;

  design myLib.tb;

  default liblist dmaLib stuffLib myLib;

endconfig

<p>invocation: verilog run_old.f config_1b.cfg

<p>In this example, the tool starts with the already-compiled cell

myLib.tb and searches for instances as in example 1A.

<p>multi-pass invocation: compile run_old.f config1b.cfg

                       simulate work.config1b

<p>Example 2: Using gate-level representations instead of rtl

<p>//-------------------------------------------------------------------

// 2A: configuration using all gate-level cells that exist

// This file: /root/projects/proj5/tb/config_2a.cfg

//-------------------------------------------------------------------

config config_2a;

  design myLib.tb;

  default liblist gateLib dmaLib stuffLib myLib;

// actually, liblist gateLib myLib is sufficient here

endconfig

<p>Each cell instantiated in the hierarchy shall first be searched for in

the gateLib library. If found, it shall be used.

<p>//-------------------------------------------------------------------

// 2B: configuration using rtl for the dma module

// and submodules (fsm and fifo), gates for other

// synthesized modules, and rtl for the rest

// This file: /root/projects/proj5/tb/config_2b.cfg

//-------------------------------------------------------------------

config config_2b;

  design myLib.tb;

  default liblist dmaLib gateLib stuffLib myLib;

endconfig

<p>Since dmaLib is searched before gateLib, the rtl descriptions of the

dma, fsm and fifo modules will be found before the gate-level versions

of these cells. All other cells in gateLib will be found in gateLib

before stuffLib.

<p>4.3 Selection Clauses

<p>This mechanism is useful, but it is limited to specifying the library

used for ALL instances of a cell. In order to provide more flexibility

in configuring a design, we introduce "selection clauses" that allow

different liblists to be used for different groups of cell instances.

The BNF for the selection clauses is shown here:

<p><<selection_clause> ::= <<default_clause>

                | <<lib_clause>

                | <<cell_clause>

                | <<inst_clause>

                | <<path_clause>

<p><<lib_clause> ::= lib <<library_identifier>

<p><<cell_clause> ::= cell [<<lib_name>.]<<cell_name>

<p><<inst_clause> ::= inst
[([<<lib_name>.]<<cell_name>[:<<view_name>])]<<inst_name>

<<inst_name> ::= <<identifier>[<<iteration_specifier>]

<<iteration_specifier> ::= [ <<integer> [ : <<integer> ] ]

<p>path_clause ::= path <<cell_inst_name> {. <<cell_inst_name> }

cell_inst_name ::=
[([<<lib_name>.]<<cell_name>[:<<view_name>])]<<inst_name>

<p>We will discuss the lib_clause later. The other selection clauses are

hown in order of precedence, with the path clause having the highest

precedence.

<p>The path clause is used to specify a single instance of a cell. For

example, if we want to use the gate-level representation of the dma

controller in the graphics module dma controller, and the rtl

representation for all other dma instances, we would use the path

clause as follows:

<p>Example 3: Using gate-level for a single instance

<p>//-------------------------------------------------------------------

// 3A: configuration using gate-level for tb.g1.grmod.dma

// This file: /root/projects/proj5/tb/config_3a.cfg

//-------------------------------------------------------------------

config config_3a;

  design myLib.tb;

  default liblist dmaLib stuffLib myLib;

  path tb.g1.grmod.dma liblist gateLib;

endconfig

<p>invocation: verilog config_3a.cfg

<p>Notice the standard Verilog hierarchical path notation to specify the

desired instance of dma. The liblist clause specifies the library in

which to search for the instance specified by the path clause, and its

ubmodules. The path clause also allows the ability for error-checking

the instance bindings throughout the path by specifying the binding

that should be used for each module in the path. Consider the

following:

<p>//-------------------------------------------------------------------

// 3B: configuration using gate-level for tb.g1.grmod.dma.fsm

// Using cell_inst_name in path clause

// This file: /root/projects/proj5/tb/config_3b.cfg

//-------------------------------------------------------------------

config config_3b;

  design myLib.tb;

  default liblist dmaLib stuffLib myLib;

  path
(myLib.tb)tb.(myLib.top)g1.(myLib.gr)grmod.(dmaLib.dma)dma.(gateLib.fsm)

       liblist gateLib;

endconfig

<p>This specifies that the bindings used for tb, tb.g1 and tb.g1.grmod

must come from the myLib library (which they do), and that

tb.g1.grmod.dma must come from the dmaLib library. Now suppose that my

default liblist were incorrectly specified as:

<p>//-------------------------------------------------------------------

// 3C: configuration using gate-level for tb.g1.grmod.dma.fsm

// Using cell_inst_name in path clause, incorrect default liblist

// This file: /root/projects/proj5/tb/config_3c.cfg

//-------------------------------------------------------------------

config config_3c;

  design myLib.tb;

  default liblist stuffLib myLib gateLib dmaLib;

  path
(myLib.tb)tb.(myLib.top)g1.(myLib.gr)grmod.(dmaLib.dma)dma.(gateLib.fsm)

       liblist gateLib;

endconfig

<p>Notice that the default liblist searches gateLib before dmaLib, and

will therefore cause the gate-level version of dma to be used for all

instances of dma. If the gate-level version collapsed the hierarchy so

that there are no submodules of dma, then without the
cell_instance_name

used in the path clause, there would be no way of knowing that there

is a problem until you actually ran your simulation, if then.

<p>4.4 The Binding Expansion Clause

<p>In addition to the liblist expansion clause, which specifies the list

of libraries to be searched to find an instance, we also include the

binding expansion clause, which specifies the exact binding for the

elected cell.

<p>binding ::= binding [[lib.]cell[:view]]

<p>//-------------------------------------------------------------------

// 3D: configuration using gate-level for tb.g1.grmod.dma.fsm

// Using path selection clause and binding expansion clause

// This file: /root/projects/proj5/tb/config_3d.cfg

//-------------------------------------------------------------------

config config_3d;

  design myLib.tb;

  default liblist stuffLib myLib dmaLib;

  path tb.g1.grmod.dma.fsm binding gateLib.fsm;

endconfig

<p>4.5 The Inst Selection Clause

<p>The inst selection clause names a particular instance within a cell to

which it applies. As we see above, the dma module has the instance

name "dma1" in the host and fb modules, but the instance name "dma" in

the gr module. If we want to use the gate-level dma controller in the

host and fb modules, but the rtl version in gr, we could use the inst

clause as follows:

<p>//-------------------------------------------------------------------

// 4A: configuration using gate-level dma controller in host and fb

// Using inst selection clause and binding expansion clause

// This file: /root/projects/proj5/tb/config_4a.cfg

//-------------------------------------------------------------------

config config_4a;

  design myLib.tb;

  default liblist stuffLib myLib dmaLib;

  inst dma1 binding gateLib.dma;

endconfig

<p>Since these are the only two instances named dma1, they will both be

bound to gateLib.dma. If we wanted all instances of dma to be

gate-level, we would use the cell selection clause:

<p>//-------------------------------------------------------------------

// 4B: configuration using gate-level dma controller

// Using cell selection clause and binding expansion clause

// This file: /root/projects/proj5/tb/config_4b.cfg

//-------------------------------------------------------------------

config config_4b;

  design myLib.tb;

  default liblist stuffLib myLib dmaLib;

  cell dma binding gateLib.dma;

endconfig

<p>Example 4c shows the order of precedence of the cell, inst and path

election clauses.

<p>//-------------------------------------------------------------------

// 4C: configuration demonstrating order of precedence of cell

// inst and path clauses

// This file: /root/projects/proj5/tb/config_4c.cfg

//-------------------------------------------------------------------

config config_4c;

  design myLib.tb;

  default liblist stuffLib myLib dmaLib;

  cell dma binding gateLib.dma;

  inst dma1 binding dmaLib.dma;

  path tb.g1.hostmod.dma1 binding gateLib.dma;

endconfig

<p>The path clause specifies that the dma instance (named dma1) in

hostmod shall be bound to gateLib.dma. The inst clause states that all

instances named dma1 (except for the instance overridden by the path

clause) shall be bound to dmaLib.dma (the rtl description). Finally,

the cell clause states that all remaining instances of cell dma,

regardless of their instance names or place in the hierarchy, shall be

bound to gateLib.dma.

<p>5. Hierarchical Configurations

<p>Since configs themselves are compiled into the libraries, they can

also be referenced from other configurations using a binding clause.

In order to avoid naming conflicts, we may want to modify the lib.map

file to put all configs into their own library:

<p>//-------------------------------------------------------------

// This file: /root/projects/proj5/tb/lib.map

// library mapping file specifying all source files

// including configurations

//-------------------------------------------------------------

library dmaLib file "./dma.v";

library gateLib file "../gates/alu.vg";

library stuffLib dir "../stuff";

library myLib file "./*.v", file "../vlog/*.v";

library configLib file "./*.cfg";

<p>Now suppose that, for all instances of the dma controller, we want to

include the gate-level fsm and the rtl fifo. The easiest way to do

this would be to use a hierarchical configuration as follows:

<p>//-------------------------------------------------------------------

// 5A: Testbench config referencing hierarchical config for dma

// This file: /root/projects/proj5/tb/config_5a.cfg

//-------------------------------------------------------------------

config config_5a;

  design myLib.tb;

  default liblist stuffLib myLib;

  cell dma binding configLib.dma;

endconfig

<p>//-------------------------------------------------------------------

// 5A: hierarchical config for dma

// This file: /root/projects/proj5/tb/dma.cfg

//-------------------------------------------------------------------

config dma;

  design dmaLib.dma;

  cell fsm binding gateLib.fsm;

  cell fifo binding dmaLib.fifo;

endconfig

<p>The cell selection clause in config_5a tells the config to use the

already-configured design dma for every instance of the dma cell. The

design statement in config dma tells the configuration to use the

dmaLib.dma cell for each instance of dma (notice that the default

liblist in config_5a does not list dmaLib). The config dma itself

pecifies that the fsm cell inside of dma shall be gate-level and the

fifo cell inside of dma shall be rtl.

<p>If we only wanted to use this dma configuration for a specific instance

of the dma controller, and use the full rtl for everything else, we

could use a new config for the testbench

<p>//-------------------------------------------------------------------

// 5B: Testbench config referencing hierarchical config for dma

// This file: /root/projects/proj5/tb/config_5b.cfg

//-------------------------------------------------------------------

config config_5b;

  design myLib.tb;

  default liblist dmaLib stuffLib myLib;

  path tb.top.grmod.dma binding configLib.dma;

endconfig

<p>6. Views

<p>All of the preceding examples were based on the assumption that each

different source representation of a module is placed in a different

library. For the dma cell, we have an rtl description in dma.v, a

gate-level description in ../gates/dma.vg and a configuration to be

used in ./dma.cfg. Each of these is currently getting compiled into

dmaLib, gateLib and configLib, respectively. These are just three

typical representations of a module - there could easily be others.

Often multiple descriptions will exist for the same module, and

configurations must be capable of specifying a specific abstraction of

the module to instantiate. In order to name these abstractions, we

introduce the concept of a 'view' to the configuration mechanism.

<p>The use of multiple abstraction levels is very prevalent in Verilog

design today. Common examples include RTL, post-synthesis,

post-layout, cycle-accurate and timing-accurate descriptions. Current

users manage these alternate descriptions through multiple mechanisms

including: creation of alternate directories of source, file suffix

conventions, command-line options and use of `ifdef and macros to

create alternate source text from one file. Additional mechanisms are

not necessary in the language to create these alternate descriptions,

imply a naming mechanism to reference them is required.

<p>However, since alternate views of a cell are typically generated from

a single source file, simply mapping the source file location (as for

libraries) is not sufficient to identify a view abstraction

uniquely. Therefore, we propose the following syntax for view

pecifications in the lib.map file:

<p>6.1 View Specification Syntax

<p>lib_view_text ::= library_declaration

                | view_specification

                | include_specification

<p>library_declaration ::= library lib_identifier library_item
[{,library_item}];

<p>library_item ::= file_item | dir_item | viewlist_spec

<p>viewlist_spec ::= viewlist view_identifier {, view_identifier};

<p>view_specification ::= view [view_identifier [view_item[{,view_item}]]];

<p>NOTE: If no view_item is included, then all subsequent elements shall

be given the declared view.

<p>EXAMPLE: `view foo;

All elements shall be assigned the view "foo".

EXAMPLE: `view;

All subsequent elements shall be given the default view

<p>view_item ::= macro_usage

            | directive_usage

            | arg_usage

            | file_item

            | dir_item

<p>macro_usage ::= macro macro_identifier [= <<value>]

NOTE: A macro is defined either by `define macro_identifier [=

<<value>] in the source, or +define+macro_identifier[=<<value>] on the

command line.

<p>directive_usage ::= directive directive_identifier [= <<value>]

EXAMPLE: directive delay_mode_zero;

                directive timescale = 1 ns / 10 ps;

<p>arg_usage ::= arg arg_identifier [= <<value>]

NOTE: "arg_identifier" is an implementation-dependent command line

argument that may be set by the user

EXAMPLE: my_verilog -LINEDEBUG foo.v

                view debug arg LINEDEBUG;

<p>As with library specifications, the specification clauses in a view

pecification are intended to indicate a map function. They are not

commands. When a source module is parsed/compiled, the source file is

known, as are any macros, compiler directives, and command-line

arguments. This information is compared against the view

pecifications, and when a view specification is found that matches

the current environment, the module is compiled into that view in the

appropriate library.

<p>By introducing views, we can simplify the library structure needed to

execute our example. Here is the latest lib.map file, which includes

the configLib library:

//-------------------------------------------------------------

// This file: /root/projects/proj5/tb/lib.map

// library mapping file specifying all source files

// including configurations

//-------------------------------------------------------------

library dmaLib file "./dma.v";

library gateLib file "../gates/alu.vg";

library stuffLib dir "../stuff";

library myLib file "./*.v", file "../vlog/*.v";

library configLib file "./*.cfg";

<p>By introducing the concept of views, the lib.map file would look like

this:

//-------------------------------------------------------------

// This file: /root/projects/proj5/tb/lib.map

// library mapping file specifying all source files

// including configurations

//-------------------------------------------------------------

library dmaLib file "./dma.*",

               file "../gates/dma.vg",

               file "../gates/f*.vg"; // fifo.vg and fsm.vg

library stuffLib dir "../stuff",

               file "../gates/a??.vg", // alu.vg and arb.vg

               file "../gates/memctl.vg";

library myLib file "./*.v", file "../vlog/*.v",

<p>view rtl file ".../*.v";

view gate file "../gates/*.vg";

view config file "./*.cfg";

//=============================================================

<p>The viewlist item for library declarations specifies the order in

which to search for a particular view in the library. By default, the

views shall be searched in the order in which they are declared in the

lib.map file. If no views are declared in the lib.map file, but

multiple views are created via some other mechanism, then the views

hall be searched in alphabetical order.

<p>viewlist_spec ::= viewlist view_identifier {, view_identifier}

<p>For example, the above lib.map file will cause the rtl view to be

taken ahead of the gate view for all libraries. If we want the gate

view to be taken ahead of the rtl view for the dmaLib library, then we

would modify the dmaLib library declaration as follows:

<p>library dmaLib file "./dma.*",

               file "../gates/dma.vg",

               file "../gates/f*.vg", // fifo.vg and fsm.vg

               viewlist gate rtl;

<p>Adding views to the library structure also allows us to introduce two

new config clauses, the library selection clause and the viewlist

expansion clause:

<p><<lib_clause> ::= lib <<library_identifier>

<p><<view_list_clause> ::= viewlist [<<view_name_list>]

<p>The lib selection clause applies to all cells selected from the

pecified library. The lib selection clause may only be modified by a

viewlist clause, although a viewlist clause may be used with any

election clause. As in the library declaration, the viewlist clause

pecifies the order in which views are to be searched for the

pecified cell.

<p>//-------------------------------------------------------------------

// 6A view-based version of example 2B:

// configuration using rtl for the dma module

// and submodules (fsm and fifo), gates for other

// synthesized modules, and rtl for the rest

// This file: /root/projects/proj5/tb/config_6a.cfg

//-------------------------------------------------------------------

config config_6a;

  design myLib.tb;

  default liblist dmaLib stuffLib myLib;

  lib dmaLib viewlist rtl;

  lib stuffLib viewlist gate rtl;

  lib myLib viewlist rtl;

endconfig

<p>//-------------------------------------------------------------------

// 6B view-based version of example 3A:

// configuration using gate-level for tb.g1.grmod.dma.fsm

// This file: /root/projects/proj5/tb/config_6b.cfg

//-------------------------------------------------------------------

config config_6b;

  design myLib.tb;

  default liblist dmaLib stuffLib myLib;

  default viewlist rtl gate config; // redundant - specified in lib.map

  path tb.g1.grmod.dma viewlist gate;

endconfig

<p>//-------------------------------------------------------------------

// 6C view-based version of example 3B:

// configuration using gate-level for tb.g1.grmod.dma.fsm

// Using cell_inst_name in path clause

// This file: /root/projects/proj5/tb/config_6c.cfg

//-------------------------------------------------------------------

config config_6c;

  design myLib.tb;

  default liblist dmaLib stuffLib myLib;

  default viewlist rtl gate;

  path (myLib.tb:rtl)tb.(myLib.top:rtl)g1.(myLib.gr:rtl)grmod.

       (dmaLib.dma:rtl)dma.(dmaLib.fsm:gate)

       viewlist gate;

endconfig

<p>//-------------------------------------------------------------------

// 6D view-based version of example 4B:

// configuration using gate-level dma controller

// Using cell selection clause and binding expansion clause

// This file: /root/projects/proj5/tb/config_6d.cfg

//-------------------------------------------------------------------

config config_6d;

  design myLib.tb;

  default liblist stuffLib myLib dmaLib;

  default viewlist rtl gate;

  cell dma binding dmaLib.dma:gate;

endconfig

<p>//-------------------------------------------------------------------

// 6E view-based version of example 5A:

// Testbench config referencing hierarchical config for dma

// This file: /root/projects/proj5/tb/config_6e.cfg

//-------------------------------------------------------------------

config config_6e;

  design myLib.tb;

  default liblist stuffLib myLib dmaLib;

  default viewlist rtl gate config;

  cell dma binding dmaLib.dma:config;

endconfig

<p>//-------------------------------------------------------------------

// 6E: hierarchical config for dma

// This file: /root/projects/proj5/tb/dma2.cfg

//-------------------------------------------------------------------

config dma2;

  design dmaLib.dma:rtl;

  cell fsm binding fsm:gate;

  cell fifo binding fifo:gate;

endconfig

<p>When searching for a cell to bind to the current unbound instance, and

in the absence of an applicable binding expansion clause, the current

library list is searched in the specified order. The current library

list is selected by the selection clauses. If no library list clause

is selected, or the selected library list is empty, then the library

list contains the single name that is the library in which the cell

containing the unbound instance is found.

<p>Notice in the dma2 config that the library is omitted from the binding

clauses for fsm and fifo. Since no library is specified, the current

library is dmaLib from the design statement, so that is the library

earched.

<p>6.2 Stoplist Expansion Clause

<p>A stop list clause defines an unordered list of view names where

hierarchical expansion should stop even if the selected view has

unbound instances.

<p><<stop_list_clause> ::= stoplist [<<view_name_list>]

<p>During expansion, if a stop list clause is specified and the current

cell is bound to a view name which exists on the stop list, then the

cell should be bound and further hierarchical expansion is halted.

The current stop list is selected by the selection clauses. If no stop

list clause is selected, or if the currently selected stop list is

empty, then expansion halts when the currently selected lib.cell:view

has no instances.

<p>NOTE: Stop lists are extremely handy for purposes other than

imulation. For instance, a timing analysis tool may want to set a

top list equal to view names which contain timing characterization

data for the cell (TLF, DCL, etc.), even though further hierarchical

decomposition may be necessary for a simulation model. Similar

abstractions may exist for synthesis, layout, floor planning, etc.

<p>7. Creating Multiple Views

<p>The set of view specifications in the lib.map file is to be used by

the compiler (whether it is separate from, or embedded in, the

imulator) to know in which view to compile the current module, based

on the current state of the environment. The state of the environment

includes:

<p>What file am I parsing/compiling?

What macros are defined? What are their values (if any)?

What command line arguments are in effect?

<p>The view specifications in the lib.map file define the default set of

views to be searched for in the absence of a config. However, a config

may select a view that is not necessarily defined in the lib.map

file. This is useful in debug situations where the developer wants to

create a new temporary view of a cell and use it for particular

instances without modifying the lib.map file. The developer may then

create a new config which references this view for the appropriate

instances. This scheme requires methods external to the lib.map file

for specifying the view in which to compile a module.

<p>To that end, we also propose two new compiler directives:

<p>`view [<<view_name>]

`library [<<library_name>]

<p>NOTE: These compiler directives may not appear within a module,

macromodule, udp or config declaration.

<p>There also needs to be an implementation-specific command-line method

for specifying to the compiler the library and view to be used. For

this discussion, we shall use

<p>+view[+<<viewname>]

+library[+<<libraryname>]

<p>If no argument is given to either the compiler directive or the

command-line argument, then the compiler shall revert to the library

and view specifications in the lib.map file.

<p>In order to ease debugability of library bindings, we also propose a

new escape sequence for format specifications ($display, etc):

<p>%l or %L - Display library binding (i.e. lib.cell:view)

<p>7.1 A Walkthrough Example

<p>This section shall walk through a typical development/debug scenario

using the example design to demonstrate how libraries and views may be

managed. Our lib.map file looks like this:

<p>//-------------------------------------------------------------

// This file: /root/projects/proj5/tb/lib.map

// library mapping file specifying all source files

// including configurations

//-------------------------------------------------------------

library dmaLib file "./dma.*",

               file "../gates/dma.vg",

               file "../gates/f*.vg"; // fifo.vg and fsm.vg

library stuffLib dir "../stuff",

               file "../gates/a??.vg", // alu.vg and arb.vg

               file "../gates/memctl.vg";

library myLib file "./*.v", file "../vlog/*.v",

<p>view rtl file ".../*.v";

view gate file "../gates/*.vg";

view config file "./*.cfg";

//=============================================================

<p>We will begin by simulating the rtl view of all elements in the

design. The view order in the lib.map file indicates that the rtl view

will always be chosen first, so we don't actually need a config. We

could use the same .f file from the old use-model:

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/tb/run_old.f

// Including alu.vg

//-------------------------------------------------------------------

tb.v

../vlog/host.v

../vlog/gr.v

../vlog/fb.v

../vlog/mem.v

-v ./dma.v

-y ../stuff

+libext+.v

<p>In the old use model, the invocation would be:

<p>verilog -f run_old.f

<p>NOTE: Even in a "multi-pass" implementation, the same -f file could be

used as the command-line to the parser/compiler.

<p>When file tb.v is parsed, its file path is compared against the

library and view specifications in the lib.map file. The result is

that the compiled form is placed in myLib.tb:rtl. The same operation

is performed as each of the other files is parsed, and since all files

match the file specification for the rtl view, they are all placed in

the rtl view in the appropriate library.

<p>In order to bind the instances in the design, the tool begins with the

top level cell of the design, myLib.tb:rtl. In order to bind instance

tb.g1, it looks for cell 'top' in libraries dmaLib, stuffLib and myLib

(in that order). In a single-pass implementation, all of the source

files shall be scanned until the 'top' module declaration is

found. When it is found, the file path is compared to the lib.map file

and the module is placed in myLib.top:rtl and this cell is bound to

tb.g1. The same process is followed for binding the subinstances in

module top, and recursively down through the hierarchy.

<p>If multiple module declarations are found with the same name, then

each module declaration shall be compared to the lib.map file.

Regardless of the order in which the source descriptions are

found, they shall be compared first to the library declarations in the

order in which the library declarations appear in the lib.map file. If

multiple module declarations match the same library specification, the

they shall be compared against the view specifications in the order in

which the views appear in the lib.map file. If multiple module

declarations match the same library and view specifications, it shall

be an error.

<p>On subsequent reinvocations of the same command line, the tool may

rescan the source files and either detect that the cells already exist

in the library, or it may recompile the cells and overwrite the

library cells.

<p>In order to achieve the same design configuration using a config, we

could add a config file to the command line.

//-------------------------------------------------------------------

// 7A Walkthru example

// configuration using rtl for all modules

// This file: /root/projects/proj5/tb/config_7a.cfg

//-------------------------------------------------------------------

config config_7a;

  design myLib.tb:rtl;

  default liblist dmaLib stuffLib myLib;

  default viewlist rtl gate config; // redundant (for now)

                   // viewlist could be taken from lib.map order

endconfig

<p>invocation: verilog -f run_old.f config_7a.cfg

<p>In this case, the parser/compiler must scan the set of source files to

locate any configs that may be necessary to determine the binding of

ubinstances. This must happen regardless of the contents of the

lib.map file. This config explicitly states that the top-level module

in the design is myLib.tb:rtl. It may either:

<p>1) scan all of the source files until the source description matching

myLib.tb:rtl is encountered and compile it, or

2) scan through all of the source files and compile all modules/udps

encountered into the appropriate lib.cell:view, and then go back and

earch the library to find myLib.tb:rtl.

<p>Now, suppose that we want to debug this design to verify the hierarchy

of the design. In this example, we shall modify the dma.v file to

print the hierarchical path to the module:

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/vlog/dma.v

// dma controller, including fsm and fifo

// modified to include DEBUG_H macro

//-------------------------------------------------------------------

module dma(...);

  ...

`ifdef DEBUG_H

  initial $display("dma: %m");

`endif

  fsm fsm(...);

  fifo fifo(...);

  ...

endmodule

<p>If we don't define the DEBUG_H macro, then this module will be no

different from the rtl version. In fact, we want to keep the ability

to use both versions, with and without the debug functionality. To do

this, we want to map the version compiled with DEBUG_H defined into a

new view of the same cell. This ability requires separate compile and

imulation steps, since we need to parse/compile the same module

description multiple times (once with DEBUG_H define and once with

DEBUG_H undefined). There are multiple ways of specifying a new view

of the dma module with DEBUG_H defined. In the absence of a config,

the only way to make it visible is to add it to the lib.map file:

<p>view debugH macro DEBUG_H;

view rtl file ".../*.v";

view gate file "../gates/*.vg";

view config file "./*.cfg";

<p>The macro, directive and arg clauses of a view specification take

precedence over the file and dir clauses. In this way, any module

compiled with DEBUG_H defined, regardless of its file path, will be

placed in the debugH view. This is true regardless of the order in the

lib.map file, but for this example we have placed debugH first so

that, in the absence of a config, the debugH view will be used if it

exists.

<p>invocation: verilog run_old.f +define+DEBUG_H

<p>NOTE: The compiler must be able to determine the set of macros used by

a particular module. If a module does not contain the DEBUG_H macro,

then it does not match the debugH view specification and shall be

placed in the rtl view according to its file path.

<p>We can still go back to the non-debug version by removing the +define

from the command line:

<p>invocation: verilog run_old.f

<p>For tools which are optimized to reduce compilation time, since we've

already run this simulation once, the tool may determine that none of

the modules need to be recompiled and may simply bind the rtl view to

each instance. As the design is scanned, no module declarations match

the debugH view specification (because DEBUG_H is not defined), so the

debugH view shall not be searched, even if it exists.

<p>To go back to the debug version, again no recompilation is strictly

necessary (since the debugH view was compiled the first time), but the

new binding shall take effect.

<p>If the debugH view specification is removed from the lib.map file,

then the debugH view must be explicitly created. From the command line

it could be created by explicitly compiling only the dma.v file:

<p>invocation: compile ../vlog/dma.v +define+DEBUG_H +view+debugH

<p>or by modifying the dma.v file as follows:

<p>//-------------------------------------------------------------------

// This file: /root/projects/proj5/vlog/dma.v

// dma controller, including fsm and fifo

// modified to include DEBUG_H macro

//-------------------------------------------------------------------

`ifdef DEBUG_H

  `view debugH

`endif

module dma(...);

  ...

`ifdef DEBUG_H

  initial $display("dma: %m");

`endif

  fsm fsm(...);

  fifo fifo(...);

  ...

endmodule

`ifdef DEBUG_H

  `view // reset to lib.map views

`endif

<p><p>invocation: compile ../vlog/dma.v +define+DEBUG_H

<p>This mechanism is more useful for library developers who want to

provide the capability of optionally including debug (or other)

information in a simulation. For individual developers who may want to

create a temporary version of a cell which includes the debug

information, the +view command-line option is much easier.</bigger>

---------------

Tom Fitzpatrick

<p>Senior Technical Marketing Manager Cadence Design Systems, Inc.

Cycle Simulation Products 270 Billerica Rd.

Logic Design and Verification Business Unit Chelmsford, MA 01824

x6438 (978)446-6438
</x-rich>
--=_AABYJQAANw43glcI--



This archive was generated by hypermail 2.1.4 : Mon Jul 08 2002 - 12:53:25 PDT and
sponsored by Boyd Technology, Inc.