System Verilog中的automatic
本文展现了module,task和变量为automatic和非automatic时的仿真结果,用于分析automatic的功能与作用范围。
automatic 仿真测试
1、子程序均为静态存储的情况
module test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=0;j<3;j++) begin
fork
distest(j);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,三次打印,k的值都为3。因为system verilog中,module和program块中子程序的存储方式在缺省情况下使用的是静态存储。
0:j=3;
100: k = 3;
100: k = 3;
100: k = 3;
2、在静态存储子程序中加入automatic的中间变量
module test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=0;j<3;j++) begin
fork
automatic int m=j;
distest(m);
$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,中间值m的打印为2,1,0,但是distest打印的k值均为0。
0:j=3,m=2;
0:j=3,m=1;
0:j=3,m=0;
0:j=3;
100: k = 0;
100: k = 0;
100: k = 0;
修改j的取值范围为1-3,for(j=1;j<4;j++),仿真结果如下,但是distest打印的k值均为1,结合上面的仿真结果,推测因为distest是静态存储的,所以仿真时以第一次配置生效,每次执行时,从静态存储区拷贝出来的取值地址为m=1的地址。
0:j=4,m=3;
0:j=4,m=2;
0:j=4,m=1;
0:j=4;
100: k = 1;
100: k = 1;
100: k = 1;
3、修改module test为动态存储
a、修改module test为动态存储,去掉中间存储变量m
module automatic test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
//automatic int m=j;
distest(j);
//$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,k的三个打印值均为1。
0:j=1;
100: k = 1;
100: k = 1;
100: k = 1;
b、修改module test为动态存储,加入中间存储变量m
module automatic test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
int m=j;
distest(m);
$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,k的打印值为2,3,4,与期望相符。
0:j=1,m=2;
0:j=1,m=3;
0:j=1,m=4;
0:j=1;
100 :k = 2;
100: k = 3;
100: k = 4;
c、修改module test为动态存储,加入中间存储变量m,默认动态存储,声明与赋值分开
module automatic test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
int m;
m=j;
distest(m);
$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,k的三个打印值均为1。
0:j=1;
100: k = 1;
100: k = 1;
100: k = 1;
4、修改distest task为动态存储
a、去掉中间存储变量m,或m为静态存储
module test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
//automatic int m=j;
distest(j);
//$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task automatic distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下:
0:j=1;
100: k = 1;
100: k = 1;
100: k = 1;
加入m为静态存储,int m=j,仿真结果如下,这个结果原因是m是静态分配的,仿真一开始就有了初值,初值为0.
0:j=1,m=0;
0:j=1,m=0;
0:j=1,m=0;
0:j=1;
100 :k = 0;
100: k = 0;
100: k = 0;
b、m为静态存储,但是声明和赋值分开
module test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
int m;
m=j;
distest(m);
$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task automatic distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,
0:j=1,m=1;
0:j=1,m=1;
0:j=1,m=1;
0:j=1;
100 :k = 1;
100: k = 1;
100: k = 1;
c、m为动态存储,但是声明和赋值分开
module test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
automatic int m;
m=j;
distest(m);
$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task automatic distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,
0:j=1,m=1;
0:j=1,m=1;
0:j=1,m=1;
0:j=1;
100 :k = 1;
100: k = 1;
100: k = 1;
d、m为动态存储,但是声明和赋值在一起
module test;
initial begin
automatic_test;
end
task automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
automatic int m=j;
//m=j;
distest(m);
$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task automatic distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,
0:j=1,m=2;
0:j=1,m=3;
0:j=1,m=4;
0:j=1;
100 :k = 2;
100: k = 3;
100: k = 4;
5、修改aotumatic_tset task为动态存储
a、中间变量m默认为动态存储,声明和赋值在一起
module test;
initial begin
automatic_test;
end
task automatic automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
int m=j;
//m=j;
distest(m);
$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,
0:j=1,m=2;
0:j=1,m=3;
0:j=1,m=4;
0:j=1;
100 :k = 4;
100: k = 4;
100: k = 4;
b、中间变量m默认为动态存储,声明和赋值分开
module test;
initial begin
automatic_test;
end
task automatic automatic_test;
int j;
for(j=4;j>1;j--) begin
fork
int m;
m=j;
distest(m);
$display($time,": j=%0d, m=%0d",j,m);
join_none
end
#0 $display($time,": j=%0d",j);
#1000;
endtask:automatic_test
task distest(int k);
#100;
$display($time,": k = %0d",k);
endtask:distest
endmodule
仿真结果如下,
0:j=1,m=1;
0:j=1,m=1;
0:j=1,m=1;
0:j=1;
100 :k = 1;
100: k = 1;
100: k = 1;