This page describes my second experience with
verilator.
-
In order to practice cpp (c++) verification benches, with system verilog DPI, using a
verilog DUT, I decided to download verilator
and do some self study exercises.
-
While my first example,
available on this site, is simple (one module, one initial statement), this test includes an hierarchical
Design Under Test and a time management (support for verilog $time system task as well as clock generation for the DUT)
from a cpp bench. VCD waves are generated as well, to complete this exercise.
-
There are two verilog files. The first one is the bench and is responsible for test-finish and to instantiate the DUT.
The bench implements a counter, uses it to control test end and
wires it as an input to a combinatorial DUT adder.
-
The verilog code is very simple and is shown below:
//top.v
module top(clk);
input clk;
reg [3:0] cnt;
wire [3:0] in0, in1;
wire [4:0] out;
initial begin
cnt=4'd0;
end
assign in0 = cnt;
assign in1 = cnt+ 4'd8;
always @ (posedge clk) begin
if(cnt == 4'd15) begin
$finish;
end
$display("dbg at %m cnt=%d add %d %d %d time=%d", cnt, in0, in1, out, $time);
cnt <= cnt + 4'd1;
end
adder u_add (
.in0(in0),
.in1(in1),
.out(out)
);//adder u_add
endmodule
//adder.v
module adder(in0, in1, out);
input [3:0] in0;
input [3:0] in1;
output [4:0] out;
assign out = in0 + in1;
endmodule
-
The cpp bench is shown below. It handles time and vcd dump as well as verilog
instantiation:
#include "Vtop.h"
#include "verilated.h"
//vcd traces
#include "verilated_vcd_c.h"
//cout
#include <iostream>
Vtop *top; // Instantiation of module
unsigned int main_time = 0; // Current simulation time
double sc_time_stamp () { // Called by $time in Verilog
return main_time;
}
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
top = new Vtop;
//vcd traces
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
top->trace (tfp, 99);
tfp->open ("obj_dir/simx.vcd");
while (!Verilated::gotFinish()) {
if ((main_time % 10) == 1) {
top->clk = 1; // Toggle clock
}
if ((main_time % 10) == 6) {
top->clk = 0;
}
top->eval(); // Evaluate model
//cout << "time is " << main_time << endl; // Read a output
main_time++; // Time passes...
tfp->dump (main_time);
} //while
tfp->close();
delete top;
exit(0);
}
-
To compile and run the following script is used. The script is also responsible to change
(the change is required due to some confusion in the debian installation)
the make file as described in
my first example.
- #!/bin/bash
- /usr/bin/verilator --trace --trace-depth 1 --cc top.v --exe sim_main.cpp || exit
- sed -i "s/VERILATOR_ROOT = \/usr\/bin/VERILATOR_ROOT = \/usr\/share\/verilator/" obj_dir/Vtop.mk
- cd obj_dir
- make -j -f Vtop.mk Vtop && echo "make ended ok"
|