Purpose of wait fork

Based on SystemVerilog LRM, the purpose of “wait fork” is to “blocks process execution flow until all immediate child subprocesses have completed.” My understanding is that, without wait fork, if the main process finishes, the execution will finish. I have the following code:

module wait_fork;
  initial begin
    fork
      begin
        #10;
        $display("%t thread1", $realtime);
      end
      begin
        #20;
        $display("%t thread2", $realtime);
      end
      begin
        #30;
        $display("%t thread3", $realtime);
      end
      fork
        begin
          #40;
          $display("%t thread4", $realtime);
        end
        begin
          #50;
          $display("%t thread5", $realtime);
        end
      join_none
    join_none
    [u]wait fork[/u];
  end
endmodule

This works as expected. When I comment out “wait fork”, I expect the execution will finish at 0 time because it is a join_none, main process will finish immediately. Since there is no wait fork, simulation should finish as well. But I do see all subprocesses spawned and executed. Is it expected?

Thanks!

                  10 thread1
                  20 thread2
                  30 thread3
                  40 thread4
                  50 thread5

For a module based testbench, the simulator will exit when all threads are finished, including forked threads. The ‘wait fork’ will only cause the main thread to pause execution until all the forked threads complete, then proceed.

You can put a $finish statement after ‘wait fork’ and see what the different behavior is when the main thread forces the simulation to finish.

Another differing behavior is using a program block instead of a module. In this case, simulation will end when the main thread finishes, even if the forked threads haven’t completed. We do not recommend using program blocks.