目录
SystemVerilog对Verilog的拓展:
- 使用typedef建立用户自定义类型。
- 使用enum建立枚举类型。
4.1 typedef
-
对比
Verilog SystemVerilog 主要用于RTL和门级建模,没有提供类似C语言的高级抽象建模的变量类型 为系统级和体系结构级建模加入了许多新的数据类型,允许通过typedef关键字使用现有数据类型建立用户自定义类型。 例子:自定义类型
typedef int unsigned uint;//利用现有数据类型(int unsigned)建立用户自定义类型(uint) ... uint a, b;
-
用户自定义类型的位置:
-
在局部定义。
-
包内定义。
-
编译单元域$unit.
-
在包中定义然后导入到$uint。
例子:在包中定义然后导入到$uint。
//包声明 package chip_types `ifdef TWO_STATE typedef bit dtype_t; `else typedef logic dtype_t; `endif endpackage //导入定义到$uint import chip_types::dtype_t; //模块声明 module counter ( output dtype_t[15:0] count, input dtype_t clock ); always @(posedge clock, negedge resetN) if (!resetN) count <= 0; else count <= count + 1; endmodule
-
-
命名习惯提示:使用“_t”作为用户自定义类型的结尾,增加代码可读性与便于维护。
4.2 枚举数据类型
-
定义:
枚举数据类型提供一种方式来声明一个具有特定允许值列表的抽象变量,每一个值都有一个确定的用户自定义的名字(label)。
例子://具有red, green, blue三个label的枚举变量RGB enum {red, green, blue} RGB;
-
对比:
Verilog SystemVerilog 没有枚举类型,通过parameter或者宏定义实现标签值。无法限定信号的有效值(比如状态机的状态)的有效值仅仅是自定义的有效状态。 增加了枚举类型,将一个变量的取值范围限制在有意义的label上。 -
注意:
- 当枚举类型定义从package中导入时,只有类型名被导入。
- 为了使枚举类型的label可见,可以显式导入每个label,或者使用通配符导入。
4.2.1 指定枚举类型标签序列的方式:
方式 | 说明 |
---|---|
state | 创建单个名为state的标签。 |
state[N] | 创建名为state0,state1,…,stateN的标签序列。 |
state[N,M] | N<M时,创建名为stateN,stateN+1,…,stateN的标签序列。N>M时,创建名为stateN,stateN-1,…,stateN的标签序列。 |
例子:
enum {RESET,S[5],W[6:9]} state;//label列表为:RESET,S0,...,S5,W6,...,W9。
4.2.2 枚举类型标签作用域:
枚举类型列表中的标签在同一个作用域必须是唯一的。
4.2.3 枚举类型值:
- 缺省的情况下,从零开始递增。中间缺省的情况下,从前一个已说明的数值开始递增。
- 允许显式说明值,但是值必须唯一。
例子:enum {A,B,C=5,D,E} list;//标签值为:A=0,B=1,C=5,D=6,E=7。
4.2.4 枚举类型标签值的类型:
- 默认为int类型。
- 可以显示定义基类,但是标签值得符合基类得取值范围和位宽。
- 如果X或者Z赋值给枚举列表中的一个标签,下一个标签必须显式赋值。以此类推,如果再下一个也没有显式赋值也必须显式赋值。
例子:enum {A = 3'b001, B = 3'b010, C = 3'b100} list;//错误,位宽不对 enum logic {A1 = 1'b0, B1, C1} list1;//错误,标签数超过基类所能代表得宽度。
4.2.5 自定义和匿名枚举
由typedef声明的枚举类型称为自定义枚举类型,不适用typedef定义的则称为匿名枚举类型。
4.2.6 枚举类型操作的强类型检验
- 枚举类型合法的赋值:
- 值为枚举类型列表中的一个标签。
- 同类枚举类型的其他变量。
- 通过cast系统函数转换成枚举类型变量的数值。
例子:
typedef enum {WAIT, LOAD, READY} state_t;
state_t state, next_state;
int foo;
foo = 1;
state = WAIT;//合法,值为枚举类型列表中的一个标签。
state = next_state;//合法,同类枚举类型的其他变量。
$cast(state, foo);//合法,通过cast系统函数转换成枚举类型变量的数值。
state = foo; //非法
state = state + 1;//非法
state++;//非法
next_state += state;//非法
4.2.8 枚举类型的专用系统任务和方法
- <枚举变量名>.first;//返回第一个成员的值。
- <枚举变量名>.last;
- <枚举变量名>.next();//返回列表中下N个成员的值,如果到了末尾则会返回到列表开头。
- <枚举变量名>.prev();
- <枚举变量名>.num;//返回列表元素个数。
- <枚举变量名>.num;//返回这个值对应的label,字符串。
4.2.9 打印枚举类型
$display("\nCurrent state is %s(%b)",state.name,state);