Question about argument passing behavior in fork join_none block

Hi All,

I am confused at the sim result of the following fork…join_none code

module top;
initial begin

 fork: receive_fork
  receive(1); 
  receive(2); 
 join_none
 
  #30ns;
  $display("%0t: Done", $time);                      
end
                                                   
task receive(int index);
  $display("entering receive, index=%0d",index);
  #(index * 10ns);
  $display("%0t: Receive is done for index = %0d", $time, index);
endtask

endmodule

Sim result

entering receive, index=1
entering receive, index=2
10: Receive is done for index = 2
20: Receive is done for index = 2
30: Done

I wonder for thread receive(1), why when argument “index” is used in the first display syntax and #(index*10ns) expression, “index” has the desired value of 1, but inside the second display syntax, the value of “index” becomes 2?

I understand that for the following example,

for(int j=0;i<3;j++)
  fork
    $write(j);
  join_none

all three $write result will be j=3 since the spawned $write(j) thread won’t execute until the for loop is exited. But for my example, when executing

$display("entering receive, index=%0d",index);
  #(index * 10ns);

the value of “index” is already 1, I am very confused why “index” became 2 when executing

$display("%0t: Receive is done for index = %0d", $time, index);

Thanks in advance for your help!

In reply to peterjin:

Because you declared the task receive() with a static lifetime (the implicit default lifetime). That means there is only one argument index for all calls to receive. Change the declaration to

task automatic receive(int index);

In reply to dave_59:

Thanks for the explanation, that solved my confusions!

Hao