有没有办法在verilog中有条件地触发编译时错误?

电器工程 验证日志
2022-01-06 07:03:46

我在verilog中有一个参数化模块,其中参数是时钟频率和刷新率,用于计算在重复操作的实例之间插入了多少不活动周期。但是,很容易设置无法达到的参数(因为操作需要很长的时间,所以重复必须在完成之前发生),并且目前设计没有给出任何反馈对此。

我想知道如果不能满足条件(即,如果一个 localparam 小于另一个),是否有某种方法可以在综合(或模拟之前的编译)期间触发错误?可能相当于流行的 C/C++ compile-time-assert hack。

3个回答

我确信有一些方法可以在 C/C++ 编译时回调中绑定。但是,只要您支持generate块(在 IEEE Std 1364-2001 中引入),您就可以执行以下操作:

generate
if (CONDITION > MAX_ALLOWED /* your condition check */ ) begin
    illegal_parameter_condition_triggered_will_instantiate_an non_existing_module();
end
endgenerate

如果条件为真,那么编译器将给出错误,因为有一个不存在的请求。如果条件为假,则跳过该操作。唯一的要求是非法条件的代码遵循合法的 Verilog 语法,并且非法条件永远不会意外变为有效(因此长而冗长的不存在的模块名称)。

如果您的模拟器和综合工具支持 IEEE Std 1800-2009(2009 年发布的 SystemVerilog 修订版)或更新的修订版,那么您可以使用$error()并给出更有意义的消息来解决错误。我不确定是否有任何供应商已经实现了这个功能。一旦大多数供应商实施,它应该成为首选方法,因此我将举一个例子:

generate
if (CONDITION > MAX_ALLOWED /* your condition check */ ) begin
    $error("%m ** Illegal Condition ** CONDITION(%d) > MAX_ALLOWED(%d)", CONDITION, MAX_ALLOWED);
end
endgenerate

你可以这样做:

module test();

  parameter VALUE=16;

  // VALUE should be between 16 and 64
  wire [64:16] range_for_value;
  assign range_for_value[VALUE] = 1'b0;

endmodule

工具的处理方式可能略有不同,但如果VALUE不在预期范围内,它确实应该是一个错误,因为分配语句的位索引将超出range_for_value.

Verilog中真的没有像“断言”这样的东西吗?这是非常基本的东西!

如果您的工具支持混合语言,您可以添加一个模块,该模块只是一个 VHDL 实体,具有必要的端口或泛型以及明显的 ASSERT 语句。对于编译或细化时间可确定的条件,这在 sim 或综合中同样适用(至少在 XST 或 Synplicity 中)。

entity CheckSize is
   generic (depth : natural := 16);
   port (data : std_logic_vector);
end CheckSize;

architecture empty of CheckSize is
begin
   Assert depth * data'length <= 256 Report "Size too large!" 
      severity Failure;
end empty;

到目前为止,除了“System Verilog 2009”$error() 之外,没有一个答案是真正令人满意的,但这可能是最广泛的工具中最简单的。