Fork-join_none with delay

In reply to dave_59:

Thanks Dave.

In reply to dave_59:

Hi Dave,
If I modify #1 to 1us in the code, why it displays 0######?
Thanks

In reply to timag:

The first iteration of the for loop always starts at time 0.

In reply to dave_59:

Hi Dave,

Does this code give different output if you use fork-join instead of join_none?

In reply to kirankinhal:

Yes, a fork/join in that example would behave the same as begin/end since there is only one statement and no delays inside. In those cases the current iteration value of k gets displayed.

My understanding from LRM is that any blocking assignment should trigger the fork join_none block.

Why is k=j not considered as a blocking statement in this piece of code?

module fork_test1;
  int k;
  initial begin
    for (int j=0; j<2; j++) begin
      //#1;
      $display("j before fork %0d", j);
      fork
        $display("j inside fork-join_none block %0d", j);
      join_none
      $display("j after join_none %0d", j);
      k = j;
      //#1;
   end
  end
endmodule:fork_test1

Output:

# run -all
# j before fork 0
# j after join_none 0
# j before fork 1
# j after join_none 1
# j inside fork-join_none block 2
# j inside fork-join_none block 2

A blocking assignment is a potentially blocking statement. With no intra-assignment delay (k = #1 j;), it is not a blocking statement. (BTW, this distinction was added to the glossary of the IEEE 1800-2023 SystemVerilog LRM.

1 Like

That is very interesting. So, only delaying simulation time can be considered as a blocking statement inside fork join_none. What sources do you recommend I read to understand this in more detail?

A procedural delay is just one kind of process blocking construct. See section 9.4 Procedural timing controls in the LRM

Hi Dave,

Can you give some clarifications about forks in IEEE 1800-2023 SV LRM?

1800-2017 LRM for fork-join_none says: the spawned processes do not start executing until the parent thread executes a blocking statement or terminates.

But in 1800-2023 LRM this sentence was removed and was placed after table 9.1 with some changes: In all cases, processes spawned by a fork-join block shall not start executing until the parent process is blocked or terminates.

It seems to me, that this may introduce new behaviour for fork-join and fork-join_any, because waiting for blocking statements applies to them too. Could you please give your comments?

There is no real change in behavior here–just clarification in terminology.

Some blocking statements are actually potentially blocking statements. For example:

wait (reset == 1);

does not block the process if reset was already set to 1.

Thanks, Dave!