always_comb和always @(*)之间的行为差​​异

时间:2015-09-25 09:16:25

标签: verilog system-verilog

我刚刚发现@ {*)在涉及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有关。

2 个答案:

答案 0 :(得分:4)

始终@(*)块对所有变量的值的变化都很敏感,总是通过块读取,或者我们可以说总是在块内的右侧。

在您的示例中,always块中没有使用任何变量,因此这个@(*)块始终不起作用。

根据SV LRM,

  

always_comb对函数内容中的更改很敏感,   而@ *总是只对a的参数变化敏感   功能

即,只要函数内部的变量发生变化,always_comb就会触发,但在你的情况下,只有在函数中传递一个参数时,@(*)才会触发。

所以要么你可以使用,

  always @(*) begin
    c = my_func(b);  
  end

或者你可以使用,

  always_comb begin
    c = my_func();  
  end

我修改了你的代码。请在下面的链接中找到它。

http://www.edaplayground.com/x/JiS

答案 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执行。