目录
SV中引进的数据类型和其优点:
1、双状态数据类型:更好性能,更低的内存消耗
2、队列、动态和关联数组:减少内存消耗,自带搜索和分类功能
3、类和结构:支持抽象数据结构
4、联合和合并结构:允许对同一数据有多种视图
5、字符串:支持内建的字符序列
6、枚举类型:方便代码编写,增加可读性
1、内建数据类型(新增数据类型logic、bit)
1、 前言:SV中引入新的数据类型logic可替代reg和wire,SV作为侧重于验证的语言,并不十分关切logic对应的逻辑应该被综合位寄存器还是线网,因为logic被使用的场景如果是验证环境,它只会作为变量进行赋值操作。
2、但是不能用在双总线和多驱动的情况下,此时只能使用网线类型,例如wire。除此之外,在验证环境中可用logic替代reg和wire。
3、logic虽然只是表示数据类型,而在声明时,它默认会表示变量类型(variable),用户也可以显式声明其类型;
var logic [63: 0] addr; // a 64-bit wide variable
wire logic [63: 0] data; // a 64-bit wide net
4、与logic(四值)相对应的是bit(二值)类型,均可以构建矢量(即有方向)类型(vector)。
5、按四值逻辑的类型和二值逻辑的类型划分:
四值逻辑类型:integer、logic、reg、net-type(例如wire)
二值逻辑类型:byte、shortint、int、longint、bit
按有无符号的类型划分:
有符号类型:byte、shortint、int、longint、integer
无符号类型:bit、logic、reg、net-type(例如wire)
bit a ; // 两态,单比特
bit [31: 0] b32 ; // 两态,32比特无符号
int c32 ; // 两态,32比特有符号
byte d8 ; // 两态,8比特有符号
shortint e16 ; // 两态,16比特有符号
longint f64 ; // 两态,64比特有符号
在SV中,数据类型可以分为线网(net)和变量(variables)。线网的赋值设定,与Verilog的要求相同,即线网赋值只能使用连续赋值语句(assign),而不能出现在过程块(initial / always);相比于线网驱动的限制,变量(var)类型的驱动要求就没那么多了。
避坑:可以在tb中大量使用logic类型变量,而很少使用wire。什么时候需要wire?多于一个驱动源的时候,或者设计模块端口是双向(inout)的时候;
2 、定宽数组
Verilog中是一维的定宽数组reg[7:0] ,SV中提供多样数组类型和功能。
2.1 定宽数组的声明和初始化
// 允许直接给出宽度的方式
int lo_hi[0:15];
int c_style[16];
// 多维数组声明和赋值
int array2[0:7][0:3]; //完整声明 左高维度右低低纬度 左行右列 8行4列
int array3[8][4]; //紧凑声明
array2[7][3]=1; // 赋值最后一个元素
若读取越界地址值,返回数组元素类型的默认缺省值.四状态类型,如logic返回X,双状态类型如bit返回0。线网如果没有驱动则返回Z。
2.2 SV两种类型的数组以及其存储方式
SV引入两种类型的数组:压缩数组(packed array)和非压缩数组(unpacked array)。
压缩数组指的是维数的定义在变量标识符之前,非压缩数组指的是维数的定义在变量标识符之后,
bit [7:0] cl; // 压缩数组(比特类型) //8行1列的一位数组
real u [7:0]; // 非压缩数组(实型)
存储空间考量
下面的两个变量,都可以表示24bit的数据容量,那么从实际硬件容量的角度出发,那种方式的存储方式更小呢?已知SV存放数组元素时使用32bit字边界。
bit [3][7:0] b_pack; // 3*8 合并型packed 3行7列
bit [7:0] b_unpack[3]; // 3*8 非合并型unpacked 3行7列
从上图可以得到b_unpack实际会占据3个WORD的存储空间,但是b_pack指挥占据一个WORD的存储空间
2.3 常量数组
初始化:一个单引号加大括号。
int ascend[4] `{0,1,2,3};
int descend[5];
descend = `{4,3,2,1,0}
descend[0:2] =`{5,6,7};
descend = `{4,8};
descend = `{9,8,default:1};
2.4 基本数组操作–for和foreach
操作数组的最常见方式是使用for和foreach循环。
$size 函数返回数组宽度。
在foreach循环中只需要指定数组名并在其后面方括号中给出索引变量,便会自动遍历数组元素。
示例:
initial begin
bit[31:0] src[5],dst[5];
for(int i=0;i<$size(src);i++)
src[i]=i;
foreach(dst[j])
dst[j] = src[j] *2; //
end
对于foreach遍历索引多维数组,不是像[i][j]分开放,而是在同一个括号里[i,j]。
int md[2][3] =`{`{0,1,2},`{3,4,5}};
initial begin
$display("Initial value:");
// 多维数组正确索引格式
foreach(md[i,j])
$display("md[%0d][%0d] = %0d",i,j,md[i][j]);
$display ("new value:");
// 对最后三个元素赋值5
md = `{`{9,8,7},`{3{32`d5}}};
// 遍历
foreach(md[i,j])
$display("md[%0d][%0d] = %0d",i,j,md[i][j]);
end
foreach循环会遍历原始申明中的数组范围
2.5 复制和比较
2.6同时使用位下标和数组下标
不常用