Giter Site home page Giter Site logo

steveicarus / iverilog Goto Github PK

View Code? Open in Web Editor NEW
2.7K 135.0 512.0 29.39 MB

Icarus Verilog

Home Page: https://steveicarus.github.io/iverilog/

License: GNU General Public License v2.0

C++ 36.88% C 21.88% Shell 0.20% Lex 1.34% Yacc 2.92% Makefile 0.64% Roff 0.35% M4 0.08% Verilog 33.63% Python 0.15% VHDL 1.22% SystemVerilog 0.01% V 0.03% Pascal 0.01% Perl 0.67% Coq 0.01%

iverilog's Introduction

The ICARUS Verilog Compilation System

Copyright 2000-2019 Stephen Williams

Table of Contents

  1. What is ICARUS Verilog?
  2. Building/Installing Icarus Verilog From Source
  3. How Icarus Verilog Works
  4. Running iverilog
  5. Unsupported Constructs
  6. Nonstandard Constructs or Behaviors
  7. Credits

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 behavioural constructs. For a view of the current state of Icarus Verilog, see its home page at https://steveicarus.github.io/iverilog/.

Icarus Verilog is not aimed at being a simulator in the traditional sense, but a compiler that generates code employed by back-end tools.

For instructions on how to run Icarus Verilog, see the iverilog man page.

Building/Installing Icarus Verilog from Source

If you are starting from the 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.

If you are building on Windows, see the mingw.txt file.

Compile Time Prerequisites

You can use:

apt install -y autoconf gperf make gcc g++ bison flex

You need the following software to compile Icarus Verilog from source on a UNIX-like system:

  • GNU Make The Makefiles use some GNU extensions, so a basic POSIX make will not work. Linux systems typically come with a satisfactory make. BSD based systems (i.e., NetBSD, FreeBSD) typically have GNU make as the gmake program.

  • ISO C++ Compiler The ivl and ivlpp programs are written in C++ and make use of templates and some of the standard C++ library. egcs and recent gcc compilers with the associated libstdc++ are known to work. MSVC++ 5 and 6 are known to definitely not work.

  • bison and flex OSX note: bison 2.3 shipped with MacOS including Catalina generates broken code, but bison 3+ works. We recommend using the Fink project version of bison and flex (finkproject.org), brew version works fine either.

  • gperf 3.0 or later The lexical analyzer doesn't recognize keywords directly, but instead matches symbols and looks them up in a hash table in order to get the proper lexical code. The gperf program generates the lookup table.

    A version problem with this program is the most common cause of difficulty. See the Icarus Verilog FAQ.

  • readline 4.2 or later On Linux systems, this usually means the readline-devel rpm. In any case, it is the development headers of readline that are needed.

  • termcap The readline library, in turn, uses termcap.

    If you are building from git, you will also need software to generate the configure scripts.

  • autoconf 2.53 or later This generates configure scripts from configure.ac. The 2.53 or later versions are known to work, autoconf 2.13 is reported to not work.

Compilation

Unpack the tar-ball, cd into the verilog-######### directory, and compile the source with the commands:

  ./configure
  make

Compiling From GitHub

If you are building from git, you have to run the command below before compiling the source. This will generate the "configure" file, which is automatically done when building from tarball.

  sh autoconf.sh
  ./configure
  make

Normally, this command automatically figures out everything it needs to know. It generally works pretty well. There are a few flags to the configure script that modify its behaviour:

	--prefix=<root>
		The default is /usr/local, which causes the tool suite to
		be compiled for install in /usr/local/bin,
		/usr/local/share/ivl, etc.

		I recommend that if you are configuring for precompiled
		binaries, use --prefix=/usr.  On Solaris systems, it is
		common to use --prefix=/opt.  You can configure for a non-root
		install with --prefix=$HOME.

	--enable-suffix
	--enable-suffix=<your-suffix>
	--disable-suffix
		Enable/disable changing the names of install files to use
		a suffix string so that this version or install can co-
		exist with other versions. This renames the installed
		commands (iverilog, iverilog-vpi, vvp) and the installed
		library files and include directory so that installations
		with the same prefix but different suffix are guaranteed
		to not interfere with each other.

	--host=<host-type>
		Compile iverilog for a different platform. You can use:
				x64_64-w64-mingw32 for building 64-bit Windows executables
				i686-w64-mingw32 for building 32-bit Windows executables
			Both options require installing the required mingw-w64 packages.

(Optional) Testing

To run a simple test before installation, execute

  make check

The commands printed by this run might help you in running Icarus Verilog on your own Verilog sources before the package is installed by root.

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.) You may need to do this as root to gain access to installation directories.

	make install

Uninstallation

The generated Makefiles also include the uninstall target. This should remove all the files that make install creates.

How Icarus Verilog 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.

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.

Parse

The Verilog compiler starts by parsing the Verilog source file. The output of the parse is 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 ivl subcommand. This will cause ivl to dump the pform into the file named <path>. (Note that this is not normally done, unless debugging the ivl subcommand.)

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 netlist includes all the behavioural descriptions, as well as gates and wires.

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>.

Elaboration is performed in two steps: scopes and parameters first, followed by the structural and behavioural elaboration.

Scope Elaboration

This pass scans through the pform looking for scopes and parameters. A tree of NetScope objects is built up and placed in the Design object, with the root module represented by the root NetScope object. The elab_scope.cc file contains most of the code for handling this phase.

The tail of the elaborate_scope behaviour (after the pform is traversed) includes a scan of the NetScope tree to locate defparam assignments that were collected during scope elaboration. This is when the defparam overrides are applied to the parameters.

Netlist Elaboration

After the scopes and parameters are generated and the NetScope tree fully formed, the elaboration runs through the pform again, this time generating the structural and behavioural netlist. Parameters are elaborated and evaluated by now so all the constants of code generation are now known locally, so the netlist can be generated by simply passing through the pform.

Optimization

This is a collection of processing steps that perform optimizations that do not depend on the target technology. Examples of some useful transformations are

  • eliminate null effect circuitry
  • combinational reduction
  • constant propagation

The actual functions performed are specified on the ivl command line by the -F flags (see below).

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 the need arises to generate actual output.

The user selects the target code generator with the -t flag on the command line.

Attributes

NOTE: The $attribute syntax will soon be deprecated in favour of the Verilog-2001 attribute syntax, which is cleaner and standardized.

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 than 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 the global scope, instead of within a module. The semicolon is not part of a type attribute.

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.

Icarus Verilog also accepts the Verilog 2001 syntax for attributes. They have the same general meaning as with the $attribute syntax, but they are attached to objects by position instead of by name. Also, the key is a Verilog identifier instead of a string.

Running iverilog

The preferred way to invoke the compiler is with the iverilog(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 iverilog(1) man page for usage details.

EXAMPLE: Hello World

Example: Compiling "hello.vl"

// ------------------------ hello.vl ----------------------------

module main();

initial
  begin
    $display("Hello World");
    $finish ;
  end

endmodule

// --------------------------------------------------------------

Ensure that iverilog is on your search path, and the vpi library is available.

To compile the program:

	iverilog 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 generated program:

	./a.out

You can use the -o switch to name the output command to be generated by the compiler. See the iverilog(1) man page.

Unsupported Constructs

Icarus Verilog 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, and in particular, browse the bug report database for reported unsupported constructs.

  • System functions are supported, but the return value is a little tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.

  • Specify blocks are parsed but ignored in general.

  • trireg is not supported. tri0 and tri1 are supported.

  • tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1, and rtranif0 are not supported.

  • Net delays, of the form wire #N foo; do not work. Delays in every other context do work properly, including the V2001 form wire #5 foo = bar;

  • Event controls inside non-blocking assignments are not supported. i.e.: a <= @(posedge clk) b;

  • Macro arguments are not supported. `define macros are supported, but they cannot take arguments.

Nonstandard Constructs or Behaviors

Icarus Verilog includes some features that are not part of the IEEE1364 standard, but have well-defined meaning, and also sometimes gives nonstandard (but extended) meanings to some features of the language that are defined. See the "extensions.txt" documentation for more details.

  • $is_signed(<expr>)

    This system function returns 1 if the expression contained is signed, or 0 otherwise. This is mostly of use for compiler regression tests.

  • $sizeof(<expr>), $bits(<expr>)

    The $bits system function returns the size in bits of the expression that is its argument. The result of this function is undefined if the argument doesn't have a self-determined size.

    The $sizeof function is deprecated in favour of $bits, which is the same thing, but included in the SystemVerilog definition.

  • $simtime

    The $simtime system function returns as a 64bit value the simulation time, unscaled by the time units of local scope. This is different from the $time and $stime functions which return the scaled times. This function is added for regression testing of the compiler and run time, but can be used by applications who really want the simulation time.

    Note that the simulation time can be confusing if there are lots of different `timescales within a design. It is not in general possible to predict what the simulation precision will turn out to be.

  • $mti_random(), $mti_dist_uniform

    These functions are similar to the IEEE1364 standard $random functions, but they use the Mersenne Twister (MT19937) algorithm. This is considered an excellent random number generator, but does not generate the same sequence as the standardized $random.

Builtin system functions

Certain of the system functions have well-defined meanings, so can theoretically be evaluated at compile-time, instead of using runtime VPI code. Doing so means that VPI cannot override the definitions of functions handled in this manner. On the other hand, this makes them synthesizable, and also allows for more aggressive constant propagation. The functions handled in this manner are:

  • $bits
  • $signed
  • $sizeof
  • $unsigned

Implementations of these system functions in VPI modules will be ignored.

Preprocessing Library Modules

Icarus Verilog does preprocess modules that are loaded from libraries via the -y mechanism. However, the only macros defined during the compilation of that file are those that it defines itself (or includes) or that are defined in the command line or command file.

Specifically, macros defined in the non-library source files are not remembered when the library module is loaded. This is intentional. If it were otherwise, then compilation results might vary depending on the order that libraries are loaded, and that is too unpredictable.

It is said that some commercial compilers do allow macro definitions to span library modules. That's just plain weird.

Width in %t Time Formats

Standard Verilog does not allow width fields in the %t formats of display strings. For example, this is illegal:

	$display("Time is %0t", $time);

Standard Verilog instead relies on the $timeformat to completely specify the format.

Icarus Verilog allows the programmer to specify the field width. The %t format in Icarus Verilog works exactly as it does in standard Verilog. However, if the programmer chooses to specify a minimum width (i.e., %5t), then for that display Icarus Verilog will override the $timeformat minimum width and use the explicit minimum width.

vpiScope Iterator on vpiScope Objects

In the VPI, the normal way to iterate over vpiScope objects contained within a vpiScope object, is the vpiInternalScope iterator. Icarus Verilog adds support for the vpiScope iterator of a vpiScope object, that iterates over everything the is contained in the current scope. This is useful in cases where one wants to iterate over all the objects in a scope without iterating over all the contained types explicitly.

Time 0 Race Resolution

Combinational logic is routinely modelled using always blocks. However, this can lead to race conditions if the inputs to the combinational block are initialized in initial statements. Icarus Verilog slightly modifies time 0 scheduling by arranging for always statements with ANYEDGE sensitivity lists to be scheduled before any other threads. This causes combinational always blocks to be triggered when the values in the sensitivity list are initialized by initial threads.

Nets with Types

Icarus Verilog supports an extended syntax that allows nets and regs to be explicitly typed. The currently supported types are logic, bool and real. This implies that logic and bool are new keywords. Typical syntax is:

	wire real foo = 1.0;
	reg logic bar, bat;

... and so forth. The syntax can be turned off by using the -g2 flag to iverilog, and turned on explicitly with the -g2x flag to iverilog.

Credits

Except where otherwise noted, Icarus Verilog, ivl, and ivlpp are Copyright Stephen Williams. The proper notices are in the head of each file. However, I have early on received aid in the form of fixes, Verilog guidance, and especially testing from many people. Testers, in particular, include a larger community of people interested in a GPL Verilog for Linux.

iverilog's People

Contributors

caryr avatar deflateawning avatar henry-stuffedcow avatar jaredcasper avatar jauricchio avatar kurzfc avatar larsclausen avatar ldoolitt avatar martinwhitaker avatar mmicko avatar mole99 avatar nekromant avatar nickg avatar nishtahir avatar orsonmmz avatar proppy avatar pszostek avatar purdeaandrei avatar purdeaandrei-movi avatar siesh1oo avatar sifferman avatar smunaut avatar steveicarus avatar thasti avatar themperek avatar udif avatar umarcor avatar vowstar avatar wmlye avatar yugr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iverilog's Issues

Icarus does undef propagation of const adds incorrectly

The following module should set both outputs to constant 4'bxxx:

module test(a, y1, y2);
  input [1:0] a;
  output [3:0] y1, y2;
  assign y1 = 4'bxx00 + 2'b00;
  assign y2 = 4'bxx00 + a;
endmodule

But Icarus Verilog (git 5a06602) does only the case involving a variable
correctly. In the constant case it is too smart and outputs 4'bxx00 instead.

Pause Resume doesn't work twice in a row because the handler gets removed.

I believe that the OS seems to remove the handler after signalling SIGINT. I have looked through the code and don't see anywhere it is being removed within the Iverilog code, yet I have found several websites online that suggest that you should reattach the handler when the handler is called.

http://www.geeksforgeeks.org/write-a-c-program-that-doesnt-terminate-when-ctrlc-is-pressed/

I'm not sure whether you wish for vvp to support pause and resume or not, but it seems that using the change proposed there that I can have this functionality.

I wanted to be able to pause and resume vvp.exe using ctrl c and the "cont" command, so I built an older snapshot of icarus to try testing it.

After altering the function "signals_handler" as shown below, I was able to get the functionality I wanted.

schedule.cc

  • These are the signal handling infrastructure. The SIGINT signal
  • leads to an implicit $stop.
    */
    extern "C" void signals_handler(int)
    {
    //reset signals handler so that program can be paused and resumed with ctrl + c and cont commands
    signal(SIGINT, &signals_handler);
    schedule_stopped_flag = true;
    }

Now I am able to hit Ctrl C, pause the simulation, and then send "cont" to standard in and have vvp resume the simulation multiple times.

If there is a better way of doing this, feel free to let me know

Bug, no bug, or just undefined, that is the question (real vs. signed and unsigned int)

I'm not sure if this is a bug report or a request to explain the Verilog standard to me [1].

Consider the following test case:

module test(y1, y2, y3);
        output [63:0] y1, y2, y3;
        assign y1 = 1 ?  1 ?  -1 : 'd0 : 0.0;
        assign y2 = 1 ? -1 :   1 ? 'd0 : 0.0;
        assign y3 = 1 ? -1 : 'd0;
        initial begin
                #1;
                $display("%b", y1);
                $display("%b", y2);
                $display("%b", y3);
        end
endmodule

In iverilog, xsim and modelsim the output is:

0000000000000000000000000000000011111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111

So the tools are consistent. But I do not understand why -1 is 32 bits in the first case and 64 bits in the two other cases. Imo it should be either

(1) evaluated as part of a real expression and only converted to a bit pattern when it is assigned to y*. And as y* is a 64 bit signal the conversion should yield 64 set bits. Or

(2) the -1 is not evaluated as part of a real expression. In this case the final size (64 bits) should be known to the negation operator, thus yielding 64 set bits.

I'm trying to implement support for real values in Yosys in a way so that corner cases that are not sufficiently covered by the standard document show the same behavior as in iverilog. This makes it much easier for me to test the defined cases. But I'm having a hard time understanding how iverilog actually handles cases like this one..

Thanks in advance for educating me. ;)

