This page describes a cpp bench, which is used to verify a parallel fifo, using
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.
-
This cpp bench is based on parallel fifo.
Both cases are used as simple exercises to gain some experience with
verilator.
The stimuli drive is done differently. Instead of dot notation access
gen(entry);
pipe_fifo->rd = entry.rd;
pipe_fifo->wr = entry.wr;
a DPI task is used.
gen(entry);
//drive using c2v DPI function
t_gen_stim(entry.rd, entry.wr);
-
The DUT (parallel FIFO) is now instantiated under a system verilog tool. The
tool gets its clock and reset in the usual way from verilator. The read
write commands are now driven by a task:
...
initial begin
Trd=1'b0;
Twr=1'b0;
end
export "DPI-C" task t_gen_stim;
task t_gen_stim;
input bit trd;
input bit twr;
$display("task drive %d %d at %d", trd, twr, $time);
Trd=trd;
Twr=twr;
endtask
reg Trd, Twr;
...
-
To monitor a signal change the opposite is required. SV checks the error flag (
always block), when it changes, it sends data to cpp via DPI.
//monitor fifo errors v2c DPI function
import "DPI-C" function integer f_ferr(integer ferr);
...
always @ (posedge clk) begin
ferrq <= ferr;
if(ferrq != ferr) begin
$display("sv mon ferr %d at %d %d", ferr, ferrq, $time);
f_ferr(ferr);
end
end
In the cpp bench:
- int f_ferr(int ferr) {
- cout << "sim gen ferr " << ferr << " time is " << main_time << endl; // Read a output
- }
- int main(int argc, char** argv) {
- ...
A word about seed. I use rand() to randomize write and read access. The seed is either taken from
command line, or a random one is used:
- void gen(Entry& entry) {
- static int fifo_level;
- entry.rd=0;
- entry.wr=0;
- if(entry.ti >= (41+delta)) {
- if(entry.fe == 1 && fifo_level > 0) entry.rd=rand() % 2;
- if(entry.ff == 0 && fifo_level < 4) entry.wr=rand() % 2;
- }
- ...
- int main(int argc, char** argv) {
- unsigned int c_seed;
- if(argc == 1) {
- c_seed=time(NULL);
- }
- else {
- c_seed=atoi(argv[1]);
- cout << "sim seed is NOT random !!!!" << endl;
- }
- srand (c_seed);
- cout << "sim seed is " << c_seed << endl;
- ...
-
The compile and run script had be changed too
- #!/bin/bash
- if [ -e obj_dir/Vpipe_fifo_tool ] ; then
- rm obj_dir/Vpipe_fifo_tool
- fi
- #--debug -CFLAGS -g
- clear;verilator -CFLAGS -g --trace --trace-depth 2 -sv --cc pipe_fifo_tool.sv --exe sim_main.cpp
- cd obj_dir
- make -j -f Vpipe_fifo_tool.mk Vpipe_fifo_tool && echo "make ended ok"
|