1

我想我已经弄清楚为什么会发生这种情况,但我想确认一下,看看是否有更好的解决方案。

考虑以下模块,该模块具有一个函数,其中一个参数的默认值绑定到模块内的某个寄存器:

module m;
  reg a, b;
  wire out;
  function f1 (input x, input y = b);
    f1 = x & y;
  endfunction :f1

  // ...
  assign out = f1(a);
endmodule

我看到的问题(不容易追查)是,在这种情况下,任务的敏感性列表只有一个。因此,如果 b 更改,然后 a 更改,out 将被正确更新。但是,如果 a 发生变化,然后 b 发生变化,因为 b 不在 out 分配的敏感列表中,out 将不会更新,并且仍将设置为旧值。

是否有首选方法将 b 添加到敏感度列表中,以便在更改时更新 out ?

我看到了一些可能的选择:

  1. 只需显式添加第二个参数:f1(a, b)
  2. 使用连续分配块always_comb out = f1(a)always @(*) out=f1(a)
  3. 使用明确的敏感度列表always @(a, b) out = f1(a)

我个人认为选项 1 是最好的(即使它会在每个调用它的位置复制可选参数),但我很好奇是否有其他解释,或者是否有更好的解决方案。

4

1 回答 1

2

选项 1 破坏了默认参数功能。您必须确保没有人在声明中提供默认值,这样您就不会再次遇到此问题。

正如您所发现的那样,选项 3 不再是一个选项——它是调试的噩梦。

always_comb结构是专门为这种编码风格设计的。事实上,人们想编写没有输入或输出的函数,只是作为一种代码结构机制,使代码更易于管理。

always_comb begin
          phase_one_stuff;
          phase_two_stuff;
          if (mode==A)
               mode_A_stuff;
          else
               mode_B_stuff;
          phase_three_stuff;
       end

不要@(*)在 SystemVerilog 中使用。always_comb替换它并具有处理@(*)可能不敏感的时间 0 初始值的好处。

于 2020-01-17T23:35:30.340 回答