为什么输出总是在forkjoin_none中打印j=5?

Why does the output always print j=5 in fork join_none?

我有一段代码表现出以下行为。我希望看到 10 个并行线程,例如第一个线程:j=0 和第五个线程:j=4,所有 运行 在模拟时间 0 ns。此外,j=i 和 $display 运行 并行,因此在 $display 执行时,j 仍然是 x.

module tb;

integer i,j;

initial
for(i=0;i<5;i++)
fork
j = i; 
$display("Value of j is %d at time=%d \n", j, $time); 
join_none

endmodule

我得到以下输出。有人可以解释一下吗?我在 EDAPlayground 上尝试使用 VCS。

Value of j is           5 at time=                   0 

Value of j is           5 at time=                   0 

Value of j is           5 at time=                   0 

Value of j is           5 at time=                   0 

Value of j is           5 at time=                   0 

您可能需要在变量开始执行之前添加一个"automatic",自动存储class变量映射到堆栈上。调用函数时,函数中声明的所有局部(非静态)变量都映射到堆栈中的各个位置。由于此类变量仅存在于堆栈中,因此一旦函数执行完毕,它们将不复存在,堆栈也会相应缩小。意思范围保持活动状态,直到到达所有子进程的末尾。

   module tb; 
      integer i,j;
      initial
        for(i=0;i<5;i++)
          fork
            automatic int j=i;
            begin 
              $display("Value of j is %d at time=%d \n", j, $time); 
            end 
          join_none 
   endmodule

您假设您的代码生成 10 个并行线程是正确的。但是,在父线程阻塞或终止之前,fork/join_none 不会启动任何这些线程。在您的情况下,它是在 initial 块进程终止之后。到那时,退出for循环后i的值为5。

此外,这 10 个线程没有定义的执行顺序 - 它们都在竞争中。 $displays 或 assignments 可以按任何顺序出现,因此 j 可能显示 x。使用不同的工具可能会得到不同的结果

要让您的代码显示 0,1,...,4,您不能为 j 使用静态变量。您需要使用 automaticfor 循环的每次迭代创建 j 的副本,每个循环使用 i 的当前值进行初始化。 @Emman 展示了一种方法。