分析下列代码的输出结果:
代码1:
module test();
initial begin
for(int j =0; j < 3; j++)
fork
$write(j);
join_none
#0 $display("\n");
end
endmodule
改代码在循环中内嵌 fsk...join_none,是一种不良代码的执行过程,该代码的执行过程如下:
代码2:
j 语句
0 for (j=0; ...
0 产生线程 $write(j) [线程 0]
1 j++ j=1
1 产生线程 Swrite (j )[线程 1]
2 j++ i=2
2 产生线程 Sprite(j ) (线程 2]
3 j+ + j=3
3 joinnone
3 # 0
3 $write(j ) [线程 0:j=3]
3 $write(j ) [线程 1:j=3]
3 $write(j ) [线程 1:j=3]
3 $display ( )
注意输出结果是3 3 3 而不是2 2 2 和0 1 2
同理,下列代码的运行结果如下:
代码3:
module test();
initial begin
for(int j =0; j <= 3; j++)
fork
$write(j);
join_none
#0 $display("\n");
end
endmodule
综上在循环中嵌套fork...join_none语句当使用自动变量来保存变量的拷贝。
代码4:
module test();
initial begin
for(int j =0; j < 3; j++)
fork
automatic int k = j;
$write(k);
join_none
#0 $display("\n");
end
endmodule
该代码的运行结果如下:
分析:代码4中fork...join_none 块被分割成两个部分。。带初始化的自动(automatic)变量声明在for循环的线程中运行。在每轮循环中,k的一个拷贝创建并被设置为j的当前值,然后fork...join_none ($write)被调度,包括k的拷贝。在循环完成后,#0阻塞了当前线程,因此三个线程一起运行,打印出各自拷贝值k。当线程运行完毕后,在当前时间片已经没有其他事件残留,这时SystemVerilog就会进到下一个语句执行$display。代码的执行步骤如下:
代码4可以在fork.. join_none的外部声明自动变量,适合在带自动存储的程序内使用,例如
代码5: