Difficulty: Easy · Puzzle 1 of 6 · Topic: Fork Join Puzzles
Give the timeline of all prints and identify which children survive each block.
`timescale 1ns/1ns
module p1;
initial begin
fork
begin #5 $display("%0t A", $time); end
begin #10 $display("%0t B", $time); end
join
$display("%0t join_done", $time);
fork
begin #5 $display("%0t C", $time); end
begin #10 $display("%0t D", $time); end
join_any
$display("%0t join_any_done", $time);
disable fork;
fork
begin #5 $display("%0t E", $time); end
begin #10 $display("%0t F", $time); end
join_none
$display("%0t join_none_done", $time);
#1 disable fork;
end
endmoduleAnalyze each fork block independently, but remember simulation time accumulates because they execute sequentially in one initial block.
1) First block (`join`) waits for both children: A at t=5, B at t=10, then `join_done` at t=10.
2) Second block starts at t=10: C at t=15, parent resumes at `join_any` and prints `join_any_done` at t=15, then `disable fork` kills D.
3) Third block starts at t=15: `join_none_done` prints immediately at t=15, then parent waits #1 and kills both detached children at t=16 before E/F can print.Answer: A@5, B@10, join_done@10, C@15, join_any_done@15, join_none_done@15; D/E/F never print
Checked by running the code in Icarus Verilog 13 and Verilator 5; the printed output supports the answer above. Only these six lines print in this order. (Icarus, 4-state) Only these six lines print in this order. (Verilator, 2-state)
`join_none` returns at once and its children have not even started, so an immediate `disable fork` kills them before they print; and `join_any` leaves D running until you disable it.
What changes if the third block removes `#1` and calls `disable fork;` immediately? Model answer: E and F are killed at t=15 before their delays expire, so they never print either way; the only difference is that the program ends at t=15 instead of t=16 (nothing else prints after join_none_done).
I would walk the three blocks in time order, because each join type resumes the parent at a different moment. The plain join waits for both, so A at 5, B at 10 and join done at 10. The join any resumes when C prints at 15, and disable fork kills D. With join none the parent continues at once and the children have not started, so the disable fork at 16 kills them and E and F never print. The trap is thinking join none children run before the parent moves on, so I would check where each fork needs a disable fork or a wait fork.