本教程将介绍新引入Systemverilog的数据类型。他们大多数是可综合的,而且使得RTL级描述更易于被编写和理解。
SystemVerilog 引入了几种新的数据类型。C语言程序员会熟悉其中的大多数。引进新的数据类型构思是这样的,如果C语言和SystemVerilog有相同的数据类型的话可以使C语言算法模型更容易的转化为SystemVerilog模型。
Verilog的变量类型是四态类型:即0,1,X(未知值)和Z(高阻值)。SystemVerilog新引入了两态的数据类型,每一位只可以是0或者1。当你不需要使用的X和Z值时,譬如在写Testbench和做为For语句的循环变量时。使用两态变量的RTL级模型,可以使仿真器效率更高。而且使用得当的话将不会对综合结果产生任何的影响。
两态整型
类型 | 描述 | 例子 |
bit | 用户定义大小 | bit [3:0] a_nibble; |
byte | 8 bits, unsigned(无符号) | byte a, b; |
shortint | 16 bits, signed(有符号) | shortint c, d; |
int | 32 bits, signed(有符号) | int i,j; |
longint | 64 bits, signed(有符号) | longint lword; |
注意:和C语言不一样,SystemVerilog指定了一些固定宽度的数据类型。
四态整型
类型 | 描述 | 例子 |
reg | 用户定义大小 | reg [7:0] a_byte; |
logic | 和reg完全相等 | logic [7:0] a_byte; |
integer | 32 bits, signed(有符号) | integer i, j, k; |
logic是一种比reg型更好更完善的数据类型。我们将会看到,你可以使用logic型来替代过去您有可能使用reg型或wire型的地方。
非整数类型
类型 | 描述 | 例子 |
time | 64-bit unsigned | time now; |
shortreal | like float in C | shortreal f; |
real | like double in C | double g; |
realtime | identical to real(等同于real) | realtime now; |
在Verilog-1995中,你可以定义标量或是矢量类型的线网和变量。你也可以定义一维数组变量类型的存储器数组。在Verilog-2001中允许多维的线网和变量数组存在,并且取消了部分存储器数组用法的限制。
SystemVerilog进一步完善了数组的概念,并对数组重新进行了定义,从而允许对数组进行更多的操作。
在SystemVerilog中,数组可以有压缩尺寸或是非压缩尺寸的属性,也可以同时具有两种属性。考虑下面的例子:
reg [3:0][7:0] register [0:9];
压缩尺寸是[3:0]和[7:0],非压缩尺寸是[0:9] 。(只要你喜欢可以有任意大小的压缩尺寸和非压缩尺寸)
压缩尺寸:
1)保证将在存储器中产生连续的数据
2)可以复制到任何其他的压缩对象中
3)可切片("部分选取")
4)仅限于位类型(bit, logic, int等),其中有些(如int)有固定的尺寸
相比之下,非压缩数组在内存中的排列方式由仿真器任意选定。我们可以可靠地复制非压缩数组到另一个具有相同数据类型的数组中。对于不同数据类型的数组,你必须使用强制类型转换(有几个非压缩数组转换到压缩数组的规则)。 其中非压缩数组可以是任意的类型,如实数数组。
SystemVerilog允许对完整的和部分选取的非压缩数组进行一些操作。其中,部分选取的数组必须是相同的数据类型和大小——即非压缩数组必须要有相同的位数和长度。而压缩数组的规则不是这样,只要选取的部分有相同大小的位数即可。
允许的操作有:
1)读和写数组
2)读和写数组的片断
3)读和写数组的可变片断
4)读和写数组的一个元素
5)数组或数组片断的相等操作
SystemVerilog也支持动态数组(在仿真中数组长度可以改变)和关联数组(数组中的数据非连续排列)。
为了支持这些数组类型,SystemVerilog中提供了一些数组查找的函数和方法。譬如你可以使用$dimensions函数查询一个数组变量的维数。
动态数组是一维的非压缩数组,它的尺寸可以在运行时设置或改变。动态数组的存储空间只有当数组在运行时被显式产生之后才会存在。
动态数组的声明语法如下:
data_type array_name [];
其中data_type是数组元素的数据类型。 动态数组与固定尺寸数组支持相同的数据类型。例如:
bit [3:0] nibble[]; // 4位向量的动态数组
integer mem[]; // integer类型的动态数组
关联数组的声明语法如下:
data_type array_id [index_type];
其中:
SystemVerilog允许自定义复杂的数据类型。为了使代码看起来清晰,引进了typedef的方法。Typedef的方法允许使用者在他们的代码中自定义名字经常使用的数据类型的名称,当构造复杂的数组时用Typedef的方法非常方便。
这和reg [7:0] b;的效果是一致的
这和reg [3:0][7:0] qBytes [1:10];的效果是一致的
SystemVerilog还引入了枚举类型,例如
enum { circle, ellipse, freeform } c;
枚举适用于表示状态值、操作码和其它的象征性数据。
Typedef和枚举经常一起使用,用法如下:
typedef enum { circle, ellipse, freeform } ClosedCurve;
ClosedCurve c;
枚举类型命名值的作用类似于常数,它的默认类型是int。枚举类型是强制类型。除非您使用强制类型转换,否则您无法复制一个数值到枚举类型变量。
c = 2; //错误
c = ClosedCurve'(2); // Casting – okay
但是,当你在一个表达式中使用了枚举类型,你所使用的值等效于整型数; 所以例子中的枚举变量与整数的比较是正确的;而且它也可以在整数表示式中使用枚举值。
同样, SystemVerilog 也引入了结构体和共同体,和C语言类似。
struct {
int x, y;
} p;
结构体成员选择使用 .name的语法。
p.x = 1;
结构体的表达可以使用括号。
p = {1,2};
结构体在使用typedef声明新的结构类型和使用新的类型声明变量时是非常有用的。注意结构体也是可以被封装的。
typedef struct packed {
int x, y;
} Point;
Point p;
共同体在用相同的硬件资源 (如寄存器)储存不同类型的值(如整数、浮点)时候是非常有用的。
文章评论(0条评论)
登录后参与讨论