从分配调用时,函数可选参数不在敏感列表中

Function optional parameters not in sensitivity list when called from assign

我想我已经弄明白为什么会这样了,但我想确认一下,看看有没有更好的解决办法。

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

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 是最好的(即使它会在调用它的每个位置复制可选参数),但我很好奇是否还有其他解释,或者是否有更好的解决方案。

选项 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 初始值的好处。