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.