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 进行许可。转载请注明出处!