verilator
some problems in driving system verilog signals from cpp bench.
-
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.
-
When I drive input data with no delay, flip-flops in the DUT were not
simulated correctly. Their output was set immediately (no sample i.e. one cycle delay). So I decided
to put a one unit time delay, as
shown in the waves below. This still did not solve the problem
completely. Now I saw some combinatorial logic, inside the DUT, not
behaving well. Their outputs were not updated, but only after the next clock rise
edge, where it was too late. I solved
it by registering the driven signals in the system verilog bench and
then applying the registered ones to the DUT:
- initial begin
- Trd=1'b0;
- Twr=1'b0;
- end
- //monitor fifo errors v2c DPI function
- import "DPI-C" function integer f_ferr(integer ferr);
- //drive using c2v DPI function
- export "DPI-C" task t_gen_stim;
- task t_gen_stim;
- input bit trd;
- input bit twr;
- /*
- if(trd || twr)
- $display("task drive %d %d at %d", trd, twr, $time);
- */
- Trd=trd;
- Twr=twr;
- endtask
- reg Trd, Twr;
- reg qrd, qwr;
- always @ (posedge clk) begin
- qwr <= Twr;
- qrd <= Trd;
- end
- ...
- pipe_fifo u_dut (
- .clk(clk),
- .rst(rst),
- .clr(clr),
- .rd(qrd), //fifo read
- .wr(qwr), //fifo write
- ...
-
Another way round this issue was suggested by Mr Wilson Snyder:
reg Trd /*verilator public_flat_rw @(negedge clk)*/;
reg Twr /*verilator public_flat_rw @(negedge clk)*/;
When I add that your test doesn't fail. This tells
verilator when your DPI task may be changing the
signals; see the man page. Verilator uses this to
schedule the model; without such hints it assumes you
only change them when the signals would otherwise
change. (Or it would have to assume they could
change anywhere which would be very slow.)
|