automatic 机制困惑
脚本执行操作
vlib work
vlog -sv ./tst_4.sv
vsim -t 1ps work.tb -novopt
run 1ns
tst_4.sv源码如下
module tb; // should not compile
int c1,c2;
int c3,c4;
initial
begin
fork
c1 = add(1,1);
c2 = add(2,2);
join_none
#1ps
$display("the data c1 is %d,time is %t",c1,$realtime);
$display("the data c2 is %d,time is %t",c2,$realtime);
fork
c3 = add_no(1,1);
c4 = add_no(2,2);
join_none
#1ps
$display("the data c3 is %d,time is %t",c3,$realtime);
$display("the data c4 is %d,time is %t",c4,$realtime);
end
function automatic int add(input int a,input int b);
int c;
c = a+b;
return c;
endfunction
functionstatic
int add_no(input int a,input int b);
static int c;
c = a+b;
return c;
endfunction
endmodule
////////////////////////////////打印显示////////////////////////////////////////////////
# the data c1 is2,time is1
# the data c2 is4,time is1
# the data c3 is2,time is2
# the data c4 is4,time is2
为什么结果一致,automatic使用和没有使用结果一样呢,不是说静态的使用一个存储空间么?
以为是function不是task
就修改了task一版代码如下,发现没有什么用
module tb; // should not compile
int c1,c2;
int c3,c4;
initial
begin
fork
add(1,1,c1);
add(2,2,c2);
join_none
#1ps
$display("the data c1 is %d,time is %t",c1,$realtime);
$display("the data c2 is %d,time is %t",c2,$realtime);
fork
add_no(1,1,c3);
add_no(2,2,c4);
join_none
#1ps
$display("the data c3 is %d,time is %t",c3,$realtime);
$display("the data c4 is %d,time is %t",c4,$realtime);
end
task automatic add(input int a,input int b,output int c);
c = a+b;
endtask
taskadd_no(input int a,input int b,output int c);
c = a+b;
endtask
endmodule
////////////////////////////////打印显示////////////////////////////////////////////////
# the data c1 is2,time is1
# the data c2 is4,time is1
# the data c3 is2,time is2
# the data c4 is4,time is2
大侠路过时,提示一两句吧
还有为什么在initial end内部申明对象,比如 packet P1 = new(); 需要加上automatic和static信息,在initial end外部就不需要,
希望给些解释
再贴一个小例子辅助理解,这个加不加影响最终结果,加了为120,不加结果为1;没有搞懂,和我发的例子有啥区别,不是static均共享内存么?
module tb;
reg [31:0] n;
reg [31:0] result;
initial begin
n = 5;
result = 0;
result = factorial(n);
$display("n=%d, result=%d", n, result);
$finish;
end
function [31:0] factorial (
//function automatic [31:0] factorial (
input [31:0] iN
);
if (iN == 1)
factorial = 1;
else
factorial = iN * factorial(iN-1);
endfunction
有点复杂
没看明白
解释一下这几行,你应该就明白了
function [31:0] factorial (
//function automatic [31:0] factorial (
input [31:0] iN
);
if (iN == 1)
factorial = 1;
else
factorial = iN * factorial(iN-1);
endfunction
当function为static时,这些var的生命周期为一声明后,那么当你给input为5时,进入else part,变为
factorial = 5 ×fac(4),
此时由于是staic的,IN被4代替
就变成了
factorial = 4xfac(3),
...
同理直到
in=1,进入fac = 1的分支
而当定义为automatic时,IN的生命周期为调用function,你可以自己想一下
没看明白
最后的那个阶乘的例子我理解,前面的两个共同调用未声明自动变量的我没有理解,应该如何解释?
可以参考LRM scope&lifetime section的内容;小编举的例子不合适;fork join内的相当于例化了两个无名线程,之间相互独立,他们各自的lifetime都影响不到对方;task显示声明为automatic只表示 其内部声明的变量默认为automatic的,与功能无关,也影响不到接口参数的 lifetime;
函数的返回值的 automatic修饰 有另外的 意义,我并没有用过,就我的理解 应该 跟这个 一点关系都没有,具体 可以参考 LRM 的 user-defined nettypes section;
initial块内的变量声明默认也一样是static
刚刚又看了下LRM13章节的内容,关于FUNCITON的 static/automatic 我的理解有误;
这里的static/automatic同样是修饰function的scope-lifetime的;不是修饰返回值的,可以自己看下;
没有太理解,我的意思是如果静态函数的话,如果同时使用是否会存在内存共享,add_no的结果要么是2要么是4,为什么都出现,函数内部内存没有共享,输出结果也没有共享。
fork join块内 的两个同名函数 虽然是同名的 ,但是因为没有begin end限制约束,属于两个相互独立的 块,你可以把他们看成 有全局统一规划出来的 两个模块,这里声明的 static分别影响他们各自内部声明的变量 的默认状态为static,但是并不影响对方的 变量,因为他们属于不通的作用域;在硬件里面,function可以看做是组合逻辑(并不一定能综合,但是与可综合逻辑在仿真过程中的内存模型一致),声明一次就 例化出一个模块,这里只不过是 例化出的两个模块没有名字;