大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
module test;
initial begin
main();
end
task main();
// fork join_any block1
fork
#5 $display("THREAD 1 %0t", $time);
#25 $display("THREAD 2 %0t", $time);
join_any
dev_state();
$display("After task call %0t", $time);
#100 $finish;
endtask
task dev_state();
// fork join_any block2
fork
#5 $display("THREAD 3 %0t", $time);
#10 $display("THREAD 4 %0t", $time);
join_any
disable fork;
endtask
initial begin
$display("debug point fork_1");
fork_1();
$display("debug point fork_2");
fork_2();
$display("debug point fork_3");
fork_3();
$display("debug point fork_4");
fork_4();
end
task fork_1();
for(int i = 0; i < 16; i++) begin
fork
// begin
automatic int index =i;
send(index);
// end
join_none
end
wait fork;
endtask
task fork_2();
for(int i = 0; i < 16; i++) begin
fork
// begin
automatic int index;
index = i;
send(index);
// end
join_none
end
wait fork;
endtask
task fork_3();
for(int i = 0; i < 16; i++) begin
fork
begin
automatic int index;
index = i;
send(index);
end
join_none
end
wait fork;
endtask
task fork_4();
for(int i = 0; i < 16; i++) begin
automatic int index;
index = i;
fork
begin
send(index);
end
join_none
end
wait fork;
endtask
task send(int j);
$display("driving port %0d" , j);
endtask
endmodule
all : clean comp run sim.log
clean:
\rm -rf simv* csrc *.key
comp:
vcs -full64 test.sv -sverilog
run:
simv -l sim.log
debug point fork_1
driving port 0
driving port 1
driving port 2
driving port 3
driving port 4
driving port 5
driving port 6
driving port 7
driving port 8
driving port 9
driving port 10
driving port 11
driving port 12
driving port 13
driving port 14
driving port 15
debug point fork_2
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
debug point fork_3
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
driving port 16
debug point fork_4
driving port 0
driving port 1
driving port 2
driving port 3
driving port 4
driving port 5
driving port 6
driving port 7
driving port 8
driving port 9
driving port 10
driving port 11
driving port 12
driving port 13
driving port 14
driving port 15
THREAD 1 5
THREAD 3 10
After task call 10
使用以上Makefile和test.sv文件,运行仿真,仿真结果如下
可以看到虽然都是fork join_none wait fork但是每一个fork_x task的打印结果是不同的。这是为什么呢?
不同之处在于变量index的生存周期,以及何时为该变量分配变量i的值的时间。
意识到将有16个并发变量名为index,只有一个名为i。在情况1)和2)中,每次进入fork / join_none块时都会创建index变量。在派生fork / join_none中的任何进程之前发生。在情况1)中,变量初始化也发生在fork / join_none中的任何进程之前。您需要记住的是,自动变量是在输入时创建的,并在执行它们所在的块中的任何过程语句之前被初始化。因此,在情况1)中,每个索引变量在每次循环迭代中都获得i的当前值。
在情况2)中,您将初始化移到了单独的过程分配语句中。 fork / join_none中的每个语句将成为新的子进程,并且直到当前父线程挂起后,该子进程才开始执行。现在,for循环会生成16个线程,然后在i的值为16时在wait fork处挂起。(正如我之前说过的,如果send(index)看到单位值0或分配的值16,这是一个竞赛。
在情况3)中,现在在一个begin / end块内声明index变量,这是fork / join_none的单个语句。因此,直到所有16个进程都已生成并且i的值为16时,才创建索引变量。
任何自动变量的生命周期都将在其块及其所有嵌套块的生命周期结束时结束。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/193010.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...