Assertion `lval_->more == 0' failed

I've tried to compile this with -tblif
it generates:

$ iverilog ./tgt2t.v -tblif -dsynth2
debug: Enable synth2 debug
./tgt2t.v:16: NetProcTop::synth_sync: Process is apparently synchronous. Making NetFFs.
./tgt2t.v:16: NetEvWait::synth_sync: Synchronous process an event statement.
./tgt2t.v:16: NetEvWait::synth_sync: Found and synthesized the FF clock.
ivl: synth2.cc:85: virtual bool NetAssignBase::synth_async(Design_, NetScope_, NexusSet&, NetBus&, NetBus&): Assertion `lval_->more == 0' failed.
sh: line 1: 4168 Done /usr/lib/ivl/ivlpp -L -F"/tmp/ivrlg27e788233" -f"/tmp/ivrlg7e788233" -p"/tmp/ivrli7e788233"
4169 Aborted | /usr/lib/ivl/ivl -C"/tmp/ivrlh7e788233" -C"/usr/lib/ivl/blif.conf" -- -

The code:

module pci_tgt(
(*PAD="1"*)
input wire clk,
(*PAD="4"*)
input wire RST,
(*PAD="?"*)
output reg S0,
(*PAD="?"*)
output reg S1,
(*PAD="?"*)
output reg S2);

//the state bits
`define S {S0,S1,S2}

always @(posedge clk or posedge RST)
begin
  if(RST)
  begin
  //this failz an assert....
    `S <= 0;
  end
end

endmodule

With the clk removed, it still segfaults(but does not fail the assert).
What's broken now?

Bug: Wrong number of arguments error on expansion of macro with default arguments

pptest.sv

module modname;
`define macro1(arg1=d1) $info(`"arg1`");
`define macro2(arg1=d1, arg2=d2) $info(`"arg1 arg2`");
   initial begin
      `macro1() // Works
      `macro1(1) // Works

      `macro2() // Cause wrong number of arguments error
      `macro2(1) // Cause wrong number of arguments error
      `macro2(1,2) // Works

      `macro2(,) // Works
      `macro2(1,) // Works
      `macro2(1,2) // Works

      `macro2(,2) // Works
   end
endmodule

iverilog output:

> iverilog -E pptest.sv && cat a.out 
pptest.sv:8: error: wrong number of arguments for `macro2
pptest.sv:9: error: wrong number of arguments for `macro2
module modname;


   initial begin
      $info("d1"); // Works
      $info("1"); // Works

       // Cause wrong number of arguments error
       // Cause wrong number of arguments error
      $info("1 2"); // Works

      $info("d1 d2"); // Works
      $info("1 d2"); // Works
      $info("1 2"); // Works

      $info("d1 2"); // Works
   end
endmodule

Correct preprocessor output:

> vlog pptest.sv -E a.out; cat a.out 
Model Technology ModelSim ALTERA vlog 10.3c Compiler 2014.09 Sep 20 2014
Start time: 09:59:36 on Jun 27,2015
vlog pptest.sv -E a.out 
-- Compiling module modname

Top level modules:
    modname
End time: 09:59:36 on Jun 27,2015, Elapsed time: 0:00:00
Errors: 0, Warnings: 0

`line 1 "pptest.sv" 0
module modname;

