系统verilog在特定实例中禁用`ifndef块

Posted

技术标签:

【中文标题】系统verilog在特定实例中禁用`ifndef块【英文标题】:system verilog disabling `ifndef blocks in specific instances 【发布时间】:2016-11-10 16:47:54 【问题描述】:

在系统 verilog 设计中,我有一个***模块、子模块和一个子子模块。 sub-sub 模块在 sub-sub 模块中实例化 在 sub-sub 模块中实例化在 top 模块中。top 模块也有 sub-sub 模块的实例。层次结构树如下所示

子子模块定义有一些代码写在这样的'ifndef块中

module sub_sub()

...........
`ifndef OFF
<code to avoid>
`endif
...........

如何在编译期间仅在子子模块实例1中禁用代码以避免? 我在子模块实例中使用了`define OFF,但它从所有实例中禁用了代码以避免

【问题讨论】:

【参考方案1】:

更简洁的解决方案是传递一个参数并使用 generate-if/case 语句。示例:

module sub_sub #(parameter OFF=0) ( ... );
  generate
    if (OFF) begin
      <code to avoid>
    end
  endgenerate
endmodule

module sub ( ... );
  ...
  sub_sub #( .OFF(1'b1) ) inst ( ... );
endmodule

module top ( ... );
  ...
  sub inst0 ( ... );
  sub_sub #( .OFF(1'b0) ) inst1 ( ... );
endmodule

从技术上讲,if (OFF) 不需要在显式 generate-endgenerate 中;否则推断。建议使用它以提高人类可读性。

有关生成块的完整详细信息,请参阅IEEE Std 1800-2012 § 27。生成构造

【讨论】:

【参考方案2】:

`define 宏和大多数其他编译器指令的范围是一个编译单元。编译单元是编译器解析的源文本流。宏在它出现在编译单元中的位置被定义,并且从该位置开始可见。

模块和其他命名空间定义的范围无关紧要,因为宏在任何 Verilog 或 SystemVerilog 语法被识别之前已经过预处理。这意味着您永远无法对宏定义进行特定于实例的控制。

如果您希望对代码进行特定于实例的控制,则需要使用特定于实例的覆盖来定义参数。然后你可以使用 generate-if/case 结构来控制你想要执行的代码。如果 generate 构造对您来说过于严格,您可以使用procedural-if/case 语句,优化将删除由于常量参数而未采用的分支。

【讨论】:

【参考方案3】:

最好的方法是使用其他答案中建议的参数修改您的 sub_sub 模块。 但是,如果您无法编辑/修改 sub_sub 模块,这可能不切实际,例如,它可能是加密 IP。

在这种情况下,一种解决方案是为每个sub_sub 模块创建包装器嵌套模块。你可以这样做:

// Wrapper for sub_sub with OFF defined
module sub_sub_wrapper1;
  `define OFF
    `include "sub_sub.v"
  `undef OFF
endmodule

// Wrapper for sub_sub without OFF defined
module sub_sub_wrapper2;
  `include "sub_sub.v"
endmodule

////////////////

module sub;
  sub_sub_wrapper1 subsub1();
endmodule

module top;
  sub sub1();
  sub_sub_wrapper2 subsub2();
endmodule

Quick sample

在这种情况下,我当然假设您能够编辑您的topsub 模块。请注意,嵌套模块仅在 system-verilog 中受支持。

【讨论】:

以上是关于系统verilog在特定实例中禁用`ifndef块的主要内容,如果未能解决你的问题,请参考以下文章

生成块中的系统 Verilog 参数

Verilog学习笔记基本语法篇········ 生成块

verilog的行为级描述和RTL级描述有啥区别

在 Visual Studio 中禁用特定代码块的代码格式

verilog语句执行顺序的疑问?

是关于verilog状态机的问题 在always 时钟块的一个状态中,系统如何运行阻塞赋值? 代码如下: