C++ C Yacc Lex Other
Fetching latest commit…
Cannot retrieve the latest commit at this time.
THE ICARUS VERILOG COMPILATION SYSTEM September 18, 1999 1.0 What is ICARUS Verilog? Icarus Verilog is intended to compile ALL of the Verilog HDL as described in the IEEE-1364 standard. Of course, it's not quite there yet. It does currently handle a mix of structural and behavioral constructs. For a view of the current state of Icarus Verilog, see its home page at <http://www.icarus.com/eda/verilog>. IVL is not aimed at being a simulator in the traditional sense, but a compiler that generates code employed by back-end tools. These back- end tools currently include a simulator written in C++ called VVM and an XNF (Xilinx Netlist Format) generator. See "vvm.txt" and "xnf.txt" for further details on these back-end processors. In the future, backends are expected for EDIF/LPM, structural Verilog, etc. 2.0 Building/Installing IVL From Source If you are starting from source, the build process is designed to be as simple as practical. Someone basically familiar with the target system and C/C++ compilation should be able to build the source distribution with little effort. Some actual programming skills are not required, but helpful in case of problems. 2.1 Compile Time Prerequisites You need the following software to compile Icarus Verilog from source on a UNIX-like system: - GNU Make The Makefiles use some GNU extensions to, so a basic POSIX make will not work. Linux systems typically come with a satisfactory make. - ISO C++ Compiler The ivl program is written in C++ and makes use of templates and some of the standard C++ library. egcs compilers with the associated libstdc++ are known to work. - bison 2.2 Compilation Unpack the tar-ball and cd into the verilog-######### directory (presumably that is how you got to this README) and compile the source with the commands: ./configure make 2.3 Installation Now install the files in an appropriate place. (The makefiles by default install in /usr/local unless you specify a different prefix with the --prefix=<path> flag to the configure command.) Do this as root. make install 3.0 How IVL Works This tool includes a parser which reads in Verilog (plus extensions) and generates an internal netlist. The netlist is passed to various processing steps that transform the design to more optimal/practical forms, then is passed to a code generator for final output. The processing steps and the code generator are selected by command line switches. 3.1 Preprocessing There is a separate program, ivlpp, that does the preprocessing. This program implements the `include and `define directives producing output that is equivalent but without the directives. The output is a single file with line number directives, so that the actual compiler only sees a single input file. See ivlpp/ivlpp.txt for details. 3.2 Parse The verilog compiler starts by parsing the verilog source file. The output of the parse in a list of Module objects in PFORM. The pform (see pform.h) is mostly a direct reflection of the compilation step. There may be dangling references, and it is not yet clear which module is the root. One can see a human readable version of the final PFORM by using the ``-P <path>'' flag to the compiler. This will cause ivl to dump the PFORM into the file named <path>. 3.3 Elaboration This phase takes the pform and generates a netlist. The driver selects (by user request or lucky guess) the root module to elaborate, resolves references and expands the instantiations to form the design netlist. (See netlist.txt.) Final semantic checks are performed during elaboration, and some simple optimizations are performed. The elaborate() function performs the elaboration. One can see a human readable version of the final, elaborated and optimized netlist by using the ``-N <path>'' flag to the compiler. If elaboration succeeds, the final netlist (i.e. after optimizations but before code generation) will be dumped into the file named <path>. 3.4 Optimization This is actually a collection of processing steps that perform optimizations that do not depend on the target technology. Examples of some useful transformations would be, - eliminate null effect circuitry, - combinational reduction - Constant propagation The actual functions performed are specified on the command line by the -F flags (See below). 3.5 Code Generation This step takes the design netlist and uses it to drive the code generator. (See target.h.) This may require transforming the design to suit the technology. The emit() method of the Design class performs this step. It runs through the design elements, calling target functions as need arises to generate actual output. The target code generator to used is given by the -t flag on the command line. 4.0 Running Verilog The preferred way to invoke the compiler with the verilog(1) command. This program invokes the preprocessor (ivlpp) and the compiler (ivl) with the proper command line options to get the job done in a friendly way. See the verilog(1) man page for usage details. 4.1 Running IVL Directly The ivl command is the compiler driver, that invokes the parser, optimization functions and the code generator. Usage: ivl <options>... file ivl -h -F <name> Use this flag to request an optimization function be applied to the netlist before it is sent to the target output stage. Any number of -F options may be given, to specify a variety of processing steps. The steps will be applied in order, with the output of one uses as the input to the next. The function is specified by name. Use the "ivl -h" command to get a list of configured function names. -f <assign> Use this flag to set a parameter value. The format of the assignment is <key>=<value> where key is any string up to the first '=', and <value> is the rest of the option. If the '=' is omitted, then the key is assigned the empty string. The useful keys are defined by the functions and the target in use. These assignments are specifically useful for passing target specific information to the target back-end, or options/parameters to optimization functions, if any are defined. -m <module> Cause a named VPI module to be included in the module list. This parameter appends the named module to the end of the VPI_MODULE_LIST. This is an ordered list of modules to be loaded into the simulation at runtime. This list can also be set with -fVPI_MODULE_LIST=<list> which sets the list completely. Then, -m after this will append module names to the list sp specified. The default list includes "system". -N <file> Dump the elaborated netlist to the named file. The netlist is the folly elaborated netlist, after all the function modules are applied and right before the output generator is called. This is an aid for debugging the compiler, and the output generator in particular. -o <file> Normally, the generated result is sent to standard output. Use the -o flag to specify an output file for the generated result. -P <file> Write the PForm of the parsed input to the specified file. The pform is the compiler's understanding of the input after parsing and before elaboration. This is an aid for debugging the compiler. -s <module> Normally, ivl will elaborate the only module in the source file. If there are multiple modules, use this option to select the module to be used as the top-level module. -t <name> Select the output format for the compiled result. Use the "ivl -h" command to get a list of configured targets. -v Print version and copyright information for ivl. ATTRIBUTES The parser accepts as an extension to Verilog the $attribute module item. The syntax of the $attribute item is: $attribute (<identifier>, <key>, <value>); The $attribute keyword looks like a system task invocation. The difference here is that the parameters are more restricted then those of a system task. The <identifier> must be an identifier. This will be the item to get an attribute. The <key> and <value> are strings, not expressions, that give the key and the value of the attribute to be attached to the identified object. Attributes are [<key> <value>] pairs and are used to communicate with the various processing steps. See the documentation for the processing step for a list of the pertinent attributes. Attributes can also be applied to gate types. When this is done, the attribute is given to every instantiation of the primitive. The syntax for the attribute statement is the same, except that the <identifier> names a primitive earlier in the compilation unit and the statement is placed in global scope, instead of within a module. The semicolon is not part of a type attribute. Currently, type attributes are only supported for UDP types. Note that attributes are also occasionally used for communication between processing steps. Processing steps that are aware of others may place attributes on netlist objects to communicate information to later steps. 4.1 EXAMPLES Example: Compiling "hello.vl" ------------------------ hello.vl ---------------------------- module main(); initial begin $display("Hi there"); $finish ; end endmodule -------------------------------------------------------------- Insure that "verilog" is on your search path, and the vpi library is available. For csh - setenv PATH /usr/local/bin:$PATH setenv VPI_MODULE_PATH /usr/local/lib/ivl verilog hello.vl (The above presumes that /usr/local/include and /usr/local/lib are part of the compiler search path, which is usually the case for gcc.) To run the program ./hello 5.0 Unsupported Constructs IVL is in development - as such it still only supports a (growing) subset of verilog. Below is a description of some of the currently unsupported verilog features. This list is not exhaustive, and does not account for errors in the compiler. See the Icarus Verilog web page for the current state of support for Verilog. - Min/Typ/Max expressions: Example: a = (1 : 6 : 14); - `timescale directive - force/release/assign/deassign procedural assignments not supported. - block disable not supported, i.e.: begin : foo [...] disable foo; // sorry [...] end - fork/join is not supported in vvm runtime - Functions in structural contexts are not supported. assign foo = user_function(a,b); // sorry always @(a or b) foo = user_function(a,b); // OK - multiplicative operators (*, /, %) are not supported in general. They do work if the compiler can evaluate them at compile time. assign foo = a * b; // sorry always @(a or b) foo = a * b; // sorry - event data type is not supported. - real data type not supported. - system functions are not supported. (User defined functions are supported, and system tasks are supported.) assign foo = $some_function(a,b); // sorry always @(a or b) foo = $some_function(a,b); // sorry - non-constant delay expressions, i.e.: reg [7:0] del; always #(reg) $display($time,,"del = %d", del); // sorry - drive strengths are parsed, bug ignored. Specify blocks are parsed but ignored in general. 6.0 CREDITS Except where otherwise noted, ivl and ivlpp are Copyright Stephen Williams. The proper notices are in the head of each file. However, I have received aid in the form of fixes, Verilog guidance, and especially testing from many people, including (in alphabetical order): Eric Aardoom <email@example.com> Stephan I. Boettcher <firstname.lastname@example.org> Ed Carter <email@example.com> Larry Doolittle <LRDoolittle@lbl.gov> Guy Hutchison <firstname.lastname@example.org> Ales Hvezda <email@example.com> Yasuhisa Kato <firstname.lastname@example.org> James Lee <email@example.com> Peter Monta <firstname.lastname@example.org> Daniel H. Nelsen <email@example.com> Stefan Petersen <firstname.lastname@example.org> Jason Schonberg <email@example.com> Stuart Sutherland <firstname.lastname@example.org> Stephen Tell <email@example.com> Stefan Theide <Stefan.Thiede@sv.sc.philips.com> Steve Wilson <firstname.lastname@example.org> and others. Testers in particular include a larger community of people interested in a GPL Verilog for Linux. Special thanks to Steve Wilson for collecting and organizing the test suite code for all those testers.