Search code examples
verilogsystem-veriloghdl

Whether the execution order is guaranteed when the statements in fork join_any and the statements following them are executed at the same time


module test();
reg a,b,c,d;
initial begin
    fork
        #5  $display("Fork Time is %0t",$time);
        #10 $display("Fork Time is %0t",$time);
        #15 $display("Fork Time is %0t",$time);
    join_any
    #5 $display("Time is %0t",$time);
    #5 $display("Time is %0t",$time);
end
endmodule

The standard guarantees that the statements in the sequential block are executed sequentially, but if fork join_any or join_none in the sequential block causes the statements following the parallel block to be executed at the same time as the statements in the block, is there any guarantee of their execution order? I've tried a lot of simulators, and the results are:

# Fork Time is 5
# Fork Time is 10
# Time is 10
# Fork Time is 15
# Time is 15

I guessed that the statement in the parallel block would be executed before the statement executed at the same time after the parallel block, but I couldn't find any evidence.


Solution

  • The output you show is expected.

    I added some comments to your code to uniquely identify each display statement (d1-d5):

    initial begin
        fork
            #5  $display("Fork Time is %0t",$time); // d1: Start execution at t= 0, display at t= 5
            #10 $display("Fork Time is %0t",$time); // d2: Start execution at t= 0, display at t=10
            #15 $display("Fork Time is %0t",$time); // d3: Start execution at t= 0, display at t=15
        join_any
        #5 $display("Time is %0t",$time);           // d4: Start execution at t= 5, display at t=10
        #5 $display("Time is %0t",$time);           // d5: Start execution at t=10, display at t=15
    end
    

    The fork block starts execution at time 0. The first display statement (d4) after the join_any line will not start execution until after the fork/join_any allows it to. Since d1 has the shortest delay inside the fork block at 5 time units, d1 will finish first. So, at time 5, d1 finishes execution, then the d4 statement starts execution.

    Then d5 will start execution after d4 finishes at time 10.