system verilog在特定情况下禁用`ifndef阻塞

问题描述 投票:1回答:3

在系统verilog设计中,我有一个顶级模块,子模块和一个子子模块。在顶层模块中实例化的子模块中实例化的子子模块。顶层模块还有一个子子模块的实例。层次结构树如下所示

enter image description here

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

module sub_sub()
{
...........
`ifndef OFF
<code to avoid>
`endif
...........
}

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

system-verilog hdl compiler-directives
3个回答
2
投票

更干净的解决方案是传递参数并使用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。生成构造


1
投票

`定义宏的范围,以及大多数其他编译器指令是编译单元。编译单元是编译器解析的源文本流。宏在编译单元中出现的位置定义,从该点开始可见。

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

如果您希望特定于实例的代码控制,则需要使用特定于实例的覆盖来定义参数。然后,您可以使用generate-if / case结构来控制要执行的代码。如果generate构造对你来说限制太多,你可以使用procedural-if / case语句,优化将删除不作为常量参数的结果的分支。


0
投票

最好的方法是使用其他答案中建议的参数修改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中受支持。

© www.soinside.com 2019 - 2024. All rights reserved.