In a simple SystemVerilog fork join
, the main thread waits until all the child threads have finished execution. This means the fork will hang the simulation if any of the child threads run forever and never complete. SystemVerilog also provides a variation to the original with a fork
and join_any
.
A fork
and join_any
will allow the main thread to resume execution of further statements that lie after the fork, if any one of the child threads complete. If five threads are launched, the main thread will resume execution only when any one of the five threads finish execution. Once the main thread resumes operation, the remaining four threads that were launched will continue to run in the background.
Syntax
fork
// Thread 1
// Thread 2
// ...
// Thread N
join_any
fork join_any Example
module tb;
initial begin
$display ("[%0t] Main Thread: Fork join going to start", $time);
fork
print (20, "Thread1_0");
print (30, "Thread1_1");
print (10, "Thread2");
join_any
$display ("[%0t] Main Thread: Fork join has finished", $time);
end
// Note that this task needs to be automatic
task automatic print (int _time, string t_name);
#(_time) $display ("[%0t] %s", $time, t_name);
endtask
endmodule
Simulation Log
ncsim> run [0] Main Thread: Fork join going to start [10] Thread2 [10] Main Thread: Fork join has finished [20] Thread1_0 [30] Thread1_1 ncsim: *W,RNQUIE: Simulation is complete.
Nested fork join_any
module tb;
initial begin
$display ("[%0t] Main Thread: Fork join going to start", $time);
fork
fork
print (20, "Thread1_0");
print (30, "Thread1_1");
join_any
print (10, "Thread2");
join_any
$display ("[%0t] Main Thread: Fork join has finished", $time);
end
// Note that this task has to be automatic
task automatic print (int _time, string t_name);
#(_time) $display ("[%0t] %s", $time, t_name);
endtask
endmodule
Simulation Log
ncsim> run [0] Main Thread: Fork join going to start [10] Thread2 [10] Main Thread: Fork join has finished [20] Thread1_0 [30] Thread1_1 ncsim: *W,RNQUIE: Simulation is complete. ncsim> exit