Verilog系列:【26】define和typedef
typedef是SystemVerilog引入的一种简化类型定义的关键字,例如在一些程序中将integer定义为INT等,而define主要用于定义一些在设计过程中不经常修改的宏,例如位宽WIDTH等.本文将针对两种方式分类示例说明.
1 define
格式:
define执行于预编译阶段,不做任何正确性检查,只进行(不关心其具体含义)文本替换,即在对设计进行编译之前完成设计中所有的宏替换.在宏定义完成后,如果需要使用相应的宏定义,那么宏名前要是用“`”,编译器将会对“`”开始的宏名进行文本替换.macro_text后可以使用“//”注释,注释部分不会作为macro_text的一部分.这里需要注意一点的是定义的宏可以有参数,其中的参数将会在进行文本替换时将macro_text中对应的参数替换掉.宏定义具体使用的一般过程如下:
-
在调用宏时,首先对参数进行检查,如果存在宏名一样的符号将会被替换;
-
替换文本并插入到对应的程序中,此时参数名将被他们的值所代替;
-
最后对结果文本进行扫描;
【示例】
在具体使用define传递参数时,define仅进行文本替换,如果参数传递过程中没有合理的使用括号对参数进行处理,那么计算结果可能与预期的不相符.这里还需要注意参数列表的括号必须与宏名紧邻,如果两者之间存在任何空白,参数列表就会被解释为被替换文本的一部分.
【示例】
仿真结果如下:
综上所述,在使用define时还需要注意以下几点:
-
define是编译命令中的一种,在Verilog中不属于关键字,所以可以作为一般标识符使用,但是不建议使用define作为标识符;
-
同一个宏名可以被define多次,但是只有被编译器最近一次获取到的一次为有效定义,即前几次被最近一次覆盖;
-
define可以引用之前define的宏,但是不允许嵌套;
-
可以使用反斜线分行显示;
- 采用命名约定,使程序员容易看出标识符是否为宏名,并且能够表示所代替的内容的大致意义;
-
2 typedef
格式:
【示例】
仿真结果如下:
从上述仿真结果可以观测到define对应的数据类型为integer,即typedef指定的INT.
typedef使用过程中需要注意以下几点:
-
typedef一般是为了隐藏特定类型的实现,强调使用类型的目的,简化复杂类型的声明;
-
typedef可简化复杂的类型定义,使其更易理解;
-
允许一种类型定义多个typedef,例如:
typedef INT1 integer
typedef INT2 integer
-
对于同样的类型标识符在同一个作用域中只能typedef一次,例如:
typedef INT integer
typedef INT int //not allowed
-
使用前置类型的typedef声明,即是将类型的定义滞后于具体类型的声明,但是在使用时必须保证声明和定义处于同一个作用域中;
【示例】
仿真结果如下:
3 define与typedef异同
| define | typedef |
| 执行阶段:预编译阶段 | 执行阶段:编译阶段 |
| 非关键字 | 关键字 |
| 简单的文本替换,不做正确性检查 | 类型别名,不是宏替换 |
| 定义必须先于使用出现 | 可以使用前置typedef方式,即定义可以滞后于声明 |
| 无作用域限制,但是需要注意适用范围 | 无作用域限制,但是需要注意适用范围 |
| 可以相互引用,但是后续宏定义引用的宏必须在当前宏定义之前已经定义 | 可以使用前置typedef方式实现相互引用 |


查看16道真题和解析