Loops 有人能解释一下verilog系统中的fork和loop吗?
我经历了这个问题,并得到了这个怀疑,我粘贴下面的例子作为参考Loops 有人能解释一下verilog系统中的fork和loop吗?,loops,system-verilog,fork-join,Loops,System Verilog,Fork Join,我经历了这个问题,并得到了这个怀疑,我粘贴下面的例子作为参考 for(int j=1; j <=3; ++j) fork automatic int k = j; begin .... # use k here end join_none 如果我在叉子里移动环会发生什么 for(int j=1; j <=3; ++j) begin automatic int k = j; fo
for(int j=1; j <=3; ++j)
fork
automatic int k = j;
begin
.... # use k here
end
join_none
for(int j=1; j <=3; ++j) begin
automatic int k = j;
fork
begin
.... # use k here
end
join_none
end
fork
for(int j=1; j <=3; ++j) begin
automatic int k = j;
begin
.... # use k here
end
end
join_none
fork
对于(int j=1;j将自动变量移到fork外部,但仍在for
循环的begin/end
块内部,具有相同的效果。循环的每次迭代都会获得自己的k
本地副本,并使用当前循环值j
初始化。因此,您可以获得三个k
副本,并使用这些值1、2和3。fork/join\u none生成的每个进程都绑定到k
的每个本地副本。由于fork/join\u none位于循环内,因此生成三个进程
如果将for
循环移动到fork内部,则只会得到一个由fork
生成的进程,该进程有一个循环。那么使用j或k并不重要,因为循环内部的代码是按顺序执行的。将自动变量移动到fork外部,但仍然在for
循环具有相同的效果。循环的每次迭代都会获得自己的k
本地副本,该副本由当前循环值j
初始化。因此,您会得到三个k
副本,值分别为1、2和3。fork/join生成的每个进程都不会绑定到k
的每个本地副本。因为fork/如果在循环中没有,则会产生三个进程
如果将for
循环移动到fork内部,则只会得到一个由fork产生的进程,该进程有一个循环。因此,使用j或k并不重要,因为循环内部的代码是按顺序执行的。1、3的效果将是相同的,fork…join
的每个线程都将采用适当的值f j(j=1,2,3…全部取)
但是对于第二种情况,由于您将值赋给线程外部的k
,因此所有线程都将采用k的最后一个值
下面是您每个案例的示例代码
// Code 1
for(int j=1; j <=3; ++j)
fork
automatic int k = j;
begin
$display("Current Value - %0d", k);
end
join_none
wait_fork;
// Output of Code 1
Current Value - 1
Current Value - 2
Current Value - 3
// Code 2
for(int j=1; j <=3; ++j)
begin
automatic int k = j;
fork
begin
$display("Current Value - %0d", k);
end
join_none
end
wait_fork;
// Output of Code 2
Current Value - 3
Current Value - 3
Current Value - 3
// Code 3
fork
for(int j=1; j <=3; ++j)
begin
automatic int k = j;
$display("Current Value - %0d", k);
end
join_none
wait fork;
// Output of Code 3
Current Value - 1
Current Value - 2
Current Value - 3
//代码1
对于(int j=1;j1,3的效果相同,fork…join
的每个线程将采用正确的j值(j=1,2,3…全部采用)
但是对于第二种情况,由于您将值赋给线程外部的k
,因此所有线程都将采用k的最后一个值
下面是您每个案例的示例代码
// Code 1
for(int j=1; j <=3; ++j)
fork
automatic int k = j;
begin
$display("Current Value - %0d", k);
end
join_none
wait_fork;
// Output of Code 1
Current Value - 1
Current Value - 2
Current Value - 3
// Code 2
for(int j=1; j <=3; ++j)
begin
automatic int k = j;
fork
begin
$display("Current Value - %0d", k);
end
join_none
end
wait_fork;
// Output of Code 2
Current Value - 3
Current Value - 3
Current Value - 3
// Code 3
fork
for(int j=1; j <=3; ++j)
begin
automatic int k = j;
$display("Current Value - %0d", k);
end
join_none
wait fork;
// Output of Code 3
Current Value - 1
Current Value - 2
Current Value - 3
//代码1
对于(int j=1;j)要了解发生了什么,请修改LRM中的示例并运行模拟:#k$write(“%0d”,k);
到#(4-k)$display(“k:%0d j:%0d”,k,j)
。您会注意到,k
的顺序与LRM中的示例相反,j
在每个实例中都是相同的。j
没有正确的值,因为它根据LRM不确定,因此不同的模拟器可能显示不同的值。要了解发生了什么,请修改L中的示例RM并运行模拟:#k$write(“%0d”,k);
到#(4-k)$display(“k:%0d j:%0d”,k,j)
。您会注意到,k
的顺序与LRM中的示例相反,j
在每个实例中都是相同的。j
没有正确的值,因为它根据LRM不确定,因此不同的模拟器可能显示不同的值。您对代码2的观察与Dav的评论相矛盾代码1和代码3给出了相同的输出,我们可能忽略了代码1实际上是在fork中运行的,而代码3是按顺序运行的。是的,但这是VCS工具的输出。我认为,每个代码都会打开线程,不会按顺序运行。你对代码2的观察与Dave的评论相矛盾。代码1和代码3给出了相同的结果输出,我们可能缺少代码1在fork中实际运行,而代码3按顺序运行。是的,但这是VCS工具的输出。我认为,每个代码都会打开线程,不会按顺序运行。