`line 2 "pptest.sv" 0


`line 3 "pptest.sv" 0

   initial begin
       $info("d1"); 
       $info("1"); 

       $info("d1 d2"); 
       $info("1 d2"); 
       $info("1 2"); 

       $info("d1 d2"); 
       $info("1 d2"); 
       $info("1 2"); 

       $info("d1 2"); 
   end
endmodule

Assert (instead of error message) for function outside module

In verilog it is invalid to declare a function outside of a module. For example the following is not a valid input file:

function test;
  begin
    test = 0;
  end
endfunction

Icarus verilog b7b77b2 does not generate a proper error for this input. Instead it just fails with an assert:

ivl: pform.cc:390: PFunction* pform_push_function_scope(const vlltype&, const char*, bool): Assertion `scopex' failed.

vpi: tri bus split

Something that worked last week does not work now.
Works with Modelsim as expected.
When tri state bus is split the state is not propagated.

#include <assert.h>
#include "vpi_user.h"

static PLI_INT32
EndOfCompile(s_cb_data *data)
{
    s_vpi_time timerec = { vpiSimTime, 0, 0, 0 };
    s_vpi_value val_b0;

    vpiHandle bd_handle;

    (void)data;

    bd_handle = vpi_handle_by_name("test.BD", 0);
    assert(bd_handle);

    val_b0.value.str = "zzzzzzzz";
    val_b0.format = vpiBinStrVal;
    vpi_put_value(bd_handle, &val_b0,  &timerec, vpiInertialDelay);

    timerec.low = 1000;
    val_b0.value.str = "00000010";
    vpi_put_value(bd_handle, &val_b0,  &timerec, vpiInertialDelay);

    timerec.low = 2000;
    val_b0.value.str = "zzzzzzzz";
    vpi_put_value(bd_handle, &val_b0,  &timerec, vpiInertialDelay);

    timerec.low = 3000;
    vpi_put_value(bd_handle, &val_b0,  &timerec, vpiInertialDelay);

    return 0;
}


static void
VPIRegister(void)
{
    s_cb_data cb_data;
    s_vpi_time timerec = { vpiSuppressTime, 0, 0, 0 };

    cb_data.time = &timerec;
    cb_data.value = 0;
    cb_data.user_data = 0;
    cb_data.obj = 0;
    cb_data.reason = cbEndOfCompile;
    cb_data.cb_rtn = EndOfCompile;

    vpi_register_cb(&cb_data);
}

void (*vlog_startup_routines[]) () = { VPIRegister, 0};
`timescale 1 ns / 1 ns

module bus_to_ip
#(
    parameter DBUSWIDTH = 8
)
(
    inout wire [DBUSWIDTH-1:0] BUS_DATA
);

