为什么verilog中递归函数需要定义为automatic?
直接上代码
module automatic_tb;reg [7:0] value;initial begin #0 value <= 8'd5;#10 $display("result of automatic: %0d", factor_automatic(value));$display("result of static: %0d", factor_static(value));#50 $stop;
endfunction reg[7:0] factor_static (input reg[7:0] dat);if (dat >= 2) beginfactor_static = factor_static(dat-1) * dat;endelsefactor_static = 1;
endfunctionfunction automatic reg[7:0] factor_automatic (input reg[7:0] dat);if (dat >= 2) beginfactor_automatic = factor_automatic(dat-1) * dat;endelsefactor_automatic = 1;
endfunctionendmodule
得到的仿真结果为:
从上述的仿真结果中可以看到,此时automatic的函数对应的结果是对的,而static的函数对应的结果是错误的。
原因分析
对于static函数而言,此函数中对应的变量都是static,也就是只存在一份。以上述的列子为例,当factor_static递归四次的时候,此时dat的值为1,即这唯一的一份dat的值为1,并且此时result也被置为1,当函数进行到上一层的时候,此时factor_static(2)的值为1,而dat的也是1,所以当前这一次返回的值也为1,因此最终的结果为1。具体的流程见下图:
在国外的网站上看到的另一个分析static和automatic函数的例子
module static_tb;task add(input reg[7:0] a, input reg[7:0] b);
begin#2;$display("the sum is %0d", a+b);
end
endtaskinitial
forkbegin add(2, 3);endbegin#1;add(3, 4);end
join endmodule
可以看到,这里的两个sum输入的参数不同,但是得到的结果却是相同的。这是由于在time为0的时候,add(2, 3)进行执行,将a设置为2,b设置为3,然后等待2个时间单位准备输出,但是在经过了1个时间单位之后,add(3,4)进行执行,又将a设置为3,b设置为4,所以再又经过一个时间单位之后,输出的结果为7,从而看到的结果都是7。
此案例的参考地址