There is a third type of fork join in SystemVerilog which is fork
and join_none
.
A fork
and join_none
will allow the main thread to resume execution of further statements that lie after the fork regardless of whether the forked threads finish. If five threads are launched, the main thread will resume execution immediately while all the five threads remain running in the background.
Syntax
fork
// Thread 1
// Thread 2
// ...
// Thread N
join_none
fork join_none 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_none
$display ("[%0t] Main Thread: Fork join has finished", $time);
end
// Note that we need automatic task
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 [0] Main Thread: Fork join has finished [10] Thread2 [20] Thread1_0 [30] Thread1_1 ncsim: *W,RNQUIE: Simulation is complete.
Nested fork join_none
module tb;
initial begin
$display ("[%0t] Main Thread: Fork join going to start", $time);
fork
begin
fork
print (20, "Thread1_0");
print (30, "Thread1_1");
join_none
$display("[%0t] Nested fork has finished", $time);
end
print (10, "Thread2");
join_none
$display ("[%0t] Main Thread: Fork join has finished", $time);
end
// Note that we need automatic task
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 [0] Main Thread: Fork join has finished [0] Nested fork has finished [10] Thread2 [20] Thread1_0 [30] Thread1_1 ncsim: *W,RNQUIE: Simulation is complete.
Why do we need automatic task ?
Without automatic
keyword, the same display task with different string tags will produce the same display message. This is because multiple threads call the same task and share the same variable in tool simulation memory. In order for different threads to initiate different copies of the same task, automatic
keyword has to be used.
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_none
$display ("[%0t] Main Thread: Fork join has finished", $time);
end
// Note that this is not an automatic task, its static
task 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 [0] Main Thread: Fork join has finished [10] Thread2 [20] Thread2 [30] Thread2 ncsim: *W,RNQUIE: Simulation is complete.