2 * Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ident "$Id: netlist.txt,v 1.10 2000/07/23 18:06:15 steve Exp $"
22 Note that the netlist.h header contains detailed descriptions of how
23 things work. This is just an overview.
27 The output from the parse and elaboration steps is a "netlist" rooted
28 in a Design object. Parsing translates the design described in the
29 initial source file into a temporary symbolic "pform". Elaboration
30 then expands the design, resolving references and expanding
31 hierarchies, to produce a flattened netlist. This is the form that
32 optimizers and code generators use.
34 The design optimization processes all manipulate the netlist,
35 translating it to a (hopefully) better netlist after each step. The
36 complete netlist is then passed to the code generator, the emit
37 function, where the final code (in the target format) is produced.
39 STRUCTURAL ITEMS: NetNode and NetNet
41 Components and wires, memories and registers all at their base are
42 either NetNode objects or NetNet objects. Even these classes are
43 derived from the NetObj class.
45 All NetNode and NetNet objects have a name and some number of
46 pins. The name usually comes from the Verilog source that represents
47 that object, although objects that are artifacts of elaboration will
48 have a generated (and probably unreadable) name. The pins are the
49 ports into the device. NetNode objects have a pin for each pin of the
50 component it represents, and NetNet objects have a pin for each signal
53 Node and net pins can be connected together via the connect
54 function. Connections are transitive (A==B and B==c means A==C) so
55 connections accumulate on a link as items are connected to it. The
56 destructors for nets and nodes automatically arrange for pins to be
57 disconnected when the item is deleted, so that the netlist can be
58 changed during processing.
62 The NetNode and NetNet classes contain arrays of Link objects, one
63 object per pin. Each pin is a single bit. The Link objects link to all
64 the NetNode and NetNet objects' links that are connected together in
65 the design, and to a Nexus object. This way, code that examines a node
66 of the design can discover what is connected to each pin.
68 The connected set of links also has common properties that are stored
69 or access from the Nexus object. All the Links that are connected
70 together are also connected to a single Nexus object. This object is
71 useful for accessing the properties and values that come from the
72 connected set of links. The Nexus object is also handy for iterating
73 over the connected set of Links.
75 See the Link class definition in netlist.h for a description of the link
76 methods, and the Nexus class for nexus global methods.
78 Currently, a link has 3 possible direction properties:
80 PASSIVE -- These pins are sampled by the object that holds the
81 pin based on some external event. These are used,
82 for example, by NetESignal objects that read a
83 point for a procedural expression.
85 INPUT -- These pins potentially react to the setting of its
88 OUTPUT -- These pins potentially drive the node. (They may be
92 BEHAVIORAL ITEMS: NetProcTop, NetProc and derived classes
94 Behavioral items are not in general linked to the netlist. Instead,
95 they represent elaborated behavioral statements. The type of the object
96 implies what the behavior of the statement does. For example, a
97 NetCondit object represents an ``if'' statement, and carries a
98 condition expression and up to two alternative sub-statements.
100 At the root of a process is a NetProcTop object. This class carries a
101 type flag (initial or always) and a single NetProc object. The
102 contained statement may, depending on the derived class, refer to
103 other statements, compound statements, so on. But at the root of the
104 tree is the NetProcTop object. The Design class keeps a list of the
105 elaborated NetProcTop objects. That list represents the list of
106 processes in the design.
108 INTERACTION OF BEHAVIORAL AND STRUCTURAL: NetAssign_
110 The behavioral statements in a Verilog design effect the structural
111 aspects through assignments to registers. Registers are structural
112 items represented by the NetNet class, linked to the assignment
113 statement through pins. This implies that the l-value of an assignment
114 is structural. It also implies that the statement itself is
115 structural, and indeed it is derived from NetNode.
117 The NetAssign_ class is also derived from the NetProc class because
118 what it does is brought on by executing the process. By multiple
119 inheritance we have therefore that the assignment is both a NetNode
120 and a NetProc. The NetAssign_ node has pins that represent the l-value
121 of the statement, and carries behavioral expressions that represent
122 the r-value of the assignment.
126 The netlist form includes the NetMemory type to hold the content of a
127 memory. Instances of this type represent the declaration of a memory,
128 and occur once for each memory. References to the memory are managed
129 by the NetEMemory and NetAssignMem_ classes.
131 An instance of the NetEMemory class is created whenever a procedural
132 expression references a memory element. The operand is the index to
133 use to address (and read) the memory.
135 An instance of the NetAssignMem_ class is created when there is a
136 procedural assignment to the memory. The NetAssignMem_ object
137 represents the l-value reference (a write) to the memory. As with the
138 NetEMemory class, this is a procedural reference only.
140 When a memory reference appears in structural context (i.e. continuous
141 assignments) elaboration creates a NetRamDq. This is a LPM_RAM_DQ
142 device. Elaboration leaves the write control and data input pins
143 unconnected for now, because memories cannot appear is l-values of
144 continuous assignments. However, the synthesis functor may connect
145 signals to the write control lines to get a fully operational RAM.
147 By the time elaboration completes, there may be many NetAssignMem_,
148 NetEMemory and NetRamDq objects referencing the same NetMemory
149 object. Each represents a port into the memory. It is up to the
150 synthesis steps (and the target code) to figure out what to do with
155 Expressions are represented as a tree of NetExpr nodes. The NetExpr
156 base class contains the core methods that represent an expression
157 node, including virtual methods to help with dealing with nested
158 complexities of expressions.
160 Expressions (as expressed in the source and p-form) may also be
161 elaborated structurally, where it makes sense. For example, assignment
162 l-value expressions are represented as connections to pins. Also,
163 continuous assignment module items are elaborated as gates instead of
164 as a procedural expression. Event expressions are also elaborated
165 structurally as events are like devices that trigger behavioral
168 However, typical expressions the behavioral description are
169 represented as a tree of NetExpr nodes. The derived class of the node
170 encodes what kind of operator the node represents.
174 The expression (represented by the NetExpr class) has a bit width that
175 it either explicitly specified, or implied by context or contents.
176 When each node of the expression is first constructed during
177 elaboration, it is given, by type and parameters, an idea what its
178 width should be. It certain cases, this is definitive, for example
179 with signals. In others, it is ambiguous, as with unsized constants.
181 As the expression is built up by elaboration, operators that combine
182 expressions impose bit widths of the environment or expose the bit
183 widths of the sub expressions. For example, the bitwise AND (&)
184 operator has a bit size implied by its operands, whereas the
185 comparison (==) operator has a bit size of 1. The building up of the
186 elaborated expression checks and adjusts the bit widths as the
187 expression is built up, until finally the context of the expression
188 takes the final bit width and makes any final adjustments.
190 The NetExpr::expr_width() method returns the calculated (or guessed)
191 expression width. This method will return 0 until the width is set by
192 calculation or context. If this method returns false, then it is up to
193 the context that wants the width to set one. The elaboration phase
194 will call the NetExpr::set_width method on an expression as soon as it
195 gets to a point where it believes that it knows what the width should
198 The NetExpr::set_width(unsigned) virtual method is used by the context
199 of an expression node to note to the expression that the width is
200 determined and please adapt. If the expression cannot reasonably
201 adapt, it will return false. Otherwise, it will adjust bit widths and
204 XXXX I do not yet properly deal with cases where elaboration knows for
205 XXXX certain that the bit width does not matter. In this case, I
206 XXXX really should tell the expression node about it so that it can
207 XXXX pick a practical (and optimal) width.
209 INTERACTION OF EXPRESSIONS AND STRUCTURE: NetESignal
211 The NetAssign_ class described above is the means for processes to
212 manipulate the net, but values are read from the net by NetESignal
213 objects. These objects are class NetExpr because they can appear in
214 expressions (and have width). They are not NetNode object, but hold
215 pointers to a NetNet object, which is used to retrieve values with the
216 expression is evaluated.
219 HIERARCHY IN NETLISTS
221 The obvious hierarchical structure of Verilog is the module. The
222 Verilog program may contain any number of instantiations of modules in
223 order to form an hierarchical design. However, the elaboration of the
224 design into a netlist erases module boundaries. Modules are expanded
225 each place they are used, with the hierarchical instance name used to
226 name the components of the module instance. However, the fact that a
227 wire or register is a module port is lost.
229 The advantage of this behavior is first the simplification of the
230 netlist structure itself. Backends that process netlists only need to
231 cope with a list of nets, a list of nodes and a list of
232 processes. This eases the task of the backend code generators.
234 Another advantage of this flattening of the netlist is that optimizers
235 can operate globally, with optimizations freely crossing module
236 boundaries. This makes coding of netlist transform functions such as
237 constant propagation more effective and easier to write.
240 SCOPE REPRESENTATION IN NETLISTS
242 In spite of the literal flattening of the design, scope information is
243 preserved in the netlist, with the NetScope class. The Design class
244 keeps a single pointer to the root scope of the design. This is the
245 scope of the root module. Scopes that are then created within that
246 (or any nested) module are placed as children of the root scope, and
247 those children can have further children, and so on.
249 Each scope in the tree carries its own name, and its relationship to
250 its parent and children. This makes it possible to walk the tree of
251 scopes. In practice, the walking of the scopes is handled by recursive
254 Each scope also carries the parameters that are applicable to the
255 scope itself. The parameter expression (possibly evaluated) can be
256 located by name, given the scope object itself. The scan of the pform
257 to generate scopes also places the parameters that are declared in the
258 scope. Overrides are managed during the scan, and once the scan is
259 complete, defparam overrides are applied.
264 The flattening of the design does not include tasks and named
265 begin-end blocks. Tasks are behavioral hierarchy (whereas modules are
266 structural) so do not easily succumb to the flattening process. In
267 particular, it is logically impossible to flatten tasks that
268 recurse. (The elaboration process does reserve the right to flatten
269 some task calls. C++ programmers recognize this as inlining a task.)
272 TIME SCALE IN NETLISTS
274 The Design class and the NetScope classes carry time scale and
275 resolution information of the elaborated design. There is a global
276 resolution, and there are scope specific units and resolutions. Units
277 and resolutions are specified as signed integers, and interpreted as
278 the power of 10 of the value. For example, a resolution "-9" means
279 that "1" is 1ns (1e-9). The notation supports units from -128 to +127.
280 It is up to the back-ends to interpret "-4" as "100us".
282 Delays are expressed in the netlist by integers. The units of these
283 delays are always given in the units of the design precision. This
284 allows everything to work with integers, and generally places the
285 burden of scaling delays into elaboration. This is, after all, a
286 common task. The Design::get_precision() method gets the global design
289 Each NetScope also carries its local time_units and time_precision
290 values. These are filled in during scope elaboration and are used in
291 subsequent elaboration phases to arrange for scaling of delays. This
292 information can also be used by the code generator to scale times back
293 to the units of the scope, if that is desired.
295 $Log: netlist.txt,v $
296 Revision 1.10 2000/07/23 18:06:15 steve
297 Document time scale in netlists.
299 Revision 1.9 2000/07/14 06:12:57 steve
300 Move inital value handling from NetNet to Nexus
301 objects. This allows better propogation of inital
304 Clean up constant propagation a bit to account
305 for regs that are not really values.
307 Revision 1.8 2000/03/08 04:36:54 steve
308 Redesign the implementation of scopes and parameters.
309 I now generate the scopes and notice the parameters
310 in a separate pass over the pform. Once the scopes
311 are generated, I can process overrides and evalutate
312 paremeters before elaboration begins.
314 Revision 1.7 1999/11/28 23:42:02 steve
315 NetESignal object no longer need to be NetNode
316 objects. Let them keep a pointer to NetNet objects.
318 Revision 1.6 1999/11/21 00:13:09 steve
319 Support memories in continuous assignments.
321 Revision 1.5 1999/11/02 04:55:34 steve
322 Add the synthesize method to NetExpr to handle
323 synthesis of expressions, and use that method
324 to improve r-value handling of LPM_FF synthesis.
326 Modify the XNF target to handle LPM_FF objects.
328 Revision 1.4 1999/09/29 00:03:27 steve
329 Spelling fixes from Larry.
331 Revision 1.3 1999/07/24 02:11:20 steve
332 Elaborate task input ports.
334 Revision 1.2 1999/07/21 01:15:29 steve
335 Document netlist semantics.
337 Revision 1.1 1999/05/27 04:13:08 steve
338 Handle expression bit widths with non-fatal errors.