diff --git a/Documentation/targets/index.rst b/Documentation/targets/index.rst index 6e8bbbe4fa..9664de14e6 100644 --- a/Documentation/targets/index.rst +++ b/Documentation/targets/index.rst @@ -13,4 +13,6 @@ Icarus Verilog. The code generator is selected by the "-t" command line flag. vvp stub null - + vhdl + verilog95 + pcb diff --git a/Documentation/targets/pcb.rst b/Documentation/targets/pcb.rst new file mode 100644 index 0000000000..68c886bbff --- /dev/null +++ b/Documentation/targets/pcb.rst @@ -0,0 +1,61 @@ + +Using the PCB code generator +============================ + +The PCB target code generator is designed to allow a user to enter a netlist +in Verilog format, then generate input files for the GNU PCB layout program. + +Invocation +---------- + +The PCB target code generation is invoked with the -tpcb flag to the iverilog +command. The default output file, "a.out", contains the generated .PCB +file. Use the "-o" flag to set the output file name explicitly. The default +output file contains only the elements. To generate a "netlist" file, add the +flag "-pnetlist=" command line flag. + +Altogether, this example generates the foo.net and foo.pcb files from the +foo.v source file:: + + % iverilog -tpcb -ofoo.pcb -pnetlist=foo.net foo.v + +Flags +----- + +* -o + + Set the output (pcb) file path + +* -pnetlist=path + + Write a netlist file to the given path. + +Attributes Summary +------------------ + +Attributes are attached to various constructs using the Verilog "(* *)" +attribute syntax. + +* ivl_black_box + + Attached to a module declaration or module instantiation, this indicates + that the module is a black box. The code generator will create an element + for black box instances. + +Parameters Summary +------------------ + +Within modules, The PCB code generator uses certain parameters to control +details. Parameters may have defaults, and can be overridden using the usual +Verilog parameter override syntax. Parameters have preferred types. + +* description (string, default="") + + The "description" is a text string that describes the black box. This string + is written into the description field of the PCB Element. + +* value (string, default="") + + The "value" is a text tring that describes some value for the black + box. Like the description, the code generator does not interpret this value, + other then to write it to the appropriate field in the PCB Element." diff --git a/Documentation/targets/verilog95.rst b/Documentation/targets/verilog95.rst new file mode 100644 index 0000000000..5312229ce6 --- /dev/null +++ b/Documentation/targets/verilog95.rst @@ -0,0 +1,101 @@ + +Using The Verilog '95 Code Generator +==================================== + +Icarus Verilog contains a code generator to emit 1995 compliant Verilog from +the input Verilog netlist. This allows Icarus Verilog to function as a Verilog +> 1995 to Verilog 1995 translator. The main goal of the project was to convert +@*, ANSI style arguments and other constructs to something allowed in 1995 +Verilog. + +Invocation +---------- + +To translate a Verilog program to 1995 compliant Verilog, invoke "iverilog" +with the -tvlog95 flag:: + + % iverilog -tvlog95 -o my_design_95.v my_design.v + +The generated Verilog will be placed in a single file (a.out by default), even +if the input Verilog is spread over multiple files. + +Generator Flags +--------------- + +* -pspacing=N + + Set the indent spacing (the default is 2). + +* -pallowsigned=1 + + Allow emitting the various signed constructs as an extension to 1995 Verilog + (off by default). + +* -pfileline=1 + + Emit the original file and line information as a comment for each generated + line (off by default). + +Structures that cannot be converted to 1995 compatible Verilog +-------------------------------------------------------------- + +The following Verilog constructs are not translatable to 1995 compatible Verilog: + +* Automatic tasks or functions. + +* The power operator (**). Expressions of the form (2**N)** (where N + is a constant) can be converter to a shift. + +* Some System Verilog constructs (e.g. final blocks, ++/-- operators, + etc.). 2-state variables are converted to 4-state variables. + +Icarus extensions that cannot be translated: + +* Integer constants greater than 32 bits. + +* Real valued nets. + +* Real modulus. + +* Most Verilog-A constructs. + + +Known Issues and Limitations +---------------------------- + +Some things are just not finished and should generate an appropriate +warning. Here is a list of the major things that still need to be looked at. + +* There are still a few module instantiation port issues (pr1723367 and + partselsynth). + +* inout ports are not converted (tran-VP). + +* Variable selects of a non-zero based vector in a continuous assignment are + not converted. + +* There is no support for translating a zero repeat in a continuous + assignment. It is currently just dropped. + +* A pull device connected to a signal select is not translated correctly (this + may be fixed). + +* L-value indexed part selects with a constant undefined base in a continuous + assignment are not translated. + +* Logic gates are not arrayed exactly the same as the input and the instance + name is not always the same. + +* The signed support does not generate $signed() or $unsigned() function calls + in a continuous assignment expression. + +* The special power operator cases are not converted in a continuous + assignment. + +* Currently a signed constant that sets the MSB in an unsigned context will be + displayed as a negative value (e.g. bit = 1 translates to bit = -1). + +* Can net arrays, etc. be unrolled? + +* Can generate blocks be converted? + diff --git a/Documentation/targets/vhdl.rst b/Documentation/targets/vhdl.rst new file mode 100644 index 0000000000..d9a095c0ca --- /dev/null +++ b/Documentation/targets/vhdl.rst @@ -0,0 +1,82 @@ + +The VHDL Code Generator (-tvhdl) +================================ + +Icarus Verilog contains a code generator to emit VHDL from the Verilog +netlist. This allows Icarus Verilog to function as a Verilog to VHDL +translator. + +Invocation +---------- + +To translate a Verilog program to VHDL, invoke "iverilog" with the -tvhdl +flag:: + + % iverilog -t vhdl -o my_design.vhd my_design.v + +The generated VHDL will be placed in a single file (a.out by default), even if +the Verilog is spread over multiple files. + +Flags +----- + +* -pdebug=1 + + Print progress messages as the code generator visits each part of the + design. + +* -pdepth=N + + Only output VHDL entities for modules found at depth < N in the + hierarchy. N=0, the default, outputs all entities. For example, -pdepth=1 + outputs only the top-level entity. + +Supported Constructs +-------------------- + +TODO + +Limitations +----------- + +Signal Values and Resolution +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are several cases where the behaviour of the translated VHDL deviates +from the source Verilog: + +* The result of division by zero is x in Verilog but raises an exception in + VHDL. + +* Similarly, the result of reading past the end of an array in Verilog is x, + whereas VHDL raises an exception. + +* Any signal that is driven by two or more processes will have the value + 'U'. This is the result of the signal resolution function in the + std_logic_1164 package. + +Constructs Not Supported +^^^^^^^^^^^^^^^^^^^^^^^^ + +The following Verilog constructs cannot be translated to VHDL: + +* fork and join + +* force and release + +* disable + +* real-valued variables + +* switches + +* hierarchical dereferencing + +Other Limitations +^^^^^^^^^^^^^^^^^ + +* The test expressions in case statements must be constant. + +* Translation of a parameter to a corresponding VHDL generic + declaration. Instead the default parameter value is used. + diff --git a/Documentation/usage/command_files.rst b/Documentation/usage/command_files.rst new file mode 100644 index 0000000000..c48cf12861 --- /dev/null +++ b/Documentation/usage/command_files.rst @@ -0,0 +1,198 @@ + +Command File Format +=================== + +The basic format of a command file is one source file or compiler argument per +line. Command files may also have comments of various form, and options for +controlling the compiler. + +Comments +-------- + +Lines that start with a "#" character are comments. All text after the "#" +character, is ignored. + +The "//" character sequence also starts a comment that continues to the end of +the line. + +The "/\*" and "\*/" character sequences surround multi-line comments. All the +text between the comment start and comment end sequences is ignored, even when +that text spans multiple lines. This style of comment does not nest, so a "/\*" +sequence within a multi-line comment is probably an error. + +Plus-args +--------- + +Outside of comments, lines that start with a "+" character are compiler +arguments. These are called plusargs but they are not the same as extended +arguments passed to the "vvp" command. The supported plusargs are definitively +listed in the iverilog manual page. + +The plusargs lines are generally "++..." where the name is the name of +an switch, and the arguments are separated by "+" characters, as in:: + + +libext+.v+.V+.ver + +With plusargs lines, the "+" character separates tokens, and not white space, +so arguments, which may include file paths, may include spaces. A plusarg line +is terminated by the line end. + +The line in the command file may also be a "-y" argument. This works exactly +the same as the:: + + -y + +argument to the compiler; it declares a library directory. The "-y" syntax is +also a shorthand for the "+libdir" plusarg, which is a more general form:: + + +libdir+... + +File Names +---------- + +Any lines that are not comments, compiler arguments or plusargs are taken by +the compiler to be a source file. The path can contain any characters (other +then comment sequences) including blanks, although leading and trailing white +space characters are stripped. The restriction of one file name per line is in +support of operating systems that can name files any which way. It is not +appropriate to expect white spaces to separate file names. + +Variable Substitution +--------------------- + +The syntax "$(name)" is a variable reference, and may be used anywhere within +filenames or directory names. The contents of the variable are read from the +environment and substituted in place of the variable reference. In Windows, +these environment variables are the very same variables that are set through +the Control Panel->System dialog box, and in UNIX these variables are +environment variables as exported by your shell. + +Variables are useful for giving command files some installation +independence. For example, one can import a vendor library with the line:: + + -y $(VENDOR)/verilog/library + +in the command file, and the next programmer will be able to use this command +file without editing it to point to the location of VENDOR on his +machine. Note the use of forward slashes as a directory separator. This works +even under Windows, so always use forward slashes in file paths and Windows +and UNIX users will be able to share command files. + +An Example +---------- + +This sample:: + + # This is a comment in a command file. + # The -y statement declares a library + # search directory + -y $(PROJ_LIBRARY)/prims + # + # This plusarg tells the compiler that + # files in libraries may have .v or .vl + # extensions. + +libext+.v+.vl + # + main.v // This is a source file + # + # This is a file name with blanks. + C:/Project Directory/file name.vl + +is a command file that demonstrates the major syntactic elements of command +files. It demonstrates the use of comments, variables, plusargs and file +names. It contains a lot of information about the hypothetical project, and +suggests that command files can be used to describe the project as a whole +fairly concisely. + +The syntax of command files is rich enough that they can be used to document +and control the assembly and compilation of large Verilog programs. It is not +unusual to have command files that are hundreds of lines long, although +judicious use of libraries can lead to very short command files even for large +designs. It is also practical to have different command files that pull +together combinations of sources and compiler arguments to make different +designs from the same Verilog source files. + +Summary +------- + +Given the above description of the command file format, the following is a +list of the special records with their meaning. + +* +libdir+*dir-path* + + Specify directories to be searched for library modules. The *dir-path* can + have multiple directories, separated by "+" characters. + +* +libdir-nocase+dir-path + + This is the same as "+libdir+", but when searching "nocase" libraries for + module files, case will not be taken as significant. This is useful when the + library is on a case insensitive file system. + +* +libext+*suffix-string* + + Declare the suffix strings to use when searching library directories for + Verilog files. The compiler may test a list of suffix strings to support a + variety of naming conventions. + +* -y dir-path + + This is like "+libdir+" but each line takes only one path. Like "+libdir+" + there can be multiple "-y" records to declare multiple library + directories. This is similar to the "-y" flag on the iverilog command line. + +* -v *file-name* or -l *file-name* + + This declares a library file. A library file is just like any other Verilog + source file, except that modules declared within it are not implicitly + possible root modules. + + NOTE: The "-l" alias is new as of 2 October 2016. It will become available + in releases and snapshots made after that date. + +* +incdir+*include-dir-path* + + Declare a directory or list of directories to search for files included by + the "include" compiler directive. The directories are searched in + order. This is similar to the "-I" flag on the iverilog command line. + +* +define+*name=value* + + Define the preprocessor symbol "name" to have the string value "value". If + the value (and the "=") are omitted, then it is assumed to be the string + "1". This is similar to the "-D" on the iverilog command line. + +* +timescale+*units/precision* + + Define the default timescale. This is the timescale that is used if there is + no other timescale directive in the Verilog source. The compiler default + default is "+timescale+1s/1s", which this command file setting can + change. The format of the units/precision is the same as that for the + timescale directive in the verilog source. + +* +toupper-filename + + This token causes file names after this in the command file to be translated + to uppercase. this helps with situations where a directory has passed + through a DOS machine (or a FAT file system) and in the process the file + names become munged. This is not meant to be used in general, but only in + emergencies. + +* +tolower-filename + + The is the lowercase version of "+toupper-filename". + +* +parameter+*name=value* + + This token causes the compiler to override a parameter value for a top-level + module. For example, if the module main has the parameter WIDTH, set the + width like this "+parameter+main.WIDTH=5". Note the use of the complete + hierarchical name. This currently only works for parameters defined in root + (top level) modules and a defparam may override the command file value. + +* +vhdl-work+*path* + + When compiling VHDL, this token allows control over the directory to use for + holding working package declarations. For example, "+vhdl-work+workdir" will + cause the directory "workdir" to be used as a directory for holding working + working copies of package headers. diff --git a/Documentation/usage/index.rst b/Documentation/usage/index.rst index e4292bc73c..cd6eabc55d 100644 --- a/Documentation/usage/index.rst +++ b/Documentation/usage/index.rst @@ -8,7 +8,12 @@ Icarus Verilog. .. toctree:: :maxdepth: 1 + installation getting_started + simulation command_line_flags + command_files verilog_attributes vvp_flags + vpi + ivl_target diff --git a/Documentation/usage/installation.rst b/Documentation/usage/installation.rst new file mode 100644 index 0000000000..859c87321f --- /dev/null +++ b/Documentation/usage/installation.rst @@ -0,0 +1,146 @@ + +Installation Guide +================== + +Icarus Verilog may be installed from source code, or from pre-packaged binary +distributions. If you don't have need for the very latest, and prepackaged +binaries are available, that would be the best place to start. + +Installation From Source +------------------------ + +Icarus is developed for Unix-like environments but can also be compiled on +Windows systems using the Cygwin environment or MinGW compilers. The following +instructions are the common steps for obtaining the Icarus Verilog source, +compiling and installing. Note that there are precompiled and/or prepackaged +versions for a variety of systems, so if you find an appropriate packaged +version, then that is the easiest way to install. + +The source code for Icarus is stored under the git source code control +system. You can use git to get the latest development head or the latest of a +specific branch. Stable releases are placed on branches, and in particular v11 +stable releases are on the branch "v11-branch" To get the development version +of the code follow these steps:: + + % git config --global user.name "Your Name Goes Here" + % git config --global user.email you@yourpublicemail.example.com + % git clone https://github.com/steveicarus/iverilog.git + +The first two lines are optional and are used to tell git who you are. This +information is important if/when you submit a patch. We suggest that you add +this information now so you don't forget to do it later. The clone will create +a directory, named iverilog, containing the source tree, and will populate +that directory with the most current source from the HEAD of the repository. + +Change into this directory using:: + + % cd iverilog + +Normally, this is enough as you are now pointing at the most current +development code, and you have implicitly created a branch "master" that +tracks the development head. However, If you want to actually be working on +the v11-branch (the branch where the latest v11 patches are) then you checkout +that branch with the command:: + + % git checkout --track -b v11-branch origin/v11-branch + +This creates a local branch that tracks the v11-branch in the repository, and +switches you over to your new v11-branch. The tracking is important as it +causes pulls from the repository to re-merge your local branch with the remote +v11-branch. You always work on a local branch, then merge only when you +push/pull from the remote repository. + +Now that you've cloned the repository and optionally selected the branch you +want to work on, your local source tree may later be synced up with the +development source by using the git command:: + + % git pull + +The git system remembers the repository that it was cloned from, so you don't +need to re-enter it when you pull. + +Finally, configuration files are built by the extra step:: + + % sh autoconf.sh + +The source is then compiled as appropriate for your system. See the specific +build instructions below for your operation system for what to do next. + +You will need autoconf and gperf installed in order for the script to work. +If you get errors such as:: + + Autoconf in root... + autoconf.sh: 10: autoconf: not found + Precompiling lexor_keyword.gperf + autoconf.sh: 13: gperf: not found. + +You will need to install download and install the autoconf and gperf tools. + +Icarus Specific Configuration Options +------------------------------------- + +Icarus takes many of the standard configuration options and those will not be +described here. The following are specific to Icarus:: + + --enable-suffix[=suffix] + +This option allows the user to build Icarus with a default suffix or when +provided a user defined suffix. Older stable releases have this flag on by +default e.g.(V0.8 by default will build with a "-0.8" suffix). All versions +have an appropriate default suffix ("-"). + +All programs or directories are tagged with this suffix. e.g.(iverilog-0.8, +vvp-0.8, etc.). The output of iverilog will reference the correct run time +files and directories. The run time will check that it is running a file with +a compatible version e.g.(you can not run a V0.9 file with the V0.8 run +time). :: + + --with-valgrind + +This option adds extra memory cleanup code and pool management code to allow +better memory leak checking when valgrind is available. This option is not +need when checking for basic errors with valgrind. + +Compiling on Linux/Unix +----------------------- + +(Note: You will need to install bison, flex, g++ and gcc) This is probably the +easiest case. Given that you have the source tree from the above instructions, +the compile and install is generally as simple as:: + + % ./configure + % make + (su to root) + # make install + +The "make install" typically needs to be done as root so that it can install +in directories such as "/usr/local/bin" etc. You can change where you want to +install by passing a prefix to the "configure" command:: + + % ./configure --prefix=/my/special/directory + +This will configure the source for eventual installation in the directory that +you specify. Note that "rpm" packages of binaries for Linux are typically +configured with "--prefix=/usr" per the Linux File System Standard. + +Make sure you have the latest version of flex otherwise you will get an error +when parsing lexor.lex. + +Compiling on Macintosh OS X +--------------------------- + +Since Mac OS X is a BSD flavor of Unix, you can install Icarus Verilog from +source using the procedure described above. You need to install the Xcode +software, which includes the C and C++ compilers for Mac OS X. The package is +available for free download from Apple's developer site. Once Xcode is +installed, you can build Icarus Verilog in a terminal window just like any +other Unix install. + +For versions newer than 10.3 the GNU Bison tool (packaged with Xcode) needs to +be updated to version 3. :: + + brew install bison + echo 'export PATH="/usr/local/opt/bison/bin:$PATH"' >> ~/.bash_profile + +Icarus Verilog is also available through the Homebrew package manager: "brew +install icarus-verilog". diff --git a/Documentation/usage/ivl_target.rst b/Documentation/usage/ivl_target.rst new file mode 100644 index 0000000000..192e00e9b9 --- /dev/null +++ b/Documentation/usage/ivl_target.rst @@ -0,0 +1,106 @@ + +Loadable Target API (ivl_target.h) +================================== + +In addition to the standard VPI API, Icarus Verilog supports a non-standard +loadable target module API. This API helps C programmers write modules that +Icarus Verilog can use to generate code. These modules are used at compile +time to write the elaborated design to the simulation or netlist files. For +example, the vvp code generator is a loadable target module that writes vvp +code into the specified file. + +Loadable target modules gain access to the 'elaborated' design. That means, +the source files have been checked for syntax and correctness, any synthesis +and general optimization steps have been performed, and what is left is a +design that reflects but is not exactly the same as the input Verilog source +code. This relieves the modules of the burden of supporting all the odd +corners and complexities of the Verilog language. + +The Target Module API +--------------------- + +The API is defined in the header file "ivl_target.h" which is installed with +Icarus Verilog. The header defines the functions that the module writer can +use to get at the elaborated design during the course of writing the output +format. + +The target module API function "target_design" is special in that the API does +not provide this function: The target module itself provides it. When the +compiler loads the target module, it invokes the "target_design" function with +a handle to the design. This is the point where the target module takes over +to process the design. + +Compiling Target Modules +------------------------ + +Compiling loadable target modules is similar to compiling VPI modules, in that +the module must be compiled with the "-fPIC" flag to gcc, and linked with the +"-shared" flag. The module that you compile is then installed in a place where +the "iverilog" command can find it, and configuration files are adjusted to +account for the new module. + +This code:: + + # include + + int target_design(ivl_design_t des) + { + return 0; + } + +is an example module that we can write into the file "empty.c"; and let us +compile it into the module file "empty.tgt" like so:: + + % gcc -o empty.tgt -fpic -shared empty.c + +This makes the "empty.tgt" file an a dynamically loaded shared object. + +Creating the Target Config File +------------------------------- + +The target config file tells the Icarus Verilog core how to process your new +code generator. The ivl core expects two configuration files: the name.conf +and the name-s.config files. The "-s" version is what is used if the user +gives the "-S" (synthesis) flag on the command line. + +The stub target, included in most distributions, demonstrates the config +files. The "stub.conf" file is:: + + functor:cprop + functor:nodangle + -t:dll + flag:DLL=stub.tgt + +and the "stub-s.conf" file is:: + + functor:synth2 + functor:synth + functor:syn-rules + functor:cprop + functor:nodangle + -t:dll + flag:DLL=stub.tgt + +Note that the "stub-s.conf" file contains more lines to invoke internal +synthesis functions, whereas the "stub.conf" invokes only the basic +optimization steps. + +In general, only the last line (The "flag:DLL=.tgt" record) varies for +each target. For your target, replace the with the name of your target +and you have a configuration file ready to install. Note that this is the name +of your target module. This is in fact how the config file tells the compiler +the name of your module. + +The rest of the config file is best taken as boiler plate and installed as is, +with one difference. If your target is a synthesis target (for example a mosis +code generator or a pld code generator) that expects synthesis to happen, then +it makes the most sense to create both your config file like the "stub-s.conf" +config file. This causes the compiler to do synthesis for your target whether +the user gives the "-S" flag or not. + +Installing the Target Module +---------------------------- + +Finally, the "empty.conf", the "empty-s.conf" and the "empty.tgt" files need +to be installed. Where they go depends on your system, but in Linux they are +normally installed in "/usr/lib/ivl". diff --git a/Documentation/usage/simulation.rst b/Documentation/usage/simulation.rst new file mode 100644 index 0000000000..35685f1e30 --- /dev/null +++ b/Documentation/usage/simulation.rst @@ -0,0 +1,487 @@ + +Simulation Using Icarus Verilog +=============================== + +Simulation is the process of creating models that mimic the behavior of the +device you are designing (simulation models) and creating models to exercise +the device (test benches). The simulation model need not reflect any +understanding of the underlying technology, and the simulator need not know +that the design is intended for any specific technology. + +The Verilog simulator, in fact, is usually a different program than the +synthesizer. It may even come from a different vendor. The simulator need not +know of or generate netlists for the target technology, so it is possible to +write one simulator that can be used to model designs intended for a wide +variety of technologies. A synthesizer, on the other hand, does need to know a +great deal about the target technology in order to generate efficient +netlists. Synthesizers are often technology specific and come from vendors +with specialized knowledge, whereas simulators are more general purpose. + +Simulation models and test benches, therefore, can use the full range of +Verilog features to model the intended design as clearly as possible. This is +the time to test the algorithms of the design using language that is +relatively easy for humans to read. The simulator, along with the test bench, +can test that the clearly written model really does behave as intended, and +that the intended behavior really does meet expectations. + +The test benches model the world outside the design, so they are rarely +destined for real hardware. They are written in Verilog simply as a matter of +convenience, and sometimes they are not written in Verilog at all. The test +benches are not throw-away code either, as they are used to retest the device +under test as it is transformed from a simulation model to a synthesizeable +description. + +Compilation and Elaboration +--------------------------- + +Simulation of a design amounts to compiling and executing a program. The +Verilog source that represents the simulation model and the test bench is +compiled into an executable form and executed by a simulation +engine. Internally, Icarus Verilog divides the compilation of program source +to an executable form into several steps, and basic understanding of these +steps helps understand the nature of failures and errors. The first step is +macro preprocessing, then compilation, elaboration, optional optimizations and +finally code generation. The boundary between these steps is often blurred, +but this progression remains a useful model of the compilation process. + +The macro preprocessing step performs textual substitutions of macros defined +with "\`define" statements, textual inclusion with "\`include" statements, and +conditional compilation by "\`ifdef" and "\`ifndef" statements. The +macropreprocessor for Icarus Verilog is internally a separate program that can +be accessed independently by using the "-E" flag to the "iverilog" command, +like so:: + + % iverilog -E -o out.v example.v + +This command causes the input Verilog file "example.v" to be preprocessed, and +the output, a Verilog file without preprocessor statements, written into +"out.v". The "\`include" and "\`ifdef" directives in the input file are interpreted, +and defined macros substituted, so that the output, a single file, is the same +Verilog but with the preprocessor directives gone. All the explicitly +specified source files are also combined by the preprocessor, so that the +preprocessed result is a single Verilog stream. + +Normally, however, the "-E" flag is not used and the preprocessed Verilog is +instead sent directly to the next step, the compiler. The compiler core takes +as input preprocessed Verilog and generates an internal parsed form. The +parsed form is an internal representation of the Verilog source, in a format +convenient for further processing, and is not accessible to the user. + +The next step, elaboration, takes the parsed form, chooses the root modules, +and instantiates (makes *instances* of) those roots. The root instances may +contain instances of other modules, which may in turn contain instances of yet +other modules. The elaboration process creates a hierarchy of module instances +that ends with primitive gates and statements. + +Note that there is a difference between a module and a module instance. A +module is a type. It is a description of the contents of module instances that +have its type. When a module is instantiated within another module, the module +name identifies the type of the instance, and the instance name identifies the +specific instance of the module. There can be many instances of any given +module. + +Root modules are a special case, in that the programmer does not give them +instance names. Instead, the instance names of root modules are the same as +the name of the module. This is valid because, due to the nature of the +Verilog syntax, a module can be a root module only once, so the module name +itself is a safe instance name. + +Elaboration creates a hierarchy of scopes. Each module instance creates a new +scope within its parent module, with each root module starting a +hierarchy. Every module instance in the elaborated program has a unique scope +path, a hierarchical name, that starts with its root scope and ends with its +own instance name. Every named object, including variables, parameters, nets +and gates, also has a hierarchical name that starts with a root scope and ends +with its own base name. The compiler uses hierarchical names in error messages +generated during or after elaboration, so that erroneous items can be +completely identified. These hierarchical names are also used by waveform +viewers that display waveform output from simulations. + +The elaboration process creates from the parsed form the scope hierarchy +including the primitive objects within each scope. The elaborated design then +is optimized to reduce it to a more optimal, but equivalent design. The +optimization step takes the fully elaborated design and transforms it to an +equivalent design that is smaller or more efficient. These optimizations are, +for example, forms of constant propagation and dead code elimination. Useless +logic is eliminated, and constant expressions are pre-calculated. The +resulting design behaves as if the optimizations were not performed, but is +smaller and more efficient. The elimination (and spontaneous creation) of +gates and statements only affects the programmer when writing VPI modules, +which through the API have limited access to the structures of the design. + +Finally, the optimized design, which is still in an internal form not +accessible to users, is passed to a code generator that writes the design into +an executable form. For simulation, the code generator is selected to generate +the vvp format--a text format that can be executed by the simulation +engine. Other code generators may be selected by the Icarus Verilog user, even +third party code generators, but the vvp code generator is the default for +simulation purposes. + +Making and Using Libraries +-------------------------- + +Although simple programs may be written into a single source file, this gets +inconvenient as the designs get larger. Also, writing the entire program into +a single file makes it difficult for different programs to share common +code. It therefore makes sense to divide large programs into several source +files, and to put generally useful source code files somewhere accessible to +multiple designs. + +Once the program is divided into many files, the compiler needs to be told how +to find the files of the program. The simplest way to do that is to list the +source files on the command line or in a command file. This is for example the +best way to divide up and integrate test bench code with the simulation model +of the device under test. + +The Macro Preprocessor +^^^^^^^^^^^^^^^^^^^^^^ + +Another technique is to use the macro preprocessor to include library files +into a main file. The `include` directive takes the name of a source file to +include. The preprocessor inserts the entire contents of the included file in +place of the `include` directive. The preprocessor normally looks in the +current working directory (the current working directory of the running +compiler, and not the directory where the source file is located) for the +included file, but the "-I" switch to "iverilog" can add directories to the +search locations list. :: + + % iverilog -I/directory/to/search example.v + +It is common to create include directories shared by a set of programs. The +preprocessor `include` directive can be used by the individual programs to +include the source files that it needs. + +The preprocessor method of placing source code into libraries is general +(arbitrary source code can be placed in the included files) but is static, in +the sense that the programmer must explicitly include the desired library +files. The automatic module library is a bit more constrained, but is +automatic. + +Automatic Module Libraries +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A common use for libraries is to store module definitions that may be of use +to a variety of programs. If modules are divided into a single module per +file, and the files are named appropriately, and the compiler is told where to +look, then the compiler can automatically locate library files when it finds +that a module definition is missing. + +For this to work properly, the library files must be Verilog source, they +should contain a single module definition, and the files must be named after +the module they contain. For example, if the module "AND2" is a module in the +library, then it belongs in a file called "AND2.v" and that file contains only +the "AND2" module. A library, then, is a directory that contains properly +named and formatted source files. :: + + % iverilog -y/library/to/search example.v + +The "-y" flag to "iverilog" tells the compiler to look in the specified +directory for library modules whenever the program instantiates a module that +is not otherwise defined. The programmer may include several "-y" flags on the +command line (or in a command file) and the compiler will search each +directory in order until an appropriate library file is found to resolve the +module. + +Once a module is defined, either in the program or by reading a library +module, the loaded definition is used from then on within the program. If the +module is defined within a program file or within an included file, then the +included definition is used instead of any library definition. If a module is +defined in multiple libraries, then the first definition that the compiler +finds is used, and later definitions are never read. + +Icarus Verilog accesses automatic libraries during elaboration, after it has +already preprocessed and parsed the non-library source files. Modules in +libraries are not candidates for root modules, and are not even parsed unless +they are instantiated in other source files. However, a library module may +reference other library modules, and reading in a library module causes it to +be parsed and elaborated, and further library references resolved, just like a +non-library module. The library lookup and resolution process iterates until +all referenced modules are resolved, or known to be missing from the +libraries. + +The automatic module library technique is useful for including vendor or +technology libraries into a program. Many EDA vendors offer module libraries +that are formatted appropriately; and with this technique, Icarus Verilog can +use them for simulation. + +Advanced Command Files +---------------------- + +Command files were mentioned in the "Getting Started" chapter, but only +briefly. In practice, Verilog programs quickly grow far beyond the usefulness +of simple command line options, and even the macro preprocessor lacks the +flexibility to combine source and library modules according to the advancing +development process. + +The main contents of a command file is a list of Verilog source files. You can +name in a command file all the source files that make up your design. This is +a convenient way to collect together all the files that make up your +design. Compiling the design can then be reduced to a simple command line like +the following:: + + % iverilog -c example.cf + +The command file describes a configuration. That is, it lists the specific +files that make up your design. It is reasonable, during the course of +development, to have a set of different but similar variations of your +design. These variations may have different source files but also many common +source files. A command file can be written for each variation, and each +command file lists the source file names used by each variation. + +A configuration may also specify the use of libraries. For example, different +configurations may be implementations for different technologies so may use +different parts libraries. To make this work, command files may include "-y" +statements. These work in command files exactly how they work on "iverilog" +command line. Each "-y" flag is followed by a directory name, and the +directories are searched for library modules in the order that they are listed +in the command file. + +The include search path can also be specified in configuration files with +"+incdir+" tokens. These tokens start with the "+incdir+" string, then +continue with directory paths, separated from each other with "+" characters +(not spaces) for the length of the line. + +Other information can be included in the command file. See the section Command +File Format for complete details on what can go in a command file. + +Input Data at Runtime +--------------------- + +Often, it is useful to compile a program into an executable simulation, then +run the simulation with various inputs. This requires some means to pass data +and arguments to the compiled program each time it is executed. For example, +if the design models a micro-controller, one would like to run the compiled +simulation against a variety of different ROM images. + +There are a variety of ways for a Verilog program to get data from the outside +world into the program at run time. Arguments can be entered on the command +line, and larger amounts of data can be read from files. The simplest method +is to take arguments from the command line. + +Consider this running example of a square root calculator:: + + module sqrt32(clk, rdy, reset, x, .y(acc)); + input clk; + output rdy; + input reset; + + input [31:0] x; + output [15:0] acc; + + // acc holds the accumulated result, and acc2 is + // the accumulated square of the accumulated result. + reg [15:0] acc; + reg [31:0] acc2; + + // Keep track of which bit I'm working on. + reg [4:0] bitl; + wire [15:0] bit = 1 << bitl; + wire [31:0] bit2 = 1 << (bitl << 1); + + // The output is ready when the bitl counter underflows. + wire rdy = bitl[4]; + + // guess holds the potential next values for acc, + // and guess2 holds the square of that guess. + wire [15:0] guess = acc | bit; + wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1); + + task clear; + begin + acc = 0; + acc2 = 0; + bitl = 15; + end + endtask + + initial clear; + + always @(reset or posedge clk) + if (reset) + clear; + else begin + if (guess2 <= x) begin + acc <= guess; + acc2 <= guess2; + end + bitl <= bitl - 1; + end + + endmodule + +One could write the test bench as a program that passes a representative set +of input values into the device and checks the output result. However, we can +also write a program that takes on the command line an integer value to be +used as input to the device. We can write and compile this program, then pass +different input values on the run time command line without recompiling the +simulation. + +This example demonstrates the use of the "$value$plusargs" to access command +line arguments of a simulation:: + + module main; + + reg clk, reset; + reg [31:0] x; + wire [15:0] y; + wire rdy; + + sqrt32 dut (clk, rdy, reset, x, y); + + always #10 clk = ~clk; + + initial begin + clk = 0; + reset = 1; + + if (! $value$plusargs("x=%d", x)) begin + $display("ERROR: please specify +x= to start."); + $finish; + end + + #35 reset = 0; + + wait (rdy) $display("y=%d", y); + $finish; + end // initial begin + + endmodule // main + +The "$value$plusargs" system function takes a string pattern that describes +the format of the command line argument, and a reference to a variable that +receives the value. The "sqrt_plusargs" program can be compiled and executed +like this:: + + % iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v + % vvp sqrt_plusargs.vvp +x=81 + y= 9 + +Notice that the "x=%d" string of the "$value$plusargs" function describes the +format of the argument. The "%d" matches a decimal value, which in the sample +run is "81". This gets assigned to "x" by the "$value$plusargs" function, +which returns TRUE, and the simulation continues from there. + +If two arguments have to be passed to the testbench then the main module would +be modified as follows:: + + module main; + + reg clk, reset; + reg [31:0] x; + reg [31:0] z; + wire [15:0] y1,y2; + wire rdy1,rdy2; + + sqrt32 dut1 (clk, rdy1, reset, x, y1); + sqrt32 dut2 (clk, rdy2, reset, z, y2); + + always #10 clk = ~clk; + + initial begin + clk = 0; + reset = 1; + + if (! $value$plusargs("x=%d", x)) begin + $display("ERROR: please specify +x= to start."); + $finish; + end + + if (! $value$plusargs("z=%d", z)) begin + $display("ERROR: please specify +z= to start."); + $finish; + end + + + #35 reset = 0; + + wait (rdy1) $display("y1=%d", y1); + wait (rdy2) $display("y2=%d", y2); + $finish; + end // initial begin + + endmodule // main + +and the "sqrt_plusargs" program would be compiled and executed as follows:: + + % iverilog -osqrt_plusargs.vvp sqrt_plusargs.v sqrt.v + % vvp sqrt_plusargs.vvp +x=81 +z=64 + y1= 9 + y2= 8 + +In general, the "vvp" command that executes the compiled simulation takes a +few predefined argument flags, then the file name of the simulation. All the +arguments after the simulation file name are extended arguments to "vvp" and +are passed to the executed design. Extended arguments that start with a "+" +character are accessible through the "$test$plusargs" and "$value$plusargs" +system functions. Extended arguments that do not start with a "+" character +are only accessible to system tasks and functions written in C using the VPI. + +In the previous example, the program pulls the argument from the command line, +assigns it to the variable "x", and runs the sqrt device under test with that +value. This program can take the integer square root of any single value. Of +course, if you wish to test with a large number of input values, executing the +program many times may become tedious. + +Another technique would be to put a set of input values into a data file, and +write the test bench to read the file. We can then edit the file to add new +input values, then rerun the simulation without compiling it again. The +advantage of this technique is that we can accumulate a large set of test +input values, and run the lot as a batch. + +This example:: + + module main; + + reg clk, reset; + reg [31:0] data[4:0]; + reg [31:0] x; + wire [15:0] y; + wire rdy; + + sqrt32 dut (clk, rdy, reset, x, y); + + always #10 clk = ~clk; + + integer i; + initial begin + /* Load the data set from the hex file. */ + $readmemh("sqrt.hex", data); + for (i = 0 ; i <= 4 ; i = i + 1) begin + clk = 0; + reset = 1; + + x = data[i]; + + #35 reset = 0; + + wait (rdy) $display("y=%d", y); + end + $finish; + end // initial begin + + endmodule // main + +demonstrates the use of "$readmemh" to read data samples from a file into a +Verilog array. Start by putting into the file "sqrt.hex" the numbers:: + + 51 + 19 + 1a + 18 + 1 + +Then run the simulation with the command sequence:: + + % iverilog -osqrt_readmem.vvp sqrt_readmem.vl sqrt.vl + % vvp sqrt_readmem.vvp + y= 9 + y= 5 + y= 5 + y= 4 + y= 1 + +It is easy enough to change this program to work with larger data sets, or to +change the "data.hex" file to contain different data. This technique is also +common for simulating algorithms that take in larger data sets. One can extend +this idea slightly by using a "$value$plusargs" statement to select the file +to read. diff --git a/Documentation/usage/vpi.rst b/Documentation/usage/vpi.rst new file mode 100644 index 0000000000..24cd6f8b69 --- /dev/null +++ b/Documentation/usage/vpi.rst @@ -0,0 +1,246 @@ + +Using VPI +========= + +Icarus Verilog implements a portion of the PLI 2.0 API to Verilog. This allows +programmers to write C code that interfaces with Verilog simulations to +perform tasks otherwise impractical with straight Verilog. Many Verilog +designers, especially those who only use Verilog as a synthesis tool, can +safely ignore the entire matter of the PLI (and this chapter) but the designer +who wishes to interface a simulation with the outside world cannot escape VPI. + +The rest of this article assumes some knowledge of C programming, Verilog PLI, +and of the compiler on your system. In most cases, Icarus Verilog assumes the +GNU Compilation System is the compiler you are using, so tips and instructions +that follow reflect that. If you are not a C programmer, or are not planning +any VPI modules, you can skip this entire article. There are references at the +bottom for information about more general topics. + +How It Works +------------ + +The VPI modules are compiled loadable object code that the runtime loads at +the user's request. The user commands vvp to locate and load modules with the +"-m" switch. For example, to load the "sample.vpi" module:: + + % vvp -msample foo.vvp + +The vvp run-time loads the modules first, before executing any of the +simulation, or even before compiling the vvp code. Part of the loading +includes invoking initialization routines. These routines register with the +run-time all the system tasks and functions that the module implements. Once +this is done, the run time loader can match names of the called system tasks +of the design with the implementations in the VPI modules. + +(There is a special module, the system.vpi module, that is always loaded to +provide the core system tasks.) + +The simulator run time (The "vvp" program) gets a handle on a freshly loaded +module by looking for the symbol "vlog_startup_routines" in the loaded +module. This table, provided by the module author and compiled into the +module, is a null terminated table of function pointers. The simulator calls +each of the functions in the table in order. The following simple C definition +defines a sample table:: + + void (*vlog_startup_routines[])() = { + hello_register, + 0 + }; + +Note that the "vlog_startup_routines" table is an array of function pointers, +with the last pointer a 0 to mark the end. The programmer can organize the +module to include many startup functions in this table, if desired. + +The job of the startup functions that are collected in the startup table is to +declare the system tasks and functions that the module provides. A module may +implement as many tasks/functions as desired, so a module can legitimately be +called a library of system tasks and functions. + +Compiling VPI Modules +--------------------- + +To compile and link a VPI module for use with Icarus Verilog, you must compile +all the source files of a module as if you were compiling for a DLL or shared +object. With gcc under Linux, this means compiling with the "-fpic" flag. The +module is then linked together with the vpi library like so:: + + % gcc -c -fpic hello.c + % gcc -shared -o hello.vpi hello.o -lvpi + +This assumes that the "vpi_user.h header file and the libvpi.a library file +are installed on your system so that gcc may find them. This is normally the +case under Linux and UNIX systems. An easier, the preferred method that works +on all supported systems is to use the single command:: + + % iverilog-vpi hello.c + +The "iverilog-vpi" command takes as command arguments the source files for +your VPI module, compiles them with proper compiler flags, and links them into +a vpi module with any system specific libraries and linker flags that are +required. This simple command makes the "hello.vpi" module with minimum fuss. + +A Worked Example +---------------- + +Let us try a complete, working example. Place the C code that follows into the +file hello.c:: + + # include + + static int hello_compiletf(char*user_data) + { + return 0; + } + + static int hello_calltf(char*user_data) + { + vpi_printf("Hello, World!\n"); + return 0; + } + + void hello_register() + { + s_vpi_systf_data tf_data; + + tf_data.type = vpiSysTask; + tf_data.tfname = "$hello"; + tf_data.calltf = hello_calltf; + tf_data.compiletf = hello_compiletf; + tf_data.sizetf = 0; + tf_data.user_data = 0; + vpi_register_systf(&tf_data); + } + + void (*vlog_startup_routines[])() = { + hello_register, + 0 + }; + +and place the Verilog code that follows into hello.v:: + + module main; + initial $hello; + endmodule + +Next, compile and execute the code with these steps:: + + % iverilog-vpi hello.c + % iverilog -ohello.vvp hello.v + % vvp -M. -mhello hello.vvp + Hello, World! + +The compile and link in this example are conveniently combined into the +"iverilog-vpi" command. The "iverilog" command then compiles the "hello.v" +Verilog source file to the "hello.vvp" program. Next, the "vvp" command +demonstrates the use of the "-M" and "-m" flags to specify a vpi module search +directory and vpi module name. Specifically, they tell the "vvp" command where +to find the module we just compiled. + +The "vvp" command, when executed as above, loads the "hello.vpi" module that +it finds in the current working directory. When the module is loaded, the +vlog_startup_routines table is scanned, and the "hello_register" function is +executed. The "hello_register" function in turn tells "vvp" about the system +tasks that are included in this module. + +After the modules are all loaded, the "hello.vvp" design file is loaded and +its call to the "$hello" system task is matched up to the version declared by +the module. While "vvp" compiles the "hello.vvp" source, any calls to "$hello" +are referred to the "compiletf" function. This function is called at compile +time and can be used to check parameters to system tasks or function. It can +be left empty like this, or left out completely. The "compiletf" function can +help performance by collecting parameter checks in compile time, so they do +not need to be done each time the system task is run, thus potentially saving +execution time overall. + +When the run-time executes the call to the hello system task, the +"hello_calltf" function is invoked in the loaded module, and thus the output +is generated. The "calltf" function is called at run time when the Verilog +code actually executes the system task. This is where the active code of the +task belongs. + +System Function Return Types +---------------------------- + +Icarus Verilog supports system functions as well as system tasks, but there is +a complication. Notice how the module that you compile is only loaded by the +"vvp" program. This is mostly not an issue, but elaboration of expressions +needs to keep track of types, so the main compiler needs to know the return +type of functions. + +Starting with Icarus Verilog v11, the solution is quite simple. The names and +locations of the user's VPI modules can be passed to the compiler via the +"iverilog" -m and -L flags and the IVERILOG_VPI_MODULE_PATH environment +variable. The compiler will load and analyse the specified modules to +automatically determine any function return types. The compiler will also +automatically pass the names and locations of the specified modules to the +"vvp" program, so that they don't need to be specified again on the "vvp" +command line. + +For Icarus Verilog versions prior to v11, the solution requires that the +developer of a module include the table in a form that the compiler can +read. The System Function Table file carries this information. A simple +example looks like this:: + + # Example sft declarations of some common functions + $random vpiSysFuncInt + $bitstoreal vpiSysFuncReal + $realtobits vpiSysFuncSized 64 unsigned + +This demonstrates the format of the file and support types. Each line contains +a comment (starts with "#") or a type declaration for a single function. The +declaration starts with the name of the system function (including the leading +"$") and ends with the type. The supported types are: + +* vpiSysFuncInt +* vpiSysFuncReal +* vpiSysFuncSized + +Any functions that do not have an explicit type declaration in an SFT file are +implicitly taken to be "vpiSysFuncSized 32 unsigned". + +The module author provides, along with the ".vpi" file that is the module, a +".sft" that declares all the function return types. For example, if the file +is named "example.sft", pass it to the "iverilog" command line or in the +command file exactly as if it were an ordinary source file. + +Cadence PLI Modules +------------------- + +With the cadpli module, Icarus Verilog is able to load PLI1 applications that +were compiled and linked to be dynamic loaded by Verilog-XL or +NC-Verilog. This allows Icarus Verilog users to run third-party modules that +were compiled to interface with XL or NC. Obviously, this only works on the +operating system that the PLI application was compiled to run on. For example, +a Linux module can only be loaded and run under Linux. In addition, a 64-bit +version of vvp can only load 64-bit PLI1 applications, etc. + +Icarus Verilog uses an interface module, the "cadpli" module, to connect the +worlds. This module is installed with Icarus Verilog, and is invoked by the +usual -m flag to iverilog or vvp. This module in turn scans the extended +arguments, looking for -cadpli= arguments. The latter specify the share object +and bootstrap function for running the module. For example, to run the module +product.so, that has the bootstrap function "my_boot":: + + % vvp -mcadpli a.out -cadpli=./product.so:my_boot + +The "-mcadpli" argument causes vvp to load the cadpli.vpl library module. This +activates the -cadpli= argument interpreter. The -cadpli=: +argument, then, causes vvp, through the cadpli module, to load the loadable +PLI application, invoke the my_boot function to get a veriusertfs table, and +scan that table to register the system tasks and functions exported by that +object. The format of the -cadpli= extended argument is essentially the same +as the +loadpli1= argument to Verilog-XL. + +The integration from this point is seamless. The PLI application hardly knows +that it is being invoked by Icarus Verilog instead of Verilog-XL, so operates +as it would otherwise. + +Other References +---------------- + +Since the above only explains how to get PLI/VPI working with Icarus Verilog, +here are some references to material to help with the common aspects of +PLI/VPI. + +* Principles of Verilog PLI by Swapnajit Mittra. ISBN 0-7923-8477-6 +* The Verilog PLI Handbook by Stuart Sutherland. ISBN 0-7923-8489-X