Getting started with Icarus Verilog on Windows

Icarus Verilog is a Verilog standard IEEE-1364 compiler that targets Linux but works almost as well on Windows. It's lightweight, free software and includes a virtual machine that simulates the design. This tutorial goes through the process of downloading, installing and using Icarus Verilog to write a simple program, compile it, simulate it and view the simulation results on a timing diagram. It assumes no previous knowledge on Verilog, but prior programming experience is recommended.

Installing Icarus Verilog

Download Icarus Verilog latest stable release for Windows from: bleyer.org/icarus

Installing Icarus Verilog is as easy as installing any other Windows program. Just hit next, but be sure to select GTK Wave (full installation) and "Add Executables to Windows Path" option. You should be able to use it from a Command Prompt by now. On Windows Vista/7/8 press Windows key and type cmd to open a command prompt. Just type "iverilog" and you should get a message saying "iverilog: no source files" and some instructions. Type "gtkwave" and the GTKWave GUI should open. This program is used to view the simulation results graphically on a timing diagram.

If these commands are not recognized but the installation was successful chances are the executables were not added to Windows Path. See How to set the Path on Windows to add "C:\iverilog\bin" to Path manually.

Writing a simple program

Now you are ready to write your first Verilog program. For this tutorial we'll write a D type flip-flop description, that is, a Verilog module that works like a D flip-flop. At the same time you'll learn some of the basic Verilog concepts by example.  You'll also write a tester module to reproduce the following D flip-flop timing diagram:

D type flip-flop timing diagram

Verilog programs are separated in modules, which are functional blocks that have inputs, outputs and internal logic. You can think of them like the blocks on a circuit's block diagram, but in this case they work. There are two types of Verilog modules: behavioral modules and structural modules. Both may have the same behaviour but are different in the way they are written as you'll see throughout the example.

For the flip-flop program three modules are used: the flip-flop module, tester module and testbench module. The last two are modules you'll need on almost every design in order to test your circuit.

Flip-flop module

Represents a simple D type flip-flop. Receives a clock signal and D signal as inputs and outputs Q and QN signals. The outputs may change on the positive clock edge. The code for this module is:

//dff modules represents a D type flip-flop
module dff(d,clk,q,qn);
	input d,clk;
	output q,qn;
	reg q,qn;

	//Initialize flip-flop outputs
	initial begin q=0; qn=1; end

	//Change output on positive clock edge
	always @(posedge clk) 
	begin
		q <= d;
		qn <= !d;
	end
endmodule

From this code, you can see the basic structure of every Verilog module. It starts with a declaration: module dff(d,clk,q,qn); and ends with endmodule. The declaration states the module's name and both its inputs and outputs. In the module we must declare which variables are inputs and which are outputs, using "input" and "output".

Variables in Verilog are wires or regs. A wire, like a real wire, has no memory. Thus Verilog wire variables do not retain their values by themselves. The reg keyword gives variables the ability to hold their values after they are assigned, until their value is changed, of course. We want this behaviour for the flip-flop's outputs so q and qn are defined as regs. If we use a wire the output is never seen by other blocks. It loses its value immediatly after any assignment. There is no need to define variables as wires, because they are all wires by default.

The way the inner logic of the module is written deppends on wether it is behavioral or structural. The flip-flop module is an example of behavioral code. That is, you describe the behavior the module should have. To do it, use initial and always blocks. The code within an initial block is executed once, when the flip-flop is created. In the example it's used to define q=0 and qn=1 initially. By default in Verilog the variables are undefined (represented by an "x"), not zero, not one. If we did'nt use this initial block q and qn would be left undefined until they are assigned for the first time.

The code within an always block is executed when a condition is met. In this case, when the clock has a positive edge, q and qn are reassigned. This describes completely the flip-flop's logic. As you can see, it is simple. When the condition is not met, Verilog keeps the outputs' values.

As a rule of thumb, when writing a behavioral module, define outputs as wires.

Verilog has control structures like while, if-else, case, for and repeat (similar to for) like most programming languages. These assist you on writting your behavioral code. For example, replacing the flip-flop module's always block by:

always @(clk) 
	begin
		if(clk == 1)
		begin
			q <= d;
			qn <= !d;
		end
	end

produces exactly the same behaviour. Some things changed. Now the always condition is always @(clk) instead of always @(posedge clk) . This means that now the always block is executed every time clk changes its value, on positive and negative edges. An always block can be triggered by any number of variables. For example, @(clk or d) would trigger it whenever clk or d change. This is used in combinational logic where the output is recalculated whenever an input changes. Back to the example, if clk == 1 then the edge is positive. We check it using an if statement. Note that adding the "begin" and "end" keywords is necessary when any block (always, initial, if, for...) has more than one instruction. If omitted for the "if" statement above the second instruction: qn <= !d; would be executed always (it would be ouside of the if statement). These two keywords act like the curly brackets on many programming languages.

Tester module

This module tests the flip-flop by generating the clock and D signal of the timing diagram above and dumping the Q and QN signals of the flip-flop. It's outputs are the flip-flop's inputs and viceversa.

//Tester module sends a periodic clock signal to the flip-flop
module tester(q,qn,clk,d);
	input q,qn;
	output clk,d;
	reg clk,d;

	//Run the test once
	initial
	begin
		clk=0;
		//Dump results of the simulation to ff.cvd
		$dumpfile("dff.vcd");
		$dumpvars;
		//Generate input signal d
		   d=0; #9 d=1; #1 d=0; #1 d=1; #2 d=0; #1 d=1; #12 d=0;
		#1 d=1; #2 d=0; #1 d=1; #1 d=0; #1 d=1; #1 d=0; # 7 d=1;
		#8 $finish;
	end

	//Generate periodic clock signal
	always
	begin
		#4 clk=!clk;
	end
endmodule

This module is behavioral too as we have initial and always blocks. You should be able to undestand most of the code. However, there are a few new concepts here. The $dumpfile and $dumpvars commands tell the Verilog simulator (more on this ahead) to log the module's variables to the specified file, "dff.vcd" in this case. You may also be wondering what the #s do. These are Verilog delays. The delay the following instruction by a given amount of time. For example, #4 clk=!clk; within an always block changes "clk" every four time units from 0 to 1, producing a square wave. The time unit is a second by default.

Without using delays there is no way of making the program work. This is the way to control time in the design. You may add delays to any instruction. For example, you could model the flip-flop's delay by adding some to its always block. It's now easy to understand how the d=0; #9 d=1; #1 d=0; #1 d=1; ... lines produce the D signal we want.

Finally, the $finish command tells the simulator to stop the simulation once the D signal was generated. If this command was omitted the simulation would continue indefinetly because this time the always block has no condition (there is no @ like in the flip-flop module).

Testbench module

This module just connects the tester module to the flip-flop module:

//Test bench connects the flip-flop to the tester module
module testbench;
	wire clk,d,q,qn;
	dff ff1(d,clk,q,qn);
	tester tst1(q,qn,clk,d);
endmodule

It is the most simple of the modules, but it's very different. This time it's structural code, that is, you define the structure of the circuit. It's like describing the circuit diagram. In this case the final circuit is simply the flip-flop connected to the tester. To create a flip flop use dff ff1(d,clk,q,qn);. First goes the module name, followed by the part name, which could be almost any string, followed by the wires that connect to the module in parenthesis. These must follow the order in the module's declaration. In a structural module we use wires. Regs are not necessary because they are defined inside the different modules.

Compiling and simulating

Go ahead and copy/paste the modules into a text file, order doesn't matter. Call the file "dff.v". The .v extension is standard for Verilog files, but isn't required by the compiler. To compile open a Command Prompt at your working directory (where you saved the file). A quick way to open a command prompt at any directory is to hold shift and right-click the folder, then click "Open Command Window Here". Type:

iverilog -o dff dff.v

The "-o" tells Icarus Verilog to "save output to the following file". The output is then saved to "dff". This file is not executable. It has to be run using vvp, the Icarus Verilog simulator which is the one that actually produces simulation results, zeros and ones for each of the model variables, as a function of time. To run the simulation type:

vvp dff

This is what outputs the dff.vcd file with all the simulation results. However if you open this file with your text editor you'll see it's not easy to understand. To generate an easy-to-understand timing diagram from this file we use GTKWave.

GTKWave does have a GUI. To open it press Windows key and type "gtkwave". Then click File -> Open New Tab and chose the ffd.vcd file. Now you must add the variables in order to see their timing diagram. Click on "testbench" at the left (SST panel) and then select all the variables using Ctrl or Shift and "Insert" them.

If everything is okay you should get a timing diagram exactly as the one at the beggining of the tutorial, just like the following:

Icarus Verilog simulation results shown using GTKWave

When testing your programs you'll have to go to the compiling-simulating-loading process every few minutes. Remember you can use the up-down arrow keys while in the command prompt to access the last commands and compile/simulate. On GTKWave use File->Reload Waveform to reload the .vcd file and refresh the timing diagrams without having to reload each variable. By using these tips the whole proccess will take you a few seconds.

It's over. Now feel free to change the code around to see what happens. Mastering the use of delays, wires and regs takes some time. See Verilog in One Day for a more in depth explanation of the language.

32 comments

  1. This was actually a very useful tutorial, but you sort of lost it at the end.

    You need to include the tester and the dff in the top level test bench:

    `include "dff_tester.v"
    `include "dff.v"

    then you invoke iverilog on the top level test bench, not the dff.v file. this will create the file that you then invoke vvc, then you get your sim file.

    Hope this helps everyone

    1. Hi Chris,
      I think the author intended to write all the mentioned code in a single file in the order of appearance in the post, even though he hasn't made it explicit.

    2. Chris, that is useful information for those who choose to make their tester module and testbench module as separate files. If they just include that code in one text file, as the tutorial suggests, then the vvp (not sure what you meant by "vvc") invocation can simulate the 'dff' file directly.

  2. I'm also having a problem with vvp. It runs, but never finishes and doesn't generate a vcd file. Is there another program I can use to generate it?

  3. Hi , help me please ...
    I choose my work folder , ( hold shift and right-click the folder and open cmd) , I wrote (iverilog -o dff dff.v) and I get this msg. "No such file or directory , no top level modules and no -s option " .
    What should I do ??

      1. you can run cmd at windows key, and write ''dff.v'''s address before it.
        For example, if your dff.v file's address is ''D:Desktop\cat\dff.v'',you can just input ''iverilog -o dff D:Desktop\cat\dff.v''

      2. Did you check to see what your file extension is? I was having this problem and I noticed the file was saved as 'dff.v.txt'. Make sure you just have it saved as 'dff.v'.

  4. Hi , help me please ...
    I choose my work folder , ( hold shift and right-click the folder and open cmd) , I wrote (iverilog -o dff dff.v) and I get this msg. "No such file or directory , no top level modules and no -s option " .
    What should I do ??

  5. hi I installed Verilog v9.7 (latest stable release ) I have windows 7 every time I try to compile a program it crashes with ivl.exe stopped working any ideas why this is happening. please reply as soon as you can thank you.

  6. Hi,
    I downloaded and installed the latest version, but iverilog always crashes with no output with windows message "ivl.exe has stopped working." I have it working fine on other machines with no problem. I have tried all older versions too. What is up here?

  7. I installed, but when running iverilog from cmd, I get the message: "iverilog" is not recognized as an internal or external command etc.

    1. Make sure you are in the correct directory. I installed in D drive, so I have to change the directory from default C to D, in command prompt. Also Jose mentioned how to open cmd for a specific folder " hold shift and right-click the folder".

    2. You need to append the installation folder to the Environment Variables - PATH manually.

      Go to:
      Control Panel\All Control Panel Items\System --> Advanced system Settings. Open "Environment Variables" and under "System Variables" select "PATH".

      Then append the iverilog bin installation folder to the PATH values (using a semicolon)
      ...;C:\iverlog\bin

  8. Hi,
    I was going to download verilog but there is five option in downloads and even more in the resources. Which one should I download for windows xp???
    Thanks.

    1. I installed (iverilog-20130827_setup.exe (development snapshot) [11.2MB]) but did not work at all. It only took me to a "explore folder". Not program to run.

  9. Hi I am new to verilog and iverilog. I followed the instructions here but not able to get the dff.vcd file generated. this is what I have got dff, dff.v, testbench.v, tester, tester.v

    1. Hi, the easiest way is to paste the three modules (dff, tester and testbench) to the same file (dff.v) and compile it. Then run the simulation with "vvp dff" and you should get the dff.vcd file. It looks like your modules are in separate files, so you should be able to compile them together with "iverilog -o dff dff.v tester.v testbench.v" and then run "vvp dff" to get the dff.vcd file. Hope it helps.

      1. I tried ur examples but do get "iverilog: cannot open diff.v file for reading... had set "path" of source file also..
        pls help

Leave a Reply

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>