我刚刚发现@ {*)在涉及OutOfMemoryError
时始终无法正常工作。
请参阅下面的简单示例代码。
http://www.edaplayground.com/x/J7M
function
尝试在模拟中切换module test;
reg a, b, c;
function reg my_func();
if (b==0) begin
$display("DEBUG 0 @%0t", $time);
return a;
end
else if (b==1) begin
$display("DEBUG 1 @%0t", $time);
return ~a;
end
else begin
$display("DEBUG 2 @%0t", $time);
return 0;
end
endfunction
always @(*) begin
//always_comb begin
c = my_func();
end
initial begin
a = 0; #10;
a = 1; #10;
a=0;
end
endmodule
和always @(*)
。如果我使用always_comb
,则不会显示任何内容。但是,如果我使用always @(*)
,它将显示预期结果如下:
always_comb
上面的代码只是简单的组合逻辑。
为什么DEBUG 2 @0
DEBUG 2 @0
DEBUG 2 @10
DEBUG 2 @20
和always @(*)
会显示不同的结果?这只是模拟问题吗?进一步的实验我注意到它可能与在always块中使用always_comb
有关。
答案 0 :(得分:4)
始终@(*)
块对所有变量的值的变化都很敏感,总是通过块读取,或者我们可以说总是在块内的右侧。
在您的示例中,always块中没有使用任何变量,因此这个@(*)
块始终不起作用。
根据SV LRM,
always_comb对函数内容中的更改很敏感, 而@ *总是只对a的参数变化敏感 功能
即,只要函数内部的变量发生变化,always_comb就会触发,但在你的情况下,只有在函数中传递一个参数时,@(*)才会触发。
所以要么你可以使用,
always @(*) begin
c = my_func(b);
end
或者你可以使用,
always_comb begin
c = my_func();
end
我修改了你的代码。请在下面的链接中找到它。
答案 1 :(得分:1)
always @(*)
由Verilog IEEE 1364-2001标准添加,并在SystemVerilog IEEE 1800-2005标准中由always_comb
替换。不应再使用always @(*)
,因为它无法在所有情况下正确模拟硬件。除了您在功能上注意到的差异之外,它还没有正确处理常量逻辑。
parameter C = 0;
reg A,B;
always @(*) A = B && C;
在A
发生更改之前, B
仍然未知。而使用always_comb会立即将A
设置为0,因为保证在时间0执行。