首页 > 解决方案 > 在 SystemVerilog 中包含警卫

问题描述

我有一个包含在包含保护中的verilog头文件。它包含一些我用来在其他 rtl 文件中定义本地参数的函数。此包含文件在模块描述(模块(端口实例化)`include....(主体)端模块)中被引用。我一直认为,当 verilog 编译每个模块时,该包含的范围将是该模块的本地范围,它只会在模块内强制执行保护。我现在一直在编译项目中的所有模块,似乎第二次在另一个模块中引用了包含项,防护仍然处于打开状态。这与预处理器对 systemverilog 的行为方式有关吗?

标签: system-verilog

解决方案


Verilog 对其编译的文件具有粘性语义。这意味着如果您在命令行上有多个文件,则在一个文件中定义的宏也会在另一个文件中定义。

影音

`include "h.vh"
`define A_V 1

BV

`include "h.vh"
...
assign A = `A_V;

因此,如果您按以下顺序编译宏 A_V,则可以在文件 bv 中使用它们:a.v, b.v.

因此,如果h.vh使用保护宏,它只会被解析为包含在 av 中,而将被保护在 bv 中而不被解析。

现在假设您在 h.vh 中包含函数参数的定义:

`ifndef H_VH
`defien H_VH
paremeter I = 10;
`endif

它被包含在模块主体中:

影音

module A;
`include "h.vh"
assign A = I;
endmodule

BV

module B;
`include "h.vh"
assign B = I;
endmodule

现在,当文件A首先包含在模块中时,参数现在在模块中定义A。但是宏 H_VH 也被定义了。包含文件将不会在“bv”文件中被第二次解析。因此,将其包含在模块中不会扩展到参数定义并且编译失败,因为没有I可用的。

如果文件包含在模块之外的全局范围内,verilog 中的 Guard 宏很有用。如果包含在范围内,它们会产生很多问题。经验法则是将它们用于全局包含的标头,如果标头包含在范围内,则永远不要使用它们。永远不要混合全局和范围包含。

是的,正如大家已经提到的那样,在系统 verilog 中,您最好为此使用包。在常规的 verilog 中,您没有其他选择来确定通用声明的范围。


推荐阅读