什么时候换行符在 Verilog 编译器指令中有意义?

When are newline characters significant in Verilog compiler directives?

我正在尝试解析包括 Verilog 编译器指令在内的 Verilog 代码。 我的解析器目前坚持这样的指令通常以换行符结尾,例如

`ifdef foo <newline>

这是由于早期 Verilog 标准中没有对编译器指令的任何讨论,除了大致“指令可能出现在源代码中的任何地方”之外,我发现的所有示例都没有违反此规则。鉴于编译器指令可以说是受“C”的启发,并且 C 的指令必须以换行符结尾,这似乎是合理的。

我已经 运行 进入开源规范 a CPU 中的以下行,我相信这是经过彻底测试(即有效)的代码:

`ifdef PR_ERROR if ($time > 1 && rst_l) `PR_ERROR("dmu_ilu_cib_addr_decode",`MON_ERROR,"ERROR: Instance ID for module dmu_ilu_cib_csr is bad"); `endif

请注意 PR_ERROR 后没有换行符。这合法吗?

IEEE1800-2012 Verilog 标准文档有点难以解释。

第 639 页说

Only white space or a comment may appear on the same line as the `include compiler directive.

所以标准显然坚持为 `include.

换行

其他编译器指令没有类似的声明。 特别是,第 685 页讨论了 `ifdef`else`elsif`endif,并且只说:

These directives may appear anywhere in the source description.

如果一个人认为标准是明确的,不禁止的就是允许的, 有人可能认为此类指令不需要换行符。我很高兴看到明确的章节引用。

无论如何,编译器实际接受什么?

尽管 1800-2017 LRM 的 22.6 `ifdef, `else, `elsif, `endif, `ifndef 节说“这些指令可能出现在源代码描述中的任何位置。 ”,该部分的其余部分根据“行组”定义了行为。对该部分的严格解释意味着以下将 not 允许出现在一行中:

`ifdef A initial $display("A"); `else initial $display("not A"); `endif

然而,所有工具似乎都支持这一点。

但是与其他编译器指令的交互可能会产生歧义

`ifdef A `define X 2 `endif

如果A没有定义,是宏的 `endif部分未编译还是 `ifdef结束?

所以我的建议是将条件编译指令放在不同的行上。