So I communicate with the testbench over a socket in DPI-C, waiting on and receiving data is a blocking call. When the socket returns data, C then calls a setter function in SV, and returns from DPI-C thus unblocking SV processing.
I want to add an option to keep time “ticking”, so even if the DPI-C call is blocking, simulation time still advances (today the blocking call in DPI-C prevents simulation time from advancing).
With the following partial-code (I believe it should be sufficient) if I send the string “ticker” the command is processed, and I see printed out:
ticker
starting ticker
SystemVerilog loop over. Will now restart waiting for command
forking!
started ticker
0 - Calculating Delay from VALUE (1) and UNIT (ps)
But I expect to see that last line and Auto-Delay ticked several times, advancing time automatically and printing out the timestamp each time.
What am I doing wrong or misunderstanding?
int ticker_started = 0;
task perform_delay;
input int delay_value;
input string delay_unit;
realtime delay_scale_unit;
realtime final_delay;
$display("%t - Calculating Delay from VALUE (%0d) and UNIT (%s)", $time, delay_value, delay_unit);
case(delay_unit)
"us" : begin
delay_scale_unit = 1us;
end
"ns" : begin
delay_scale_unit = 1ns;
end
"ps" : begin
delay_scale_unit = 1ps;
end
"fs" : begin
delay_scale_unit = 1fs;
end
endcase
final_delay = delay_value * delay_scale_unit;
#(final_delay);
$display("END DELAY COMMAND");
endtask
task automatic my_ticker;
input int delay_value;
input string delay_unit;
begin
$display("started ticker");
while (1) begin
perform_delay(delay_value, delay_unit);
//#(delay_value)
$display("@%g - Auto-Delay ticked %d", $time, delay_value);
end
end
endtask
// ... inside the body of a test-sequence
while (1) begin
if (ticker_started) begin
$display("forking!");
fork
my_ticker(1, "ps");
get_commands__blocking(); // DPI-C call, which will populate the "instr" var
join_any
// the ticker should never end, but the get_commands will return once we get a new command
$display("after join_any");
// terminate all the threads
disable fork;
end else
get_commands__blocking(); // DPI-C call, which will populate the "instr" var
if (instr.substr(0,3) == "quit") begin
$display("stopping RTL simulation");
$finish;
end
else if (instr.substr(0, 5) == "ticker")) begin
$display("ticker");
if (ticker_started==0) begin
$display("starting ticker");
ticker_started = 1;
end else begin
$display("ending ticker");
ticker_started = 0;
end
end
$display("SystemVerilog loop over. Will now restart waiting for command");
end
edit: note, I previously was using forever begin but changed it (inside my_ticker) to a while(1) just to check if it had different behavior.