SV的数据类型

对SystemVerilog语言数据类型做一个总结,详细全面的介绍可以翻阅绿皮书

一、内建数据类型

  • 相对于Verilog将寄存器类型reg和线网(net)类型,如wire,SV中引入了logic数据类型。
  • Verilog便硬件描述,所以注重的是声明的变量是寄存器类型还是线网类型。
  • SV偏验证,不关心logic对应逻辑应该被综合成为寄存器类型还是线网类型,只会作为单纯的变量进行赋值。
  • logic类型为四值逻辑,分别是0、1、x、z。x代表不确定,可能为0也可能为1;z代表高阻态,表示没有被驱动。四值逻辑可以看作是硬件的世界。
  • bit类型为二值逻辑,分别是0、1。二值逻辑可以看作是软件的世界。

四值逻辑

  • integer
  • logic
  • reg
  • net-type(wire、tri)

二值逻辑

  • byte
  • short int
  • int
  • long int
  • bit

有无符号划分

  • 有符号:byte、short int、int、long int、integer
  • 无符号:bit、logic、reg、net-type(wire、tri)

在编码时操作符左右两侧符号类型要保持一致

显式转换

  • 静态转换:在转换的表达式前面加上单引号,该方式不会对转换值做检查
  • 动态转换:$cast(src,dst), 转换失败会在仿真的时候报错

隐式转换

logic[3:0] a = 4'b111x;
bit[2:0] b;
b = a;		//b的值应该为110,四值赋值给二值逻辑类型时,x变成0,z也会变成0

在不同类型进行操作时要注意:

  1. 逻辑数值类型:是四值还是二值
  2. 符号的类型
  3. 矢量的位宽

二、定宽数组

数组声明

int lo_hi[0:15];	//16个int类型元素

int c_style[16];	//C语言风格

多维数组声明和使用

int array2[0:7][0:3];	//完整声明
int array3[8][4];		//紧凑声明

array[7][3] = 1;			//给最后一个元素赋值为1

初始化和赋值

//声明的同时,对4个元素初始化
int ascend[4] = '{0,1,2,3};		

//声明和赋值分开操作
int descend[5];
descend = '{4,3,2,1,0};

//4个值全部赋值为8
ascend = '{4{8}};

//部分元素使用默认赋值
descend = '{9,8,default:-1};		//{9,8,-1,-1,-1}

存储空间考量

二值逻辑
bit[3][7:0] b_pack;		//合并型
bit[7:0] b_unpack[3];	//非合并型

对于bit[3][7:0] b_pack;每一个元素都是8bit,一共有3个元素,3*8=24bit,因为是合并型,所以占用一个WORD空间就够了。

对于bit[7:0] b_unpack[3];因为是非合并型,每一个元素占用一个WORD空间,但是有效空间只有8bit。
在这里插入图片描述

四值逻辑类型
logic[3][7:0] l_pack;		//合并型
logic[7:0] l_unpack[3];		//非合并型

四值逻辑类型有四种值,所以需要2bit来表示。

对于logic[3][7:0] l_pack;因为是合并型,每一个元素有8bit,一共有3个元素,每种值得用2bit来表示,所以832=48位,用2个WORD空间足以。

对于logic[7:0] l_unpack[3];因为是非合并型,每个元素占用8bit,而四值逻辑得用2bit表示,所以一个元素8*2=16位,用一个WORD足以放下一个元素,所以需要3 * WORD=3WORD的空间。

基本数组操作for和foreach循环

initial begin
	bit[31:0] src[5], dst[5];
	for(int i = 0; i < $size(src); i++)		//for循环进行赋值
		src[i] = i;
	foreach(dst[i])							//foreach循环遍历,所有值都乘2
		dst[j] = src[j] * 2;
end

赋值和比较

  • 赋值:阻塞赋值“=”,非阻塞赋值“<=”
  • 比较:等于“==”, 不等于“!=”

三、动态数组

  • 定宽数组:宽度编译时确定
  • 动态数组:运行时再确定宽度

动态数组声明时用[],之后使用new[]来分配空间

四、队列

  • 队列可在任何地方添加、删除元素,并且通过索引实现对任一元素的访问,这一点和C/C++、java语言的队列不相同,其他语言的队列只能是先进先出,从队列头取元素,在队尾添加元素。
  • 队列的声明使用[$],队列元素的标号从0到 $ 。
  • 队列不需要new[]来创建空间。
  • 可用push_back()和pop_front()二者结合实现FIFO的用法。

五、关联数组

当使用超大容量的数组时,使用关联数组会更好一些。动态数组面临超大容量的情景,可能存在着浪费的情况,因为很有可能该大容量数组中有相当多的数据不会被存储和访问。而关联数组可以用来保存稀疏矩阵的元素,该数组只为实际写入的元素分配空间。
在这里插入图片描述

bit[63:0] assoc[int], idx = 1;
repeat(64) begin
	assoc[idx] = idx;
	idx = idx << 1;		//1,2,4,8,···
end

六、结构体

Verilog没有数据结构,而在SV中可以使用struct语句创建结构。struct只是一个数据的集合,伴随typedef可以用来创建新的类型。

typedef struct{bit[7:0] r,s,b} pixel_s
pixel_s my_pixel;
my_pixel = '{'h10, 'h10, 'h10};

七、枚举类型

enum经常和typedef搭配使用

typedef enum{INIT,DECODE,IDLE} fsmstate_e;

fsmstate_e pstate,nstate;
case(pstate)
	IDLE: nstate = INIT;		//枚举类型可复制给整型,但是整型赋值给枚举类型时需要做转化
	INIT: nstate = DECODE;
	default: nstate = IDLE;
endcase

八、字符串

使用string来保存和处理与字符串相关的处理,字符串格式化函数$sformatf().
string s为空是指的“ ”,而不是c语言中的“\0”.

string s = "IEEE ";
s.getc(0);					// I
s.tolower()					// ieee
s.putc(s.len()-1, "-")		// 将末尾的空格替换成了“-”
s = {s, "P1800"};			// 拼接字符串 IEEE-P1800
s.substr(2,5);				// EE-P
$sformatf("%s %5d", s, 42)	//格式化,生成临时字符串返回
  • 5
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值