systemverilog允许行与尾随" \"连接,这通常与tick("`")预处理器命令一起使用。所以以下两组定义是相同的:
`define A(b) b + \
5
`define A(b) b + 5
同样,在下面的代码中,X和P的定义应该是相同的。唯一的区别是一个版本使用" \"而另一个版本没有。
`define Y
`define X(a) `ifdef Y \
`define Z a+2 \
$display(`Z); \
`endif
`define P(a) `ifdef Y `define R a+2 $display(`R); `endif
module m();
initial begin
`X(5) // expands as: $display(5+2);
$display(`Z); // expands as: $display(5+2);
`P(7) // expansion was empty, but no error reported
$display(`R); // this reports an error: cyclical definition of R
end
endmodule
但是,正如评论所提到的,其中一个版本不适用于商业模拟器。所以我的问题是:为什么第二个版本错了," \"的语义究竟是什么?用于连接连续的行,特别是在`define和其他预处理器命令中使用的上下文中?
答案 0 :(得分:2)
在define
之后写入的任何内容被视为宏名称并且在宏名称之后的空格之后任何被视为宏值/文字。可选的形式参数用大括号分隔,如下所示。
text_macro_definition :: =`define text_macro_name macro_text
text_macro_name :: = text_macro_identifier [( list_of_formal_arguments )]
list_of_formal_arguments :: = formal_argument {, formal_argument}
formal_argument :: = simple_identifier [ = default_text]
text_macro_identifier :: = identifier
此处,为了成功编译,您必须将define R a+2
视为一行,将$display
视为另一行。模拟器本身不会理解何时结束定义宏值以及何时开始另一条$display
行。
它作为一个赋值扩展并显示在一行中:
// Actual expansion
<macro> R = a+2 $display(R);
// Intended expansion
<macro> R = a+2 // assign value to R
$display(R); // then display R
如果不止一个 如果需要行来指定文本,则换行符前面应加一个反斜杠(\)。
此代码中的问题是 define
R
没有分隔符。因此R
被定义为完整a+2 $display(R)
。现在,如果我们添加\
,那么模拟器会理解它是一个新行,因此它会将$display
视为编译时的下一个语句。
`define P(a) `ifdef Y `define R a+2 \
$display(`R); `endif
有关详细信息,请参阅IEEE 1800-2012 Sntax 22-2。