The difference between a looped `fork...join_none` and a serial `fork...join_none`

Hi all,

When I use a loop in a module and declare a variable a within a fork...join_none, that variable should have a static lifetime, and its scope should be limited to the fork...join_none.

initial begin
  repeat(2) begin
    fork
      int a;      
      begin
        a++;
        $display("a is %0d", a);
      end
    join_none
  end
  wait fork;
end

As I understand it, a new fork...join_none should be created for each iteration of the loop. Therefore, the two loops in the snippet above create two fork...join_none instances, and variable a should be initialized in both of them. Consequently, a should ultimately print 1 in both cases, but in reality, it prints 1 and 2.

Later, I tried a serial fork...join_none, and this time the results were as expected—both were 1. Why is that?

initial begin 
  fork
    int a;
    begin
      a++;
      $display("a is %0d", a);
    end
  join_none

  fork
    int a;
    begin
      a++;
      $display("a is %0d", a);
    end
  join_none
  wait fork;
end

It seems that the two fork...join_none instances of repeat are sharing the same variable.

BR

SystemVerilog allocates and initializes static variables once at the beginning of the simulation before any initial or always blocks begin execution. To create a new instance of a for each iteration of the loop, declare it as automatic int a;.

Thanks dave, I understand what you mean, but I think the variable a is declared within fork...join_none, so its scope is limited to fork...join_none. Since the two loops create two fork...join_none blocks, each fork...join_none should have its own a with a static lifetime, and the two as should be independent of each other. However, the results seem to indicate that the two as are the same.

I thought about it carefully, and I wonder if I can understand it this way.

There is only one begin...end block here, and within that block there is only one fork...join_none block; there is also only one variable declared within the fork...join_none block. The loop simply repeats the execution of the same begin...end block, similar to a method call. Therefore, when variable a is declared as static, even if the loop runs multiple times, the static variable a will only be initialized once.

Yes, I think your last post suggests you are beginning to understand it.

You might want to read my DVCon paper:

Much appreciated.