Difficulty: Easy · Puzzle 3 of 6 · Topic: Fork Join Puzzles
Order these prints by time and explain what `wait fork` waits for.
`timescale 1ns/1ns
module p3;
initial begin
fork
#3 $display("%0t A", $time);
#7 $display("%0t B", $time);
join_none
$display("%0t parent_after_join_none", $time);
wait fork;
$display("%0t parent_after_wait_fork", $time);
end
endmodule`join_none` returns immediately, but `wait fork` blocks until all currently active children from this process finish.
1) Parent prints `parent_after_join_none` at t=0 immediately after spawning children.
2) Child A prints at t=3.
3) Child B prints at t=7.
4) `wait fork` unblocks only after both children complete, so final parent print is at t=7.Answer: parent_after_join_none@0, A@3, B@7, parent_after_wait_fork@7
Checked by running the code in Icarus Verilog 13 and Verilator 5; the printed output supports the answer above. wait fork returns only after the last child finishes. (Icarus, 4-state) wait fork returns only after the last child finishes. (Verilator, 2-state)
`wait fork` waits for ALL child processes of the calling process, not just the last one spawned, so a single child that never finishes blocks the parent forever.
What if one of the forked children is a `forever` loop? Model answer: `wait fork` never returns, the parent hangs for the rest of the simulation (run: the line after wait fork never printed, only a watchdog fired); disable that child first or use `fork ... join_any` plus `disable fork` with a timeout instead.
I would note that wait fork blocks until all children of the calling process are done, not just the last one. So the parent prints at time 0 right after the join none, child A prints at 3, child B at 7, and the parent prints again at 7. The trap is that one child that never finishes, like a forever loop, would hang the parent for good. I would check every child has an end, or add a timeout with join any and disable fork.