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

时间:2017-08-10 08:44:34

标签: multithreading system-verilog fork-join

我有一段代码表现出以下行为。我期望看到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

我得到以下输出。有人可以解释一下。我尝试使用VCS进行EDAPlayground。

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 

2 个答案:

答案 0 :(得分:1)

您可能需要添加&#34;自动&#34;在变量开始执行之前,自动存储类变量映射到堆栈上。调用函数时,函数中声明的所有本地(非静态)变量都映射到堆栈中的各个位置。由于这些变量仅存在于堆栈中,因此只要函数的执行完成并且堆栈相应地收缩,它们就不再存在。在到达所有子进程的末尾之前,含义范围仍然有效。

   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

答案 1 :(得分:1)

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

此外,10个线程没有定义的执行顺序 - 它们都处于竞争中。 $显示或分配可以按任何顺序排列,因此j可能会显示x。您可能会从不同的工具中获得不同的结果

要使代码显示0,1,...,4,您不能使用j的静态变量。您需要使用jfor循环的每次迭代创建automatic的副本,该i会针对每个循环使用当前值String stringParser(String inputString) { inputString.split("_")[0] } 进行初始化。 @Emman已经展示了一种方法。