I have the following scenario for an ALU SV testbench where I have a fork-join inside a forever:
task run();
forever
begin
fork
// f1
begin
alu_agent_h.alu_driver_h.drive(); // this call the a driver task which is responsible to drive the values from generator to ALU DUT interface
end
// f2
begin
alu_agent_h.alu_monitor_h.monitor_in; // used to monitor and store the DUT interface inputs.
end
// f3
begin
alu_agent_h.alu_monitor_h.monitor_out; // used to monitor and store the DUT interface outputs as actual values.
end
// f4
begin
alu_ref_mdl_h.alu_expect(); // a reference model used to produce the expected value for ALU DUT
end
// f5
begin
alu_scoreboard_h.compare(); // compare the expected with actual data in scoreboard class
end
join
end
endtask
This code can only work if I used a fork-join but when I try to replace the join with join_any or join_none the simulation fails. What could the be the reason why I can’t use join_any or join_none with this case?
When you replace the fork/join with a fork/jone_none, you get into a zero-delay forever loop with an infinite number of processes being spawned.
When you replace the fork/join with a fork/jone_any, you get into a zero-delay forever loop with an infinite number of processes being spawned if any of the forks is a function consuming zero time.
forever is a procedural statement that executes its accompanying procedural statement once, and when completes, it executes it again and again.
The accompanying statement must have some procedural blocking delay, otherwise you get into an infinite 0 delay loop and the simulation will hang.
That accompanying statement could be a single procedural statement, or a group of statements contained by a begin/end, or fork/join/join_any/join_none. Both begin/end and fork/join have the potential to be blocking statements if any of their statements have a blocking delay. The only difference between the latter two are begin/end execute their statements sequentially, whereas fork/join execute their statements in parallel.
Inside a forever loop in either of those two cases, if none of the contained statements are blocking, you get into an infinite 0 delay loop and the simulation will hang. A fork/join_none is always non-blocking. A fork/join_any is non-blocking if any one of its statements is non-blocking.