在系统verilog设计中,我有一个顶级模块,子模块和一个子子模块。在顶层模块中实例化的子模块中实例化的子子模块。顶层模块还有一个子子模块的实例。层次结构树如下所示
子模块定义有一些代码写在'ifndef块中,就像这样
module sub_sub()
{
...........
`ifndef OFF
<code to avoid>
`endif
...........
}
如何在编译期间禁用代码以避免仅在子子模块instance1中?我在子模块实例中使用`define OFF但是它禁用了代码以避免所有实例。
更干净的解决方案是传递参数并使用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。生成构造
`定义宏的范围,以及大多数其他编译器指令是编译单元。编译单元是编译器解析的源文本流。宏在编译单元中出现的位置定义,从该点开始可见。
模块和其他命名空间定义的范围无关紧要,因为在识别任何Verilog或SystemVerilog语法之前会对宏进行预处理。这意味着您永远不能对宏定义进行实例特定控制。
如果您希望特定于实例的代码控制,则需要使用特定于实例的覆盖来定义参数。然后,您可以使用generate-if / case结构来控制要执行的代码。如果generate构造对你来说限制太多,你可以使用procedural-if / case语句,优化将删除不作为常量参数的结果的分支。
最好的方法是使用其他答案中建议的参数修改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
在这种情况下,我当然假设你能够编辑你的top
和sub
模块。请注意,嵌套模块仅在system-verilog
中受支持。