这个问题是关于系统verilog宏的。
我有一个顶级模块、子模块和一个子子模块。在子模块中实例化的子模块在顶层模块中实例化。
如果我在子模块中定义一个宏`define abc
,里面写的代码`ifndef abc
会在顶层模块/子子模块中编译吗
这个问题是关于系统verilog宏的。
我有一个顶级模块、子模块和一个子子模块。在子模块中实例化的子模块在顶层模块中实例化。
如果我在子模块中定义一个宏`define abc
,里面写的代码`ifndef abc
会在顶层模块/子子模块中编译吗
`define
宏和大多数其他编译器指令的范围是一个编译单元。编译单元是编译器解析的源文本流。宏在它出现在编译单元中的位置被定义,并且从该位置开始可见。
由模块和其他命名空间定义的范围是无关紧要的,因为宏在任何 Verilog 或 SystemVerilog 语法被识别之前已经过预处理。这意味着您永远无法对宏定义进行特定于实例的控制。
Verilog 和 SystemVerilog 如何定义编译单元之间存在明显差异。
在 Verilog 中,每个编译单元都是一个编译步骤,或者是对编译源代码的工具的一次调用。有些工具只有一个编译步骤,需要您一步编译所有源代码。其他工具(例如 Modelsim)允许您在单独的步骤中编译您的代码。一个编译步骤中的`define
宏在任何其他编译步骤中都不可见,除非您重新定义它。
SystemVerilog 添加了将编译器命令行上的每个文件视为单独的编译单元的能力。这是必需的,因为 SystemVerilog 允许您在模块之外定义类型定义和函数等内容。将每个文件保留为单独的编译单元可防止命名冲突。(此编译单元行为在 C/C++ 中是相同的)。
由于人们将遗留 Verilog 代码与 SystemVerilog 混合的方式,一些工具允许您选择编译单元的 Verilog 或 SystemVerilog 行为。
除非您+define+...
在编译命令中使用,否则define
宏将根据编译顺序生效。一旦编译完成,它将被任何后续的代码或文件行占用,直到undef
满足相应的要求。
假设在您的情况下,编译顺序是:subsub.v
, sub.v
, top.v
(根据您的模块名称)。
假设 位于define abc
的第一行sub.v
,这abc
在 的任何后续行sub.v
以及在本例中为 的剩余文件中都有效top.v
,但不是subsub.v
。
因此,要回答您的问题, in 中的任何代码ifndef abc
都top.v
不会被编译。另一方面,ifndef abc
insubsub.v
将被编译。