====== VVP Simulation Engine ====== /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * * $Id: README.txt,v 1.74 2005/11/25 17:55:26 steve Exp $ */ VVP SIMULATION ENGINE The VVP simulator takes as input source code not unlike assembly language for a conventional processor. It is intended to be machine generated code emitted by other tools, including the Icarus Verilog compiler, so the syntax, though readable, is not necessarily convenient for humans. GENERAL FORMAT The source file is a collection of statements. Each statement may have a label, an opcode, and operands that depend on the opcode. For some opcodes, the label is optional (or meaningless) and for others it is required. Every statement is terminated by a semicolon. The semicolon is also the start of a comment line, so you can put comment text after the semicolon that terminates a statement. Like so: Label .functor and, 0x5a, x, y ; This is a comment. The semicolon is required, whether the comment is there or not. Statements may span multiple lines, as long as there is no text (other then the first character of a label) in the first column of the continuation line. HEADER SYNTAX Before any other non-commentary code starts, the source may contain some header statements. These are used for passing parameters or global details from the compiler to the vvp run-time. In all cases, the header statement starts with a left-justified keyword. * :module "name" ; This header statement names a vpi module that vvp should load before the rest of the program is compiled. The compiler looks in the standard VPI_MODULE_PATH for files named "name.vpi", and tries to dynamic load them. * :vpi_time_precision [+|-]; This header statement specifies the time precision of a single tick of the simulation clock. This is mostly used for display (and VPI) purposes, because the engine itself does not care about units. The compiler scales time values ahead of time. The value is the size of a simulation tick in seconds, and is expressed as a power of 10. For example, +0 is 1 second, and -9 is 1 nanosecond. If the record is left out, then the precision is taken to be +0. LABELS AND SYMBOLS Labels and symbols consist of the characters: a-z A-Z 0-9 .$_<> Labels and symbols may not start with a digit or a '.', so that they are easily distinguished from keywords and numbers. A Label is a symbol that starts a statement. If a label is present in a statement, it must start in the first text column. This is how the lexical analyzer distinguishes a label from a symbol. If a symbol is present in a statement, it is in the operand. Opcodes of statements must be a keyword. Symbols are references to labels. It is not necessary for a label to be declared before its use in a symbol, but it must be declared eventually. When symbols refer to functors, the symbol represents the vvp_ipoint_t pointer to the output. (Inputs cannot, and need not, be references symbolically.) If the functor is part of a vector, then the symbol is the vvp_ipoint_t for the first functor. The [] operator can then be used to reference a functor other then the first in the vector. There are some special symbols that in certain contexts have special meanings. As inputs to functors, the symbols "C<0>", "C<1>", "C" and "C" represent a constant driver of the given value. SCOPE STATEMENTS: PARAMETER STATEMENTS: Parameters are named constants within a scope. These parameters have a type and value, and also a label so that they can be referenced as VPI objects. The syntax of a parameter is:
;
, , , ; is an event functor that triggers a write, if the input is true. is the input that connect to the data input port. For asynchronous transparent write operation, connect to C4, the RAM will transparently follow any changes on address and data lines, while is true. There is no Verilog construct that calls for a structural write port to a memory, but synthesis may ask for lpm_ram_d[pq] objects. To initialize a memory, use: .mem/init , val , val ... ; is the label of the memory, and the is the start address (canonical) of the first word to be initialized. The start address allows multiple statements be used to initialize words of a memory. The values are one per word. Procedural access to the memory employs an index register to address a bit location in the memory, via the commands: %load/m , ; %set/m , ; %assign/m , , ; The memory bit is addressed by index register 3. The value of register 3 is the index in the memory's bit space, where each data word occupies a multiple of four bits. EVENT STATEMENTS Threads need to interact with the functors of a netlist synchronously, as well as asynchronously. There are cases where the web of functors needs to wake up a waiting thread. The web of functors signals threads through .event objects, that are declared like so: