Verilog Include files with ModelSim

I am currently using ModelSim to verify some hardware modules for my term project, and I have developed some tasks and macros that are useful when working with SRAM modules.  I decided to put these in a separate file from my testbench code, and then have the testbench code use the `include verilog macro to include these tasks in the testbench.  This has two advantages:

  1. The tasks and macros can be shared and used in other testbenches
  2. The testbench code is significantly easier to read

For those not familiar with the `include macro, from section 19.5 of the IEEE1394-2001 Verilog Language Reference Manual,

The file inclusion (`include) compiler directive is used to insert the entire contents of a source file in another file during compilation. The result is as though the contents of the included source filea ppear in place of the `include compiler directive.

Please note that you can also use `ifndef/`define/`endif macros, just as you would with C/C++ header files, to prevent compiler issues due to multiple inclusions of the included file.  Also like C/C++ compilers, ModemSim’s verilog compiler looks in the current directory for included files.  Any files not in the current directory will not be found by the compiler, as shown below.

> vlog testbench/sram_tb.v
# Model Technology ModelSim PE Student Edition vlog 10.0a Compiler 2011.02 Feb 20 2011
# — Compiling module sram_tb
# ** Error: testbench/sram_tb.v(120): Cannot find `include file “sram_tb_util.v” in directories:
#     C:/Modeltech_pe_edu_10.0a/ovm-2.1.1/../verilog_src/ovm-2.1.1/src, C:/Modeltech_pe_edu_10.0a/uvm-1.0/../verilog_src/uvm-1.0/src
# C:/Modeltech_pe_edu_10.0a/win32pe_edu/vlog failed.

There are two ways to specify the include path.  The first method is to pass the incdir option to the vlog command.  The command below tells the verilog compiler to look in the testbench directory for any files included in the sram_tb.v file.

vlog testbench/sram_tb.v +incdir+./testbench

The other way is to use the GUI to set the include directories for project.  Right-click on any verilog source file in the Project View, and select “Properties…”.  In the dialog box that appears, select the Verilog & System Verilog tab, and use the “Include directories…” button to add paths to include directories.

Whenever you compile your verilog source files, the paths specified in the include directories will be searched when the `include macro is encountered in your source files. Please note that this only works when you compile with the GUI compile button.  Users who prefer to use the command shell in the GUI –like myself–will still have to add the +incdir+ option to the vlog command.  I suppose the designers of ModelSim are encouraging us to write Tcl build scripts…

Advertisements

GNU Verilog

I started my graduate studies in electrical engineering on this past Monday.  I am taking a course in ASIC design which I have always wanted to learn more about.  In the course we will be using the Verilog HDL language, and we will be using expensive industry standard tools, including  ModelSim for simulation and Synopsis for synthesis.  I do not always have access to ModelSim and I was looking for a simple way to test some verilog without having to use the university’s machines.  I stumbled upon the GNU Icaraus Verilog compiler and GtkWave.  Like all GNU tools, they are available free of charge and are of rather good quality in my opinion.  I created a basic tutorial for getting started with these tools using a simple D flip-flop.

Before getting started, one must install the ‘verilog’ and ‘gtkwave’ packages, corresponding to Icarus Verilog and GtkWave.  I found the packages available for OpenSuSE, and I am sure they are also available for other distributions too.  The brave can alawys build from the source if no package exists.

Lets get started.  Below is the verilog model for a simple D flip-flop with a synchronous reset.

// dff.v
module dff(d,q,clock,reset);
input wire clock;
input wire reset;
input wire d;
output reg q;

always @(posedge clock)
begin
if (clock) begin
if (reset) begin
q <= 1’b0;
end
else begin
q <= d;
end
end
end

Below is a basic test bench with a 20 ns clock period that toggles the flip-flop input a few times.

// dff_tb.v
`timescale 1ns/1ps
module dff_tb;
parameter CLK_PERIOD = 20;
reg clock, reset, d;
wire q;

dff d0(
.d(d),
.q(q),
.reset(reset),
.clock(clock)
);

initial begin
$dumpfile(“dff_tb.vcd”);
$dumpvars(1, dff_tb);
$monitor(“clock=%b, d=%b, q=%b”, clock, d, q);
clock = 1’b1;
reset = 1’b1;
d = 1’b0;
#(CLK_PERIOD*5)
reset = 1’b0;
#CLK_PERIOD
d = 1’b1;
#CLK_PERIOD
d = 1’b0;
#CLK_PERIOD
d = 1’b1;
#CLK_PERIOD
d = 1’b0;
#CLK_PERIOD
$finish;
end

always #(CLK_PERIOD/2) clock = ~clock;

endmodule

The test bench is written such that the changes in the signals are dumped to a Value Change Dump (VCD) file, using the $dumpfile and $dumpvars system commands.  The state of the variables is also printed to the terminal using the $monitor system command. Now that the D flip-flop module and a test bench are ready, we need to compile the verilog and run the simulator.

iverilog -o dff dff.v dff_tb.v  # compiles the modules into a “dff” project
vvp dff                                           # runs the simulation on the project
gtkwave -f dff_tb.vcd              # graphically view the simulation output

Selecting the dff_tb in the upper lefthand box, add each of the four signals using the “insert” button.  The time scale will probably set set in the picoseconds, so zoom out until you are at a suitable scale to view the waveforms.  This can all probably be done on the command line, but I have not looked into it yet.

As you can see, with two very simple packages it is easy to get started modeling with Verilog–with no cost at all.  Synthesis, on the other hand…