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

Ald*_*doT 2 verilog system-verilog

我刚刚发现 always@(*) 在涉及function.

请参阅下面的简单示例代码。

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

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
Run Code Online (Sandbox Code Playgroud)

尝试在模拟always @(*)always_comb模拟之间切换。如果我使用always @(*),则不会显示任何内容。但是,如果我使用always_comb,它将显示如下预期结果:

DEBUG 2 @0
DEBUG 2 @0
DEBUG 2 @10
DEBUG 2 @20
Run Code Online (Sandbox Code Playgroud)

上面的代码只是简单的组合逻辑。为什么always @(*)always_comb显示不同的结果?只是模拟问题吗?进一步的实验我注意到它可能与function在 always 块中的使用有关。

H.M*_*odh 7

always@(*)块对所有变量的值变化很敏感,即由 always 块读取,或者我们可以说哪个位于 always 块内的右侧。

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

根据 SV LRM,

always_comb 对函数内容的变化敏感,而 always @* 只对函数参数的变化敏感。

即,每当函数内的变量发生变化时, always_comb 将触发,但在您的情况下, always @(*) 只有在我们在函数中传递参数时才会触发。

所以你可以使用,

  always @(*) begin
    c = my_func(b);  
  end
Run Code Online (Sandbox Code Playgroud)

或者你可以使用,

  always_comb begin
    c = my_func();  
  end
Run Code Online (Sandbox Code Playgroud)

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

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