1. 字符串内的宏变量替换
在 Verilog 中,宏定义通常不能在字符串中进行变量替换,字符串中的宏变量会被视为普通文本。然而,SystemVerilog 允许在字符串中进行宏变量的替换,这是通过使用(`)(重音符号)来实现的。
Verilog 中的宏文本替换(不支持变量替换)
在 Verilog 中,字符串内嵌入宏时,宏变量无法替换为实际的值。例如:
1 |
|
这在 Verilog 中是有效的,但无法在双引号中的文本部分进行宏变量替换。也就是说,双引号中的 "variable v = %h"
将始终是固定的字符串,而不会替换 v
变量为其实际的值。
SystemVerilog 中的宏文本替换(支持变量替换)
- 经过我的实验,发现在Verilog中也是生效的,不知道是不是编译器的问题。
在 SystemVerilog 中,可以通过在形成字符串的引号前加上 `` ` (键盘tab键位上面的那个键)来实现宏文本中的变量替换。例如:
1 | `define print(v) \ |
在这里,print(data)
将把宏 v
替换为实际的变量 data
,并生成以下内容:
1 | $display("variable data = %h", data); |
- 其中,
"variable v = %h"
是一个字符串,v
会被替换为data
的值。
2. 转义字符的使用
当字符串中需要嵌入双引号时,在 Verilog 中,必须使用转义字符(\
)来处理。例如:
1 | $display("variable \"data\" = %h", data); |
这里,\"
用来表示在字符串中嵌入双引号,避免它们被解释为字符串的结束符。
但是,在 SystemVerilog (Verilog中同样的用法)中进行宏文本替换时,字符串的宏变量替换功能会使得普通的转义字符不再足够,需要使用额外的转义字符 \''
来嵌入宏变量。
示例:嵌入双引号
1 | `define print(v) \ |
这里,'
符号用于将宏 v
包含在双引号中,确保在显示时能够正确地输出带双引号的 v
变量名。
展开的代码:
1 | $display("variable "data" = %h", data); |
这样,宏 v
被正确地替换为 data
,并且变量名 v
被双引号包围。
3. 宏连接生成新的标识符
在 Verilog 中,宏定义无法通过连接多个文本宏来动态创建新的标识符,因为宏定义的文本中会存在空格(因为要和之前的字符分开才能是一个新的,比如sdf v
,这样才能替换v成宏变量,不然还是sdfv)。然而,SystemVerilog 提供了一种方法来实现文本的连接,允许多个宏组合成新的标识符,且不会引入空格。
Verilog 中的限制
在 Verilog 中,如果你试图通过两个或多个宏连接来创建新的标识符,通常会遇到空格分隔问题,导致生成无效的标识符(在宏文本中,"
作为不引入空格的分隔符,感觉没啥用)。例如,下面是 Verilog 的无效代码:
1 |
这段代码想通过宏 name
连接多个部分,但实际上在 name"_bit
和 name"_net
中,name
和 "_bit"
之间会被空格隔开,导致无法生成有效的标识符。
SystemVerilog 中的增强功能
SystemVerilog 提供了两个连续的重音符号(``)来进行连接操作,避免了空格的产生。例如:
1 | `define TWO_STATE_NET(name) \ |
通过两个连续的重音符号 ```,我们可以将 name
和 _bit
(或 _net
)连接起来,避免了空格的插入。这允许我们在宏中创建动态生成的标识符。
示例:生成多态的变量和网
假设我们需要定义多个 bit
类型的变量和相应的 wand
类型网,并将变量持续赋值给网。我们可以使用以下宏来简化代码:
1 | `define TWO_STATE_NET(name) \ |
通过这个宏,我们可以自动生成多个变量和网的定义,而无需手动编写每一行:
1 | bit d00_bit; wand d00_net = d00_bit; |
注意:硬撇号(’)不同于重音符号(`)
本文链接: https://talent-tudou.github.io/2024/12/21/DV/SystemVerilog中宏文本替换功能的扩展/
版权声明: 本作品采用 CC BY-NC-SA 4.0 进行许可。转载请注明出处!