Getting Started
A Basic Verilog testbench
Before introducing Verilator let`s first describe a simple testbench with Verilog.
In a new file src/hello_tb.v enter the following:
module hello_tb;
reg clk;
parameter N_CYCLES = 20;
parameter PULSE_WIDTH = 5;
integer j;
initial begin
clk <= 0;
for (j=0; j<N_CYCLES; j = j + 1)
#PULSE_WIDTH clk <= ~clk;
end
always @(posedge clk) begin
$display("tick");
end
endmoduleThis module only drives a clock signal which can be used to test a digital system. You can compile and run this module with iverilog for example:
You should see the following output:
The system under test is very simple as our main focus at this stage is to study how parts of this setup can be written with C++.
Building Systems with Verilator
The example above uses the square symbol (#) to implement pulses. Verilog code that shall be translated to C++ (or "verilated" code) would not be able to process these delays in Verilog. Therefore let's remove the clock generator from Verilog. It will be addressed later in C++.
To make the system under test a bit more interesting, we can add a counting action: To track the variables with digital waveforms, the Verilog dumpfile and dumpvar tasks are inserted. The resulting module is:
The next step is to setup the C++ code that drives this device under test (or DUT).
In Verilator, clocks can be generated with C++ or with SystemC. One possiblity to drive the module is as follows:
To compile with SystemC and C++, we can use CMake with this CMakeLists.txt build definition:
Now compile all with:
You should be able to run the example and see:
Besides the console output of clock ticks, you should have a waveform file which can be loaded with gitkwave:
You should be able to see 20 clock cycles and the resulting count value.
A counter varation
We can make the system under test a bit more interesting. First instead of having all structures defined in one module (which is unlikely in a real project), you can add a top module as follows:
You see already that we added a new signal to control the module reset. Also the top module can be a good place to define conditiions on when to finish the simulation.
This reset could be driven from the testbench as follows
Last updated
Was this helpful?