assign BUS_DATA = {DBUSWIDTH{1'bz}};

endmodule


module test(
    inout wire [7:0] BD
);

    bus_to_ip #( .DBUSWIDTH(4)) i_bus_to_ip1
    (
        .BUS_DATA(BD[3:0])
    );

    bus_to_ip #( .DBUSWIDTH(8)) i_bus_to_ip2
    (
        .BUS_DATA(BD)
    );

    initial begin
        $dumpfile("testz.vcd");
        $dumpvars(0);
    end

    initial begin
        #1500
        $display("BUS_IP1 = %b BUS_IP2 = %b @ %0t", i_bus_to_ip1.BUS_DATA, i_bus_to_ip2.BUS_DATA, $time);
    end

endmodule

Output:

BUS_IP1 = zzzz BUS_IP2 = 00000010 @ 1500

Fails to compile

Just cloned the repository and tried to make
first with -j3
then without...
didn't work...
I believe it's related to the latest change to the makefile...

make[1]: Entering directory '/home/klammerj/projects/FPGA/src/ivl_ups_relly/tgt-pcb'
g++ -I. -I..  -DHAVE_CONFIG_H -fPIC -Wall -Wextra -Wshadow   -O0 -g -MD -c fp_lex.cc -o fp_lex.o
./fp.lex:27:18: fatal error: fp.h: No such file or directory
 # include  "fp.h"

Efficiency of verinum and vpp_net pow() functions

Modules such as

module test(y);
  output [5:0] y;
  assign y = 6'd3 ** 123456789;
endmodule

take forever to compile because the verinum pow() function is actually using a loop to evaluate the power:

  for (long idx = 1 ;  idx < pow_count ;  idx += 1)
        result = result * left;

(For exponents that do not fit into a long long this would also return incorrect values, but I think no-one would wait for such a case to finish compiling..)

This should of course be instead calculated using a Power-Modulus Algorithm. See the const_pow() function in Yosys for an example implementation.

The vvp_net pow() function seems to implement a power-modulus algorithm but nevertheless the following code snippet hangs vvp:

module test(a, y);
  input [5:0] a;
  output [5:0] y;
  assign a = 3;
  assign y = a ** 123456789;
endmodule

PS: the examples above should evaluate to

assign y = 6'b110011;

unability to async-reset wide registers to non-zero value

I run the command:
iverilog -tblif ./dff_scramble.v

The error message I get is:
./dff_scramble.v:24: sorry: Forgot how to implement asynchronous scramble (set to x/z). ./dff_scramble.v:23: error: Unable to synthesize synchronous process.
It happens in synth2.cc

The file is:

/*
 * A D-type flip-flop to check synchronous logic works
 * correctly.
 */


module dff(
output wire [3:0] q, 
input wire [3:0] d, 
input wire clk, 
input wire rstin,
input wire ce,
input wire [3:0] oe);


reg [3:0] rg;

bufif1(q[0],rg[0],oe[0]);
bufif1(q[1],rg[1],oe[1]);
bufif1(q[2],rg[2],oe[2]);
bufif1(q[3],rg[3],oe[3]);

  always @(posedge clk or posedge rstin)
    if (rstin)
      rg <= 4'b0001;
    else
        if(ce)
        rg <= d;


endmodule // dff

out of date FSF address

The FSF address is out of date in the header of many files

at the moment it read:

  • You should have received a copy of the GNU General Public License
  • along with this program; if not, write to the Free Software
  • Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA

but it should read:
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

see: http://www.gnu.org/licenses/gpl-2.0.html#SEC4

if you want I can fork and supply a patch, let me know.

Icarus confused about signed/unsigned in strange ?: example

The following module should set the output to constant 0, because the 4'b0 makes the whole expression unsigned.

module issue_032(y);
  wire signed [3:0] a = -5;
  wire signed [3:0] b =  0;
  output y;
  assign y = (1 ? a : 4'b0) < (1 ? b : b); 
  initial #1 $display("%b", y);
endmodule

But Icarus Verilog (git 3e41a93) assigns 1 instead. Interestingly the bug goes away if the (1 ? b : b) is replaced by b.

SystemVerilog 'b0 construct for flexible padding?

Is support for flexible padding in Verilog planned, as described here?

I seems to be a SV 2012 construct, but using the development version of iverilog -g2012 on assign padded_A = {'b0, A};, I get the following error:

error: Concatenation operand "'d0" has indefinite width.
error: Unable to elaborate r-value: {'d0, A}

Thanks!
Mike

Insufficient string escaping when writing vvp script

When iverilog writes a vvp script it does not sufficiently escape quotes in module names. For example:

module tb;
  wire [63:0] y;
  \test_str="hello" uut (y);
  initial #1 $display("%s", y);
endmodule

module \test_str="hello" (output [63:0]y);
  assign y = "hello";
endmodule

Is valid Verilog but will create invalid output:

$ iverilog demo.v 
$ ./a.out 
./a.out:13: syntax error

(Tested with rev f104ffc.)

iverilog gives no warning against dangling wires within a module

For the latest git version, the following code with a dangling wire "e" in the "bug2" module

module bug2 (input a, input b, input c, output d);
wire e;
assign d = c & e;
endmodule

module top ();
wire mon;
bug2 inst (.a(1'b1), .b(1'b1), .d(mon));
endmodule

produces no warning about "e" even if -Wall is turned on. iverilog does give warning about the dangling "c" in the port during instantiation.

It will also be helpful if iverilog can check unused wires and regs. This will be helpful for removing logics that are no longer needed in a huge complicated design.

internal error: lval-rval width mismatch

The following module fails to build with icarus verilog:

module issue_022(a, y);
  input [1:0] a;
  output [1:0] y;
  assign y = 'bx ? 2'b0 : a;
endmodule

the error message produced is:

internal error: lval-rval width mismatch: rval->vector_width()==1, lval->vector_width()==2
assert: elaborate.cc:150: failed assertion rval->vector_width() >= lval->vector_width()

This is with git rev 68f8de2.

Icarus only using the lowest 32 bits of right shift operand

The following module should set the output to constant 4'b0000:

module issue_029(y);
  output [3:0] y;
  assign y = 4'b1 << 33'h100000000;
endmodule

But Icarus Verilog (git ed2e339) assigns 4'b0001 instead.

(Sorry for another "stupidly large right shift operand" issue, but that's what keeps coming up in my test cases.)

yosys test repwhile causes crash

yosys commit YosysHQ/yosys@7066312 contains a test "repwhile" that will crash iverilog

  1. run "make" and "make test" to produce all necessary yosys files (the "make test" should fail out at the repwhile test)
  2. cd <yosys_repo>/tests/simple/repwhile.out
  3. iverilog -s testbench -o repwhile_tb_syn0 repwhile_tb.v repwhile_syn1.v ../../../techlibs/common/simlib.v ../../../techlibs/common/simcells.v
  4. output is as follows
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    warning: verinum::as_long() truncated 32 bits to 31, returns 2147483647
    ivl: t-dll.cc:542: void dll_target::make_scope_parameters(ivl_scope_t, const NetScope*): Assertion `cur_par->msb >= 0' failed.
    Aborted (core dumped)

@cliffordwolf updated yosys with the following commits to avoid the crash
YosysHQ/yosys@a1c62b7
YosysHQ/yosys@95944eb

@cliffordwolf mentioned that the generated code contained questionable constructs, but I thought you would want to know it crashed iverilog.

NOT accuracy when mix block & non-block assignment

Icarus Verilog version 0.10.0 (devel) (s20150603-55-g97c6339)
cygwin, gcc-4.8.3

the following is bench file.

module test (

output reg MPC_LCLK,
output reg MPC_LALE,

output reg [7:0] MPC_LA,
inout [7:0] MPC_LAD
);

reg [7:0] mpc_address;

assign MPC_LAD = (MPC_LALE == 1'b1) ? mpc_address : 8'hz;

initial begin
MPC_LCLK = 0;
MPC_LALE = 0;
mpc_address = 0;
end

always #15 MPC_LCLK = !MPC_LCLK;

task foo;
input [16:0] address;

begin
@(posedge MPC_LCLK)
mpc_address = address[15:8];
MPC_LA = address[7:0];
MPC_LALE = 1;
@(posedge MPC_LCLK)
MPC_LALE = 0;
end

endtask

reg [15:0] addr;

always @(posedge MPC_LCLK)
begin
addr <= {MPC_LAD, MPC_LA};
end

integer i;
initial begin
//$dumpfile("test.vcd");
//$dumpvars(0, test);
$monitor($time, " : %h %h : %h %h", MPC_LAD, MPC_LA, MPC_LALE, addr);
#100 foo(4);
#100 $finish;
end

endmodule

the simulation result is below.

               0 : zz xx : 0 xxxx
             15  : zz xx : 0 zzxx
             105 : 00 04 : 1 zz04        <-  this line should be "105 : 00 04 : 1 zzxx"
             135 : zz 04 : 0 0004
             165 : zz 04 : 0 zz04

Signedness handling in binary bitwise operations of constants

Bitwise operations of signed values should yield a signed value (see sec. 5.5.1 of IEEE Std 1365-2005). This is implemented correctly in Icarus Verilog for operations involving at least one variable, but bit-wise boolean operations of two signed constants yield an unsigned constant.

For example the following test case:

module issue_013(a, y);
  input signed [3:0] a;
  output [1:0] y;
  assign y[0] = a > (4'sb1010 | 4'sd0);
  assign y[1] = (a | 4'sd0) > 4'sb1010;
endmodule

For "a=0" this will assign y[0]=0 and y[1]=1. The value for y[1] is correct (this is an all-signed expression). The value for y[0] is incorrect. (Tested with git d1c9dd5.)

Strange "localparam integer" behavior

The following module should print '1' (tested with modelsim 10.1d and xsim 2014.2), but iverilog 1572dcd prints '0':

module test;
  localparam integer p = -1;
  initial $display("%b", (1 + p) == |0);
endmodule

Without the keyword "integer" the module behaves as expected.

Pause Resume functionality.

I wanted to be able to pause and resume vvp.exe using ctrl c and the "cont" command. There is a ctrl c handler, to allow pausing, but it will break because it does not reattach the handler for SIGINT after the sigint is called.

My testing indicates that if I alter the function:

  • These are the signal handling infrastructure. The SIGINT signal
  • leads to an implicit $stop.
    */
    extern "C" void signals_handler(int)
    {
    //reset signals handler so that program can be paused and resumed with ctrl + c and cont commands
    signal(SIGINT, &signals_handler);
    schedule_stopped_flag = true;
    }

in schedule.cc, then the the signal handler gets reattached and can be used for resuming.

If there is a better way of doing this, feel free to let me know

iverilog allows use before declaration

For the latest version from git, the following code that uses "d" before declaration

module bug1 (input a, input b, output c);
assign c = d;
wire d = a & b;
endmodule

produces no warning, even if -Wall is specified in the command line. Meanwhile, many other verilog compilers treat this as an error. I think at least a warning should be given.

{256'b0}[ADDR-1:0]; Syntax error

I am not sure how to define in.

But in order to avoid ISE warning (Size mismatch) I am using this construct. It works their but gives error in iverilog.

Address_In <= {Address_In + 1}[ADDR-1:0];

../../hdl/fifo.v:73: syntax error
../../hdl/fifo.v:73: error: malformed statement

and

{256'b0}[ADDR-1:0];

../../hdl/fifo.v:47: syntax error
../../hdl/fifo.v:47: error: invalid port connection expression.

RAM simulation mismatch

When I describe a ram using two slightly different but valid descriptions and use the same testbench on both descriptions I recieve different results. I believe the results should be the same.

file gold.v::

module bram_00_08(A1ADDR, A1DATA, B1ADDR, B1DATA, CLK1);
  input CLK1;
  input [0:0] A1ADDR;
  input [3:0] A1DATA;
  input [0:0] B1ADDR;
  output reg [3:0] B1DATA;

  reg [3:0] memory [0:1];
  initial begin
    memory[0] <= 4'd0;
    memory[1] <= 4'd0;
  end

  always @(posedge CLK1) begin
    memory[A1ADDR] = A1DATA;
    B1DATA <= memory[B1ADDR];
  end
endmodule

file gate.v::

module bram_00_08(A1ADDR, A1DATA, B1ADDR, B1DATA, CLK1);
  input CLK1;
  input [0:0] A1ADDR;
  input [3:0] A1DATA;
  input [0:0] B1ADDR;
  output reg [3:0] B1DATA;

  reg [3:0] memory [0:1];
  initial begin
    memory[0] <= 4'd0;
    memory[1] <= 4'd0;
  end

  always @(posedge CLK1)
    memory[A1ADDR] = A1DATA;
  always @(posedge CLK1)
    B1DATA <= memory[B1ADDR];
endmodule

file tb.v::
Autogenerated using yosys.

module testbench;

integer i;

reg [31:0] xorshift128_x = 123456789;
reg [31:0] xorshift128_y = 362436069;
reg [31:0] xorshift128_z = 521288629;
reg [31:0] xorshift128_w = 1431531335; // <-- seed value
reg [31:0] xorshift128_t;

task xorshift128;
begin
    xorshift128_t = xorshift128_x ^ (xorshift128_x << 11);
    xorshift128_x = xorshift128_y;
    xorshift128_y = xorshift128_z;
    xorshift128_z = xorshift128_w;
    xorshift128_w = xorshift128_w ^ (xorshift128_w >> 19) ^ xorshift128_t ^ (xorshift128_t >> 8);
end
endtask

wire [3:0] sig_bram_00_08_B1DATA;
reg [0:0] sig_bram_00_08_B1ADDR;
reg [3:0] sig_bram_00_08_A1DATA;
reg [0:0] sig_bram_00_08_A1ADDR;
reg [0:0] sig_bram_00_08_CLK1;
bram_00_08 uut_bram_00_08(
    .B1DATA(sig_bram_00_08_B1DATA),
    .B1ADDR(sig_bram_00_08_B1ADDR),
    .A1DATA(sig_bram_00_08_A1DATA),
    .A1ADDR(sig_bram_00_08_A1ADDR),
    .CLK1(sig_bram_00_08_CLK1)
);

task bram_00_08_reset;
begin
    sig_bram_00_08_A1ADDR <= #2 0;
    sig_bram_00_08_A1DATA <= #4 0;
    sig_bram_00_08_B1ADDR <= #6 0;
    sig_bram_00_08_CLK1 <= #8 0;
    #100; sig_bram_00_08_CLK1 <= 1;
    #100; sig_bram_00_08_CLK1 <= 0;
    sig_bram_00_08_A1ADDR <= #2 ~0;
    sig_bram_00_08_A1DATA <= #4 ~0;
    sig_bram_00_08_B1ADDR <= #6 ~0;
    #100; sig_bram_00_08_CLK1 <= 1;
    #100; sig_bram_00_08_CLK1 <= 0;
end
endtask

task bram_00_08_update_data;
begin
    xorshift128;
    sig_bram_00_08_A1ADDR <= #2 { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };
    xorshift128;
    sig_bram_00_08_A1DATA <= #4 { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };
    xorshift128;
    sig_bram_00_08_B1ADDR <= #6 { xorshift128_x, xorshift128_y, xorshift128_z, xorshift128_w };
end
endtask

task bram_00_08_update_clock;
begin
    xorshift128;
    { sig_bram_00_08_CLK1 } = { sig_bram_00_08_CLK1 } ^ (1'b1 << (xorshift128_w % 2));
end
endtask

task bram_00_08_print_status;
begin
    $display("#OUT# %b %b %b %t %d", { sig_bram_00_08_A1ADDR, sig_bram_00_08_A1DATA, sig_bram_00_08_B1ADDR }, { sig_bram_00_08_CLK1 }, { sig_bram_00_08_B1DATA }, $time, i);
end
endtask

task bram_00_08_print_header;
begin
    $display("#OUT#");
    $display("#OUT#   A   sig_bram_00_08_A1ADDR");
    $display("#OUT#   B   sig_bram_00_08_A1DATA");
    $display("#OUT#   C   sig_bram_00_08_B1ADDR");
    $display("#OUT#   D   sig_bram_00_08_CLK1");
    $display("#OUT#   E   sig_bram_00_08_B1DATA");
    $display("#OUT#");
    $display("#OUT# A/--BC D /--E");
end
endtask

task bram_00_08_test;
begin
    $display("#OUT#\n#OUT# ==== bram_00_08 ====");
    bram_00_08_reset;
    for (i=0; i<1000; i=i+1) begin
        if (i % 20 == 0) bram_00_08_print_header;
        #100; bram_00_08_update_data;
        #100; bram_00_08_update_clock;
        #100; bram_00_08_print_status;
    end
end
endtask

initial begin
    // $dumpfile("testbench.vcd");
    // $dumpvars(0, testbench);
    bram_00_08_test;
    $finish;
end

endmodule

Thank you for a nice tool!

Icarus Verilog creates huge in-memory arrays for shifts with large rhs

Icarus Verilog allocates 16 GB of memory when processing the following statement:

module issue_023;
  localparam [4:0] p = 1'b1 << ~30'b0;
endmodule

Adding another 10 bits to the RHS triggers an assert: ivl: verinum.cc:370:
verinum::V verinum::set(unsigned int, verinum::V): Assertion 'idx < nbits_'
failed:

module issue_023;
  localparam [4:0] p = 1'b1 << ~40'b0;
endmodule

please add a simple option for dumping *all* arrays in a design

As far as I can tell, the current method of dumping arrays is to dump them element-by-element. This is not sufficient for several use cases.

  1. In a design with deep hierarchy with arrays at several levels of hierarchy, the amount of boilerplate required to dump out everything can quickly get out of control.
  2. In a design with parameterized, 2-d arrays, it is simply not possible to loop over both indices of the array. This causes a run time error.

3. In a design with vectors of instances, where each instance contains an array, it is not possible to write a nested loop over the vector of instances and the array indices. This causes a compile time error.

I have provided test cases and error outputs below.

Probably (2) and (3) should be fixed or documented; but even if this is fixed, a commandline switch that causes all arrays to be dumped by default seems to me like a near necessity for any sufficiently complex project that uses arrays.

(Edit to note that (3) is not an Icarus issue, it's a requirement of the language semantics, as @martinwhitaker points out below.)

synthesis translate_{off,on} inside behavioral code

The following module

module test(output reg [7:0] y);
  initial begin
    // synthesis translate_off
    y <= 42;
    // synthesis translate_on
  end
endmodule

results in the following syntax error (iverilog git 0f294cb):

test.v:3: syntax error
test.v:3: Syntax in assignment statement l-value.
test.v:4: syntax error

I'm not sure if there is any kind of formal definition for the synthesis translate_off / synthesis translate_on comments, but the lattice lm32 CPU is using them inside behavioral code like in my example.

module Input ports are unconnected...

Hello,
I was trying to dump a netlist from
a modified 'ivtest/blif/blif01c.v'.
As it turns out, the inputs to the module
are disconnected and get replaced by a 5'b0zzzz...
(in the netlist and blif output)
Am I doing something wrong invoking the module
or is it a bug?
(it does not seem to happen with the other, structural adder(..01a.v))

This is the snippet I used:

module addN
   #(parameter WID = 4)
    (input wire [WID-1:0] A,
     input wire [WID-1:0] B,
     output wire [WID:0]  Q
     /* */);

    assign Q = A + B;

endmodule // add

module top;

    parameter WID = 4;
    (* PAD="2,3,4,5"*)
    wire [WID-1:0] A;
    (* PAD="6,7,8,9"*)
    wire [WID-1:0] B;
    (* PAD="14,15,16,17,18"*)
    wire [WID:0]  Q;

    addN #(.WID(WID)) usum (.A(A), .B(B), .Q(Q));


endmodule

compiled using:
iverilog -tblif -N./t.net ./atf01c.v

I'm getting:

ELABORATED NODES:
Adder (NetAddSub): _s9 width=5 pin_count=4
     0 Cout   O (strong0 strong1):.
     1 DataA  I (strong0 strong1): 0x8ba8448 top.usum._s0
     2 DataB  I (strong0 strong1): 0x8ba90c8 top.usum._s4
     3 Result O (strong0 strong1): 0x8ba9258 top.Q
     LPM_Direction = ""ADD""
constant 5'b0zzzz: _s1 #(.,.,.)
     0 pin0 O (strong0 strong1): 0x8ba8448 top.usum._s0
constant 5'b0zzzz: _s5 #(.,.,.)
     0 pin0 O (strong0 strong1): 0x8ba90c8 top.usum._s4

It happens with version currently on github...

BTW: I tried posting on iverilog-devel, but it bounced...

Problem with multi-dimensional arrays

Consider the following test bench:

module tb;
    reg [3:0] mem [0:15] [0:15];

    task cycle;
        input [3:0] a, b, c;
        reg [3:0] tmp;
        begin
            #10; tmp <= mem[a][b];
            #10; mem[a][b] <= c;
            #10; $display("a=%d, b=%d, c=%d -> old=%d, new=%d", a, b, c, tmp, mem[a][b]);
        end
    endtask

    integer i, j, k;
    initial begin
        cycle( 7, 0, 1);
        cycle(15, 0, 2);
        cycle( 7, 0, 3);
        cycle(15, 0, 4);
    end
endmodule

The expected output would be (tested with xsim 2014.2 and modelsim 10.1d):

a= 7, b= 0, c= 1 -> old= x, new= 1
a=15, b= 0, c= 2 -> old= x, new= 2
a= 7, b= 0, c= 3 -> old= 1, new= 3
a=15, b= 0, c= 4 -> old= 2, new= 4

However, with iverilog (rev c7a3672) I get the following output (difference in the "old" column):

a= 7, b= 0, c= 1 -> old= x, new= 1
a=15, b= 0, c= 2 -> old= 1, new= 2
a= 7, b= 0, c= 3 -> old= 2, new= 3
a=15, b= 0, c= 4 -> old= 3, new= 4

Looks like the MSB of 'a' is not used when addressing elements of 'mem'.

Undef propagation in power operator

icarus verilog (git d1c9dd5) does not correctly propagate undef thru power operator. For example, y should be 4'bx when a is zero in the following test case, but iverilog returns 4'd1:

module issue_012(a, y);
  input [3:0] a;
  output [3:0] y;
  assign y = 4'd2 ** (4'd1/a);
endmodule

PS: In case anyone is wondering: I find this bugs using VlogHammer (http://www.clifford.at/yosys/vloghammer.html).

vvp asserts on reduce of one-bit .arith/sub

The following module builds fine with iverilog (ivl) but triggers an assert in vvp:

module issue_011(a, y);
  input [0:0] a;
  output [0:0] y;
  assign y  = |(-a);
endmodule

The error I get is:

Internal error: Input vector expected width=1, got bit=2'b00, base=0, vwid=2
vvp: vvp_net_sig.cc:896: virtual vvp_net_fil_t::prop_t vvp_wire_vec4::filter_vec4(const vvp_vector4_t&, vvp_vector4_t&, unsigned int, unsigned int): Assertion `bits4_.size() == vwid' failed.

Another assert for invalid input

Iverilog 6547fde triggers an assert on the following (invalid) code:

module tb;
  wire [3:0] a, y;
  test uut (.a(a), .y(y));
endmodule

module test(a, b, y);
  input [3:0] a;
  output [3:0] y;
  assign y = a;
endmodule

The output I get is:

test.v:6: error: Port b (2) of module test is not declared within module.
ivl: elaborate.cc:1310: void PGModule::elaborate_mod_(Design*, Module*, NetScope*) const: Assertion `tmp' failed.

Simple class usage

I'm trying to use classes on latest trunk, and the following simple code isn't compiling:

program test;

  class a;
    function new(string str);
      $display(str);
    endfunction
  endclass // a

  initial begin
    a m_a;
    m_a = new("hello world");
    $finish();
  end

endprogram

The compilation output is:

testbench:10: syntax error
testbench:10: error: malformed statement

How to flush output to stdout with vvp?

I notice that when I run vvp, all my $display output gets flushed to the screen at the end of the run, and not while the run is going. Is there a way to get the results flushed to stdout sooner? VCS simulator has an option that does this called +vcs+flush+all

Here is my testcase:

module t; 
  reg [255:0] number;
  reg [255:0] i;
  initial begin
    $display("hi");
    number = 1;
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
    #1;
    for (i = 1; i < 1000000; i = i+1) begin
      number = number + i;
      #1;
    end
    $display("%032h", number);
  end
endmodule

Another "size of unsized constant" bug

Hello,

consider the following test case:

module test;
  wire [5:0] a;
  wire [15:0] y;
  assign a = ~0, y = 1 ? ~a >>> 5 : 0;
  initial #10 $display("%b", y);
endmodule

the output should be "1111111111111110", but iverilog prints "0000011111111110". The problem is of course that the "0" on the right hand of the ?: expression does not force the expression to be at least 32 bits, as requested by the IEEE Std.

Running iverilog with -gstrict-expr-width does not change the observed behavior.

Syntax error on operator attributes.

According to syntax A.8.3 of IEEE Std. 1364-2005 an attribute can be placed directly after an unary operator, binary operator, or the ? in the ?: operator. So the following is valid Verilog code:

module test(input [3:0] a, b, output [3:0] y1, y2, y3);
    assign y1 = - (* foo = "bar" *) a;
    assign y2 = a + (* foobar = 42 *) b;
    assign y3 = a == b ? (* foobar *) y1 : y2;
endmodule

Icarus Verilog creates a syntax error for each of the three assignments.

Concatenation seemingly not using full width

See http://stackoverflow.com/q/14460685/309483

module main();
wire [31:0] a = 32'b0;
wire [25:0] a_man = {1'b1, a[24:0]};
initial begin
$display("%b\n%b\n%b", {1'b1,a[24:0]}, a_man[25:0], a_man);
end
endmodule

Actual output:

10000000000000000000000000
1xxxxxxxxxxxxxxxxxxxxxxxxx
1xxxxxxxxxxxxxxxxxxxxxxxxx

Expected output:

10000000000000000000000000
10000000000000000000000000
10000000000000000000000000

Version: 0.9.6

failed assertion rval.len() == wid in eval_tree.cc:1029:

The code below triggers the following assert in iverilog ccce9d9: test.v:2: assert: eval_tree.cc:1029: failed assertion rval.len() == wid

module demo(output [3:0] y);
assign y = 1 * (1 ? (1.0 * 0) : 0);
endmodule

(Notice the real value 1.0 in the middle of the expression.)

assert on invalid verilog input

The following (invalid) input triggers an assert. It would be nice if it could print an error message instead:

module TEST_MEM (
    input        WCLK,
    input [15:0] WDATA
);
    reg [15:0] memory;
    always @(posedge WCLK)
        memory <= WDATA[0][3:0];
endmodule

The assert is: test.v:7: assert: elab_expr.cc:4696: failed assertion prefix_indices.size()+1 == net->sig()->packed_dims().size()

VPI: update

Disclaimer: I do not know internals of simulator or vpi. Possibly doing something wrong.

Test files can be found here:
https://gist.github.com/themperek/4f0053269c7c7838041f

Output:

B0 = zz B1 = 01 @ 0
B0 = zz B1 = zz @ 1000
B0 = zz B1 = 01 @ 2000

In first order B1 and B0 should be same. There some difference how assign is handled.

The original problem comes from using cocotb.
The workaround (see comments):
https://github.com/SiLab-Bonn/basil/blob/master/device/modules/utils/bus_to_ip.v#L37
https://github.com/SiLab-Bonn/basil/blob/master/host/basil/utils/sim/SiLibUsbBusDriver.py#L146

PS. The unit test using icarus run pretty nice on travis: https://travis-ci.org/SiLab-Bonn/basil

Version number is incorrect when build from source.

When the lastest git source is build and installed the version string and copyright dates are incorrect. There is a reference in version_base.h to version_base.in which no longer exists.

$ vvp -V
Icarus Verilog runtime version 0.10.0 (devel) (s20121218-432-g065c485)

Copyright 1998-2012 Stephen Williams
...

I'm willing to submit a patch for the issue if given a definition of the expected result. It looks like the string is:
Icarus Verilog runtime version x.y.z (devel) (sYYYYMMDD-{commit count}-{git commit short hash})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.