2 * Copyright (c) 2001 Stephen Williams (steve@icarus.com)
4 * $Id: README.txt,v 1.82 2007/03/22 16:08:19 steve Exp $
9 The VVP simulator takes as input source code not unlike assembly
10 language for a conventional processor. It is intended to be machine
11 generated code emitted by other tools, including the Icarus Verilog
12 compiler, so the syntax, though readable, is not necessarily
13 convenient for humans.
18 The source file is a collection of statements. Each statement may have
19 a label, an opcode, and operands that depend on the opcode. For some
20 opcodes, the label is optional (or meaningless) and for others it is
23 Every statement is terminated by a semicolon. The semicolon is also
24 the start of a comment line, so you can put comment text after the
25 semicolon that terminates a statement. Like so:
27 Label .functor and, 0x5a, x, y ; This is a comment.
29 The semicolon is required, whether the comment is there or not.
31 Statements may span multiple lines, as long as there is no text (other
32 then the first character of a label) in the first column of the
37 Before any other non-commentary code starts, the source may contain
38 some header statements. These are used for passing parameters or
39 global details from the compiler to the vvp run-time. In all cases,
40 the header statement starts with a left-justified keyword.
44 This header statement names a vpi module that vvp should load before
45 the rest of the program is compiled. The compiler looks in the
46 standard VPI_MODULE_PATH for files named "name.vpi", and tries to
49 * :vpi_time_precision [+|-]<value>;
51 This header statement specifies the time precision of a single tick of
52 the simulation clock. This is mostly used for display (and VPI)
53 purposes, because the engine itself does not care about units. The
54 compiler scales time values ahead of time.
56 The value is the size of a simulation tick in seconds, and is
57 expressed as a power of 10. For example, +0 is 1 second, and -9 is 1
58 nanosecond. If the record is left out, then the precision is taken to
63 Labels and symbols consist of the characters:
70 Labels and symbols may not start with a digit or a '.', so that they
71 are easily distinguished from keywords and numbers. A Label is a
72 symbol that starts a statement. If a label is present in a statement,
73 it must start in the first text column. This is how the lexical
74 analyzer distinguishes a label from a symbol. If a symbol is present
75 in a statement, it is in the operand. Opcodes of statements must be a
78 Symbols are references to labels. It is not necessary for a label to
79 be declared before its use in a symbol, but it must be declared
80 eventually. When symbols refer to functors, the symbol represents the
81 vvp_ipoint_t pointer to the output. (Inputs cannot, and need not, be
82 references symbolically.)
84 If the functor is part of a vector, then the symbol is the
85 vvp_ipoint_t for the first functor. The [] operator can then be used
86 to reference a functor other than the first in the vector.
88 There are some special symbols that in certain contexts have special
89 meanings. As inputs to functors, the symbols "C<0>", "C<1>", "C<x>"
90 and "C<z>" represent a constant driver of the given value.
95 The syntax of a scope statement is:
97 <label> .scope <type>, <instance>, <declaration>, <parent> ;
99 The <type> is the general type of the scope: module, function, task,
100 begin, fork or generate.
102 The <instance> is a string that is the base name of the instance. For
103 modules, this is the instance name. For tasks, this is the task name.
105 The <declaration> is a string that represents the declaration. For
106 modules, this is the name of the module given in the module
107 declaration, and *not* the instantiation. For tasks and functions,
108 this is the hierarchical name of the path to the declaration. This is
109 because the declaration can be different within different module
112 Finally, the <parent> is the label for the parent scope for this
113 one. Root scopes leave this out. Otherwise, this label references
114 another .scope record.
116 PARAMETER STATEMENTS:
118 Parameters are named constants within a scope. These parameters have a
119 type and value, and also a label so that they can be referenced as VPI
122 The syntax of a parameter is:
124 <label> .param/str <name>, <value>;
125 <label> .param/b <name>, <value> [<msb>,<lsb>];
126 <label> .param/l <name>, <value> [<msb>,<lsb>];
127 <label> .param/r <name>, <value>;
129 The <name> is a string that names the parameter. The name is placed in
130 the current scope as a vpiParameter object. The .param suffix
131 specifies the parameter type.
133 .param/str -- The parameter has a string value
134 .param/l -- The parameter has a logic vector value
135 .param/b -- The parameter has a boolean vector value
136 .param/r -- The parameter has a real value
138 The value, then, is appropriate for the data type. For example:
140 P_123 .param/str "hello", "Hello, World.";
142 The boolean and logic values can also be signed or not. If signed, the
143 value is preceeded by a '+' character. (Note that the value is 2s
144 compliment, so the '+' says only that it is signed, not positive.)
148 A functor statement is a statement that uses the ``.functor''
149 opcode. Functors are the basic structural units of a simulation, and
150 include a type (in the form of a truth table) and up to four inputs. A
151 label is required for functors.
153 The general syntax of a functor is:
155 <label> .functor <type>, symbol_list ;
156 <label> .functor <type> [<drive0> <drive1>], symbol_list ;
158 The symbol list is 4 names of labels of other functors. These connect
159 inputs of the functor of the statement to the output of other
160 functors. If the input is unconnected, use a C<?> symbol instead. The
161 type selects the truth lookup table to use for the functor
162 implementation. Most of the core gate types have built in tables.
164 The initial values of all the inputs and the output is x. Any other
165 value is passed around as run-time behavior. If the inputs have C<?>
166 symbols, then the inputs are initialized to the specified bit value,
167 and if this causes the output to be something other than x, a
168 propagation event is created to be executed at the start of run time.
170 The strengths of inputs are ignored by functors, and the output has
171 fixed drive0 and drive1 strengths. So strength information is
172 typically lost as it passes through functors.
174 Almost all of the structural aspects of a simulation can be
175 represented by functors, which perform the very basic task of
176 combining up to four inputs down to one output.
188 The Verilog language itself does not have a DFF primitive, but post
189 synthesis readily creates DFF devices that are best simulated with a
190 common device. Thus, there is the DFF statement to create DFF devices:
192 <label> .dff <d>, <clk>, <ce>, <async-input>;
194 The generated functor is generally synchronous on the <clk> rising
195 edge of <clk>, with the <ce> enable active high. The <clk> and <ce>
196 are single bit vectors (or scalars) on ports 1 and 2. Port-0 is any
197 type of datum at all. The device will transfer the input to the output
198 when it is loaded by a clock. The <async-input> is a special
199 asynchronous input that is immediately stored and transferred to the
200 output when data arrives here. This is useful for implementing
201 asynchronous set/clear functions.
205 A UDP statement either defines a User Defined Primitive, or
206 instantiates a previously defined UDP by creating a UDP functor. A
207 UDP functor has as many inputs as the UDP definition requires.
209 UDPs come in sequential and combinatorial flavors. Sequential UDPs
210 carry an output state and can respond to edges at the inputs. The
211 output of combinatorial UDPs is a function of its current inputs
214 The function of a UDP is defined via a table. The rows of the table
215 are strings which describe input states or edges, and the new output
216 state. Combinatorial UDPs require one character for each input, and
217 one character at the end for the output state. Sequential UDPs need
218 an additional char for the current state, which is the first char of
221 Any input transition or the new state must match at most one row (or
222 all matches must provide the same output state). If no row matches,
223 the output becomes 1'bx.
225 The output state can be specified as "0", "1", or "x". Sequential
226 UDPs may also have "-": no change.
228 An input or current output state can be
238 For Sequential UDPs, at most one input state specification may be
239 replaced by an edge specification. Valid edges are:
241 "*": (??) "_": (?0) "+": (?1) "%": (?x)
242 "P": (0?) "r": (01) "Q": (0x)
243 "N": (1?) "f": (10) "M": (1x)
244 "B": (x?) "F": (x0) "R": (x1)
249 A combinatorial UDP is defined like this:
251 <type> .udp/comb "<name>", <number>, "<row0>", "<row1>", ... ;
253 <type> is a label that identifies the UDP. <number> is the number of
254 inputs. "<name>" is there for public identification. Sequential UDPs
255 need an additional initialization value:
257 <type> .udp/sequ "<name>", <number>, <init>, "<row0>", "<row1>", ... ;
259 <init> is the initial value for all instances of the UDP. We do not
260 provide initial values for individual instances. <init> must be a
261 number 0, 1, or 2 (for 1'bx).
263 A UDP functor instance is created so:
265 <label> .udp <type>, <symbol_list> ;
267 Where <label> identifies the functor, <type> is the label of a UDP
268 defined earlier, and <symbol_list> is a list of symbols, one for each
274 A variable is a bit vector that can be written by behavioral code (so
275 has no structural input) and propagates its output to a functor. The
276 general syntax of a variable is:
278 <label> .var "name", <msb>, <lsb>;
279 <label> .var/s "name", <msb>, <lsb>;
280 <label> .var/real "name", <msb>, <lsb>;
282 The "name" is the declared base name of the original variable, for the
283 sake of VPI code that might access it. The variable is placed in the
284 current scope. The variable also has a width, defined by the indices
285 for the most significant and lest significant bits. If the indices are
286 equal (normally 0) the vector has width of one. If the width is greater
287 then one, a contiguous array of functors is created and the value of
288 the label is the address of the least significant bit.
290 A variable does not take inputs, since its value is set behaviorally
291 by assignment events. It does have output, though, and its output is
292 propagated into the net of functors in the usual way.
294 A variable gets its value by assignments from procedural code: %set
295 and %assign. These instructions write values to the port-0 input. From
296 there, the value is held.
298 Behavioral code can also invoke %cassign/v statements that work like
299 %set/v, but instead write to port-1 of the variable node. Writes to
300 port-1 of a variable activate continuous assign mode, where the values
301 written to port-0 are ignored. The continuous assign mode remains
302 active until a long(1) is written to port-3 (a command port).
304 Behavioral code may also invoke %force/v statements that write to port-2
305 to invoke force mode. This overrides continuous assign mode until a
306 long(2) is written to port-3 to disable force mode.
310 A net is similar to a variable, except that a thread cannot write to
311 it (unless it uses a force) and it is given a different VPI type
312 code. The syntax of a .net statement is also similar to but not
313 exactly the same as the .var statement:
315 <label> .net "name", <msb>, <lsb>, <symbol>;
316 <label> .net/s "name", <msb>, <lsb>, <symbol>;
317 <label> .net8 "name", <msb>, <lsb>, <symbol>;
318 <label> .net8/s "name", <msb>, <lsb>, <symbol>;
319 <label> .net/real "name", <msb>, <lsb>, <symbol>;
320 <label> .alias "name", <msb>, <lsb>, <symbol>;
323 Like a .var statement, the .net statement creates a VPI object with
324 the basename and dimensions given as parameters. The symbol is a
325 functor that feeds into the vector of the net, and the vpiHandle
326 holds references to that functor.
328 The input of a .net is replicated to its output. In this sense, it
329 acts like a diode. The purpose of this node is to hold various VPI
330 and event trappings. The .net and .net8 nodes are vector types. They
331 both may represent wires, but the .net8 nodes preserve strength values
332 that arrive through them, while .net nodes reduce strength values to
333 4-value logic. The .net8 nodes should only be used when strength
334 information really is possible.
336 The <label> is required and is used to locate the net object that is
337 vrepresents. This label does not map to a functor, so only references
338 that know they want to access .nets are able to locate the symbol. In
339 particular, this includes behavioral %load and %wait instructions. The
340 references to net and reg objects are done through the .net label
341 instead of a general functor symbol. The instruction stores the
342 functor pointer, though.
344 The .alias statements do not create new nodes, but instead create net
345 names that are aliases of an existing node. This handles special cases
346 where a net has different names, possibly in different scopes.
350 Delay nodes are structural net delay nodes that carry and manage
351 propagation delays. Delay nodes can have fixed delays or variable
352 delays. Fixed delay nodes have only the input that is to be
353 delayed. The delay amount is given on the node line. Variable delay
354 nodes have three extra inputs to receive the rise, fall and decay
355 times that are used for delay.
357 .delay ( <rise>, <fall>, <decay> ) <input> ;
358 .delay <input>, <rise>, <fall>, <decay> ;
360 The first form above takes three constant numbers as the initial
361 delay, and takes a single input. The second form takes 4 net inputs,
362 with the first being the value to delay, and the remaining to be the
365 MODULE PATH DELAY STATEMENTS:
367 A module path delay takes data from its input, then a list of module
368 path delays. The <src> for each possible delay set is a trigger that
371 .modpath <input> , [ <src> (<delays> [? <condition>]) ] ;
373 ARRAY INDEX STATEMENTS:
375 Variables can be collected into arrays. The words of the array are
376 declared seperately, this statement collects them together:
378 <label> .array "name", <last> <first> ;
380 the .var or .net statements after this array statement, that have the
381 same "name" are collected, in order, as words.
383 The syntax below is different, in that it creates an alias for an
384 existing array. The dimensions and storage are taken from the .array
387 <label> .array "name", <src> ;
391 Memories are arrays of words, each word a vvp_vector4_t vector of the
392 same width. The memory is canonically addressed as a 1-dimensional
393 array of words, although indices are stored with the memory for
394 calculating a canonical address from a multi-dimensional address.
396 Three types of memory statement perform (1) creation of a memory, (2)
397 connecting a read port to an existing memory, and (3) initializing the
400 <label> .mem "name", <msb>,<lsb>, <last>,<first> ... ;
402 The pair of numbers <msb>,<lsb> defines the word width. The pair
403 <last>,<first> defines the address range. Multiple address ranges are
404 allowed for multidimensional indexing. This statement creates the
405 memory array and makes it available to procedural code.
407 Procedural access to the memory references the memory as single array
408 of words, with the base address==0, and the last address the size (in
409 words) of the memory -1. It is up to the compiler to convert Verilog
410 index sets to a canonical address. The multi-dimensional index set is
411 available for VPI use.
413 Structural read access is implemented in terms of address and data
414 ports. The addresses applied to the address port are expected to be
417 A read port is a functor that takes a single input, the read address,
418 and outputs the word value at the given (canonical) address.
420 <label> .mem/port <memid>, <address> ;
422 <label> identifies the vector of output functors, to allow connections
423 to the data output. <memid> is the label of the memory.
425 Any address input change, or any change in the addressed memory
426 contents, is immediately propagated to the port output.
428 A write port is a superset of a read port. It is a 4-input functor
429 that accepts the word address, an event input, a write enable input,
432 <label> .mem/port <memid>, <address>, <event>, <we>, <data> ;
434 <event> is an event functor that triggers a write, if the <we> input
435 is true. <data> is the input that connect to the data input
436 port. For asynchronous transparent write operation, connect
437 <event> to C4<z>, the RAM will transparently follow any changes on
438 address and data lines, while <we> is true.
440 There is no Verilog construct that calls for a structural write port
441 to a memory, but synthesis may ask for lpm_ram_d[pq] objects.
443 To initialize a memory, use:
445 .mem/init <memid> <start>, val , val ... ;
447 <memid> is the label of the memory, and the <start> is the start
448 address (canonical) of the first word to be initialized. The start
449 address allows multiple statements be used to initialize words of a
452 The values are one per word.
454 Procedural access to the memory employs an index register to address a
455 bit location in the memory, via the commands:
457 %load/m <bit>, <memid> ;
458 %set/m <memid>, <bit> ;
459 %assign/m <memid>, <delay>, <bit> ;
461 The memory bit is addressed by index register 3. The value of
462 register 3 is the index in the memory's bit space, where each data
463 word occupies a multiple of four bits.
468 Threads need to interact with the functors of a netlist synchronously,
469 as well as asynchronously. There are cases where the web of functors
470 needs to wake up a waiting thread. The web of functors signals threads
471 through .event objects, that are declared like so:
473 <label> .event <type>, <symbols_list>;
474 <label> .event "name";
477 This event statement declares an object that a %wait instruction
478 can take as an operand. When a thread executes a %wait, it puts
479 itself in the notification list of the event and suspends. The
480 <symbols_list> is a set of inputs that can trigger the event.
482 The <type> describes the conditions needed to trigger the event. It
483 may be posedge, negedge or edge. If the type is instead a "name"
484 string, then this is a named event which receives events by the %set
485 instruction instead of from the output of a functor.
487 If the event has inputs (a requirement unless it is a named event)
488 then it has up to 4 symbols that address functors. The event then
489 detects the appropriate edge on any of the inputs and signals when the
490 event is true. Normally (in Verilog) a posedge or negedge event only
491 watches a single bit, so the generated code would only include a
492 single symbol for the addressed bit. However, if there are several
493 events of the same edge in an event OR expression, the compiler may
494 combine up to 4 into a single event.
496 If many more events need to be combined together (for example due to
497 an event or expression in the Verilog) then this form can be used:
499 <label> .event/or <symbols_list>;
501 In this case, the symbols list all the events that are to be combined
502 to trigger this event. Only one of the input events needs to trigger
508 Resolver statements are strength-aware functors with 4 inputs, but
509 their job typically is to calculate a resolved output using strength
510 resolution. The type of the functor is used to select a specific
513 <label> .resolv tri, <symbols_list>;
514 <label> .resolv tri0, <symbols_list>;
515 <label> .resolv tri1, <symbols_list>;
517 The output from the resolver is vvp_vector8_t value. That is, the
518 result is a vector with strength included.
521 PART SELECT STATEMENTS:
523 Part select statements are functors with three inputs. They take in at
524 port-0 a vector, and output a selected (likely smaller) part of that
525 vector. The other inputs specify what those parts are, as a canonical
526 bit number, and a width. Normally, those bits are constant values.
528 <label> .part <symbol>, <base>, <wid>;
529 <label> .part/pv <symbol>, <base>, <wid>, <vector_wid>;
530 <label> .part/v <symbol>, <symbol>, <wid>;
532 The input is typically a .reg or .net, but can be any vector node in
535 The .part/pv variation is the inverse of the .part version, in that
536 the output is actually written to a *part* of the output. The node
537 uses special part-select-write functions to propagate a part of a
538 network. The <vector_wid> is the total width of the destination net
539 that part is written to. Destination nodes use this value to check
540 further output widths.
542 The .part/v variation takes a vector (or long) input on port-1 as the
543 base of the part select. Thus, the part select can move around.
545 PART CONCATENATION STATEMENTS:
547 The opposite of the part select statement is the part concatenation
548 statement. The .concat statement is a functor node that takes at input
549 vector values and produces a single vector output that is the
550 concatenation of all the inputs.
552 <label> .concat [W X Y Z], <symbols_list> ;
554 The "[" and "]" tokens surround a set of 4 numbers that are the
555 expected widths of all the inputs. These widths are needed to figure
556 the positions of the input vectors in the generated output, and are
557 listed in order LSB to MSB. The inputs themselves are also listed LSB
558 to MSB, with the LSB vector input coming through port-0 of the real
561 The initial output value is (W+X+Y+Z) bits of 'bx. As input values are
562 propagated, the bits are placed in the correct place in the output
563 vector value, and a new output value is propagated.
566 REPEAT VECTOR STATEMENTS:
568 The repeat vector statement is similar to the concatenation statement,
569 expect that the input is repeated a constant number of times. The
570 format of the repeat vector statement is:
572 <label> .repeat <wid>, <rept count>, <symbol> ;
574 In this statement, the <wid> is a decimal number that is the width of
575 the *output* vector. The <rept count> is the number of time the input
576 vector value is repeated to make the output width. The input width is
577 implicit from these numbers. The <symbol> is then the input source.
581 The reduction logic statements take in a single vector, and propagate
584 <label> .reduce/and <symbol> ;
585 <label> .reduce/or <symbol> ;
586 <label> .reduce/xor <symbol> ;
587 <label> .reduce/nand <symbol> ;
588 <label> .reduce/nor <symbol> ;
589 <label> .reduce/xnor <symbol> ;
591 the device has a single input, which is a vector of any width. The
592 device performs the logic on all the bits of the vector (a la Verilog)
593 and produces and propagates a single bit width vector.
597 Sign extension nodes are the opposite of reduction logic, in that they
598 take a narrow vector, or single bit, and pad it out to a wider
601 <label> .expand/s <wid>, <symbol> ;
603 The .expand/s node takes an input symbol and sign-extends it to the
606 FORCE STATEMENTS (old method - remove me):
608 A force statement creates functors that represent a Verilog force
611 <label> .force <signal>, <symbol_list>;
613 The symbol <signal> represents the signal which is to be forced. The
614 <symbol_list> specifies the bits of the expression that is to be
615 forced on the <signal>. The <label> identifies the force functors.
616 There will be as many force functors as there are symbols in the
619 To activate and deactivate a force on a single bit, use:
621 %force <label>, <width>;
624 <label>/<width> is the label/width of a vector of force functors.
625 <signal> is the label of the functor that drives the signal that is
628 FORCE STATEMENTS (new method - implement me):
630 A %force instruction, as described in the .var section, forces a
631 constant value onto a .var or .net, and the matching %release releases
632 that value. However, there are times when the value of a functor
633 (i.e. another .net) needs to be forced onto a .var or .net. For this
634 task, the %force/link instruction exists:
636 %force/link <dst>, <src> ;
637 %release/link <dst> ;
639 This causes the output of the node <src> to be linked to the force
640 input of the <dst> .var/.net node. When linked, the output functor
641 will automatically drive values to the force port of the destination
642 node. The matching %release/link instruction removes the link (a
643 %release is still needed) to the destination. The %release/link
644 releases the last %force/link, no matter where the link is from. A new
645 %force/link will remove a previous link.
649 %cassign/link <dst>, <src> ;
650 %deassign/link <dst> ;
652 are the same concept, but for the continuous assign port.
654 STRUCTURAL ARITHMETIC STATEMENTS:
656 The various Verilog arithmetic operators (+-*/%) are available to
657 structural contexts as two-input functors that take in vectors. All of
658 these operators take two inputs and generate a fixed width output. The
659 input vectors will be padded if needed to get the desired output width.
661 <label> .arith/sub <wid>, <A>, <B>;
662 <label> .arith/sum <wid>, <A>, <B>;
663 <label> .arith/mult <wid>, <A>, <B>;
664 <label> .arith/div <wid>, <A>, <B>;
665 <label> .arith/mod <wid>, <A>, <B>;
667 In all cases, there are no width limits, so long as the width is
670 NOTE: The .arith/mult inputs are not necessarily the width of the
671 output. I have not decided how to handle this.
673 These devices support .s and .r suffixes. The .s means the node is a
674 signed vector device, the .r a real valued device.
676 STRUCTURAL COMPARE STATEMENTS:
678 The arithmetic statements handle various arithmetic operators that
679 have wide outputs, but the comparators have single bit output, so they
680 are implemented a bit differently. The syntax, however, is very
683 <label> .cmp/eeq <wid>, <A>, <B>;
684 <label> .cmp/nee <wid>, <A>, <B>;
685 <label> .cmp/eq <wid>, <A>, <B>;
686 <label> .cmp/ne <wid>, <A>, <B>;
687 <label> .cmp/ge <wid>, <A>, <B>;
688 <label> .cmp/gt <wid>, <A>, <B>;
689 <label> .cmp/ge.s <wid>, <A>, <B>;
690 <label> .cmp/gt.s <wid>, <A>, <B>;
692 Whereas the arithmetic statements generate an output the width of
693 <wid>, the comparisons produce a single bit vector result. The plain
694 versions do unsigned comparison, but the ".s" versions to signed
695 comparisons. (Equality doesn't need to care about sign.)
698 STRUCTURAL SHIFTER STATEMENTS:
700 Variable shifts in structural context are implemented with .shift
703 <label> .shift/l <wid>, <data symbol>, <shift symbol>;
704 <label> .shift/r <wid>, <data symbol>, <shift symbol>;
706 The shifter has a width that defines the vector width of the output, a
707 <data symbol> that is the input data to be shifted and a <shift-symbol>
708 that is the amount to shift. The vectors that come from port 0 are the
709 data to be shifted and must have exactly the width of the output. The
710 input to port 1 is the amount to shift.
713 STRUCTURAL FUNCTION CALLS:
715 The .ufunc statement defines a call to a user defined function.
717 <label> .ufunc <flabel>, <wid>, <isymbols> ( <psymbols> ) <rsymbol> ;
719 The <flabel> is the code label for the first instruction of the
720 function implementation. This is code that the simulator will branch
723 The <wid> is the width of the output vector in bits.
725 The <isymbols> is a list of net symbols for each of the inputs to the
726 function. These are points in the net, and the ufunc device watches
727 these nets for input changes.
729 The <psymbols> list is exactly the same size as the <isymbols>
730 list. The <psymbols> are variables that represent the input ports for
731 the function. The ufunc performs an assignment to these variables
732 before calling the function.
734 Finally, the <rsymbol> is the variable within the function where the
735 result will be found when the function code ends. This value is picked
736 up and propagated to the output of the functor.
740 Thread statements create the initial threads for a simulation. These
741 represent the initial and always blocks, and possibly other causes to
742 create threads at startup.
744 .thread <symbol> [, <flag>]
746 This statement creates a thread with a starting address at the
747 instruction given by <symbol>. When the simulation starts, a thread is
748 created for the .thread statement, and it starts at the <symbol>
749 addressed instruction.
751 The <flag> modifies the creation/execution behavior of the
752 thread. Supported flags are:
754 $push -- Cause the thread to be pushed in the scheduler. This
755 only effects startup (time 0) by arranging for pushed
756 threads to be started before non-pushed threads. This
757 is useful for resolving time-0 races.
761 Thread statements create the initial threads of a design. These
762 include the ``initial'' and ``always'' statements of the original
763 Verilog, and possibly some other synthetic threads for various
764 purposes. It is also possible to create transient threads from
765 behavioral code. These are needed to support such constructs as
766 fork/join, named blocks and task activation.
768 A transient thread is created with a %fork instruction. When a
769 transient thread is created this way, the operand to the %fork gives
770 the starting address, and the new thread is said to be a child of the
771 forking thread. The children of a thread are pushed onto a stack of
772 children. A thread can have only one direct child.
774 A transient thread is reaped with a %join instruction. %join waits for
775 the top thread in the stack of children to complete, then
776 continues. It is an error to %join when there are no children.
778 As you can see, the transient thread in VVP is a cross between a
779 conventional thread and a function call. In fact, there is no %call
780 instruction in vvp, the job is accomplished with %fork/%join in the
781 caller and %end in the callee. The %fork, then is simply a
782 generalization of a function call, where the caller does not
783 necessarily wait for the callee.
785 For all the behavior of threads and thread parentage to work
786 correctly, all %fork statements must have a corresponding %join in the
787 parent, and %end in the child. Without this proper matching, the
788 hierarchical relationships can get confused. The behavior of erroneous
793 The context of a thread is all the local data that only that thread
794 can address. The local data is broken into two addresses spaces: bit
795 memory and word memory.
797 The bit memory is a region of 4-value bits (0,1,x,z) that can be
798 addressed in strips of arbitrary length. For example, an 8-bit value
799 can be in locations 8 through and including 15. The bits at address 0,
800 1, 2 and 3 are special constant values. Reads from those locations
801 make vectors of 0, 1, x or z values, so these can be used to
802 manufacture complex values elsewhere.
804 The word memory is a region of tagged words. The value in each word
805 may be native long or real. These words have a distinct address space
810 The Verilog ``disable'' statement deserves some special mention
811 because of how it interacts with threads. In particular, threads
812 throughout the design can affect (end) other threads in the design
813 using the disable statement.
815 In Verilog, the operand to the disable statement is the name of a
816 scope. The behavior of the disable is to cause all threads executing
817 in the scope to end. Termination of a thread includes all the children
818 of the thread. In vvp, all threads are in a scope, so this is how the
819 disable gains access to the desired thread.
821 It is obvious how initial/always thread join a scope. They become part
822 of the scope simply by being declared after a .scope declaration. (See
823 vvp.txt for .scope declarations.) The .thread statement placed in the
824 assembly source after a .scope statement causes the thread to join the
827 Transient threads join a scope that is the operand to the %fork
828 instruction. The scope is referenced by name, and the thread created
829 by the fork atomically joins that scope. Once the transient thread
830 joins the scope, it stays there until it ends. Threads never change
831 scopes, not even transient threads.
835 The logic that a functor represents is expressed as a truth table. The
836 functor has four inputs and one output. Each input and output has one
837 of four possible values (0, 1, x and z) so two bits are needed to
838 represent them. So the input of the functor is 8 bits, and the output
839 2 bits. A complete lookup table for generating the 2-bit output from
840 an 8-bit input is 512 bits. That can be packed into 64 bytes. This is
841 small enough that the table should take less space then the code to
844 To implement the truth table, we need to assign 2-bit encodings for
845 the 4-value signals. I choose, pseudo-randomly, the following
853 The table is an array of 64 bytes, each byte holding 4 2-bit
854 outputs. Construct a 6-bit byte address with inputs 1, 2 and 3 like
858 The input 0 2-bits can then be used to select which of the 4 2-bit
859 pairs in the 8-bit byte are the output:
861 MSB -> zzxx1100 <- LSB
863 A complete truth table, then is described as 64 8-bit bytes.
865 The vvp engine includes truth tables for the primitive gate types, so
866 none needs to be given by the programmer. It is sufficient to name the
867 type to get that truth table.
870 EXECUTABLE INSTRUCTIONS
872 Threads run executable code, much like a processor executes machine
873 code. VVP has a variety of opcodes for executable instructions. All of
874 those instructions start with '%' and go into a single address
875 space. Labels attached to executable instructions get assigned the
876 address of the instruction, and can be the target of %jmp instructions
877 and starting points for threads.
879 The opcodes.txt file has a more detailed description of all the
880 various instructions.
883 THE RELATIONSHIP BETWEEN FUNCTORS, THREADS AND EVENTS
885 Given the above summary of the major components of vvp, some
886 description of their relationship is warranted. Functors provide a
887 structural description of the design (so far as it can be described
888 structurally) and these functors run independently of the threads. In
889 particular, when an input to a functor is set, it calculates a new
890 output value; and if that output is different from the existing
891 output, a propagation event is created. Functor output is calculated
892 by truth table lookup, without the aid of threads.
894 Propagation events are one of three kinds of events in vvp. They are
895 scheduled to execute at some time, and they simply point to the functor
896 that is to have its output propagated. When the event expires, the
897 output of the referenced functor is propagated to all the inputs that
898 it is connected to, and those functors in turn create new events if
901 Assignment events (the second of three types of events) are created
902 by non-blocking assignments in behavioral code. When the ``<='' is
903 executed (a %assign in vvp) an assign event is created, which includes
904 the vvp_ipoint_t pointer to the functor input to receive the value,
905 as well as the value. These are distinct from propagation events because:
907 a) There is no functor that has as its output the value to be
908 assigned (this is how values get into the functor net in
909 the first place), and
911 b) This allows for behavioral code to create waveforms of
912 arbitrary length that feed into a variable. Verilog allows
913 this of non-blocking assignments, but not of gate outputs.
915 The last type of event is the thread schedule event. This event simply
916 points to a thread to be executed. Threads are made up of a virtual
917 processor with a program counter and some private storage. Threads
918 can execute %assign instructions to create assignment events, and can
919 execute %set instructions to do blocking assignments. Threads can also
920 use %load to read the output of functors.
922 The core event scheduler takes these three kinds of events and calls
923 the right kind of code to cause things to happen in the design. If the
924 event is a propagate or assignment event, the network of functors is
925 tickled; if the event is a thread schedule, then a thread is run. The
926 implementation of the event queue is not important, but currently is
927 implemented as a ``skip list''. That is, it is a sorted singly linked
928 list with skip pointers that skip over delta-time events.
930 The functor net and the threads are distinct. They communicate through
931 thread instructions %set, %assign, %waitfor and %load. So far as a thread
932 is concerned, the functor net is a blob of structure that it pokes and
933 prods via certain functor access instructions.
936 VVP COMPILATION AND EXECUTION
938 The vvp program operates in a few steps:
941 Data structures are cleared to empty, and tables are
942 readied for compilation.
945 The input file is read and compiled. Symbol tables are
946 build up as needed, objects are allocated and linked
950 Symbol tables and other resources used only for
951 compilation are released to reduce the memory
955 Event simulation is run.
958 The initialization step is performed by the compile_init() function in
959 compile.cc. This function in turn calls all the *_init() functions in
960 other parts of the source that need initialization for compile. All
961 the various sub-init functions are called <foo>_init().
963 Compilation is controlled by the parser, it parse.y. As the parser
964 reads and parses input, the compilation proceeds in the rules by
965 calling various compile_* functions. All these functions live in the
966 compile.cc file. Compilation calls other sections of the code as
969 When the parser completes compilation, compile_cleanup() is called to
970 finish the compilation process. Unresolved references are completed,
971 then all the symbol tables and other compile-time-only resources are
972 released. Once compile_cleanup() returns, there is no more use for the
973 parser for the function in compile.cc.
975 After cleanup, the simulation is started. This is done by executing
976 the schedule_simulate() function. This does any final setup and starts
977 the simulation running and the event queue running.
980 HOW TO GET FROM THERE TO HERE
982 The vvp simulation engine is designed to be able to take as input a
983 compiled form of Verilog. That implies that there is a compiler that
984 compiles Verilog into a form that the vvp engine can read.
987 * Boolean logic gates
989 Gates like AND, OR and NAND are implemented simply and obviously by
990 functor statements. Any logic up to 4 inputs can be implemented with a
991 single functor. For example:
993 and gate (out, i1, i2, i3);
997 gate .functor and, i1, i2, i3;
999 Notice the first parameter of the .functor is the type. The type
1000 includes a truth table that describes the output with a given
1001 input. If the gate is wider then four inputs, then cascade
1002 functors. For example:
1004 and gate (out, i1, i2, i3, i4, i5, i6, i7, i8);
1008 gate.0 .functor and, i1, i2, i3, i4;
1009 gate.1 .functor and, i5, i6, i7, i8;
1010 gate .functor and, gate.0, gate.1;
1013 * reg and other variables
1015 Reg and integer are cases of what Verilog calls ``variables.''
1016 Variables are, simply put, things that behavioral code can assign
1017 to. These are not the same as ``nets,'' which include wires and the
1020 Each bit of a variable is created by a ``.var'' statement. For example:
1031 Events in general are implemented as functors, but named events in
1032 particular have no inputs and only the event output. The way to
1033 generate code for these is like so:
1037 This creates a functor and makes it into a mode-2 functor. Then the
1038 trigger statement, "-> a", cause a ``%set a, 0;'' statement be
1039 generated. This is sufficient to trigger the event.
1042 * Copyright (c) 2001 Stephen Williams (steve@icarus.com)
1044 * This source code is free software; you can redistribute it
1045 * and/or modify it in source code form under the terms of the GNU
1046 * General Public License as published by the Free Software
1047 * Foundation; either version 2 of the License, or (at your option)
1048 * any later version.
1050 * This program is distributed in the hope that it will be useful,
1051 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1052 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1053 * GNU General Public License for more details.
1055 * You should have received a copy of the GNU General Public License
1056 * along with this program; if not, write to the Free Software
1057 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA