SystemVerilog学习笔记---01基础语法

SystemVerilog

数据类型

内建数据类型


在这里插入图片描述

延续Verilog的语法,增加新的数据类型。

在verilog中,数据类型分为两类:variablenet

variable:reg,integer,time等

net:wire,wor,wand等

在systemVerilog中,**数据类型有两个属性:**type、datatype

type表明该数据是variable或net型

datatype表明数据的值是4值或2值。

vartable型数据既可以是4值逻辑也可以是2值逻辑,但是net型只能是4值逻辑。

SV推出了新的数据类型logic、bit

​ logic为4值逻辑:0、1、x、z

​ bit为2值逻辑:0、1(在某种不需要不定值x和阻塞值z的情况下使用,节省空间)

4值逻辑:integer、reg、logic、net-type(wire等)

2值逻辑:byte、shortint、int、longint、bit

有符号类型:byte、shortint、int、longint、integer

无符号类型bit、logic、reg、net-type

默认大小和值: bit:1为2值的整数

byte:8位2值的整数,类似char类型

shortint:16位2值整数,类似short类型

int:32位2值整数,类似int型

longint:64位2值整数,类似longlongint类型

在systemverilog中,使用关键字logic类型代替reg类型,logic单独使用是位4值逻辑。

logic类型的数据赋给bit型:

​ 高位宽的数据赋给低位宽:从高到低舍弃,不定值x变为0;

​ 低位宽赋给高位宽:从高到低补充0;


常用数据类型

数组
一维数组
一维数组:int lo_hi[0:15];	16个整数[0],[1],...,[15]
​		int c_style[15];	16个整数...
多维数组:int array[0:1][0:2];	完整声明,直接在声明时定义大小
​		int array[2][3]='{'{0,1,2},'{2,3,4}};
初始化前访问数组返回值:logic:x,bit、int:0;

如果试图从一个越界的地址中读取数据,那个SV将会返回数组元素的缺省值。对于一个元素为四状态类型的数组,例如logic,返回的是X,而对于双状态类型,例如int或bit,则返回0。这适用于所有的数组类型,包括定宽数组、动态数组、关联数组和队列,也同时适用于地址中含有X或Z的情况。线网在没有驱动的时候输出Z。
合并数组
合并数组
	当需要把数据当成一个整体访问时,同时又可以把它分为更小的单元,此时需要合并数组。例如一个32bit的寄存器,有时候可以当成4个8bit的数据,有时候可以堪称一个无符号数据。
bit [3:0][7:0] bytes;
bytes = 32'haabb_ccdd;
$display("%h",bytes);	//整个32位bit,32‘haabb_ccdd
$display("%h",bytes[3]);	//最高位byte,8’haa
$display("%h",bytes[3][7]);		//最高bit位,8'haa=8'b1010_1010;
其中Byte[3]中的数据aa是byte型,相当于c中的char

*

非合并数组
非合并数组
不需要把数组当作一个整体来访问
声明:bit[7:0] b_unpack[3]; //3字节

在这里插入图片描述

动态数组
动态数组
在执行程序前不知道数组宽度,可以用[]预留空定义动态数组
数组为空,但是调用前必须用new[]来指定宽度
int dyn[],d2[];		//声明2个动态数组
initial begin
    dyn=new[5];		//为数组dyn分配5个空间
    foreach(dyn[j]) dyn[j]=j;		//遍历dyn,并且把0-4赋给dyn
	d2=dyn;			//把dyn数组复制给d2
    d2[0]=5;		//把d2中的0位置元素更改为5
    dyn=new[20](dyn);	//复制dyn并且为dyn分配20个空间,把dyn的前5个空间用dyn[0-5]覆盖
    dyn=new[100];	//分配100个新的元素,旧值不存在
    dyn.delete();	//删除数组
	end
常量数组
常量数组
常量数组用一个‘+{}来初始化数组
  int  ascend[4] = `{0, 1, 2, 3};    // 对4个元素进行初始化
  int descend[5];
  descend[0:2] = `{5,. 6, 7};     // 为前3个元素赋值
  ascend = `{4{8}};         // 四个值全是8
  descend = `{9, 8, default:1};    // {9, 8, 1, 1, 1}

使用数组下标和位下标
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XvrGyiTV-1692507609608)(C:\Users\史飞洋\AppData\Roaming\Typora\typora-user-images\1682407424260.png)]

src[5]=00000101,00000101,00000101,00000101,00000101
src[0]:00000101
src[0][0]:00000101中最后一位1
src[0][2:1]:00000101中10

关联数组类似于哈希表,一个索引对应一个数组值

基本数组操作
foreach循环
对多维数组使用foreach时,并不是像[i][j]这样把每个下标分别放在不同的括号里,而是用逗号隔开放在同一个方括号里,像[i, j],如foreach(md[i, j]) begin ... end
	bit[31:0] src[5],dst[5];
	for(int i=0;i<$size(src);i++)
        src[i]=i;		//初始化src
	foreach(dst[j])
        dst[j]=src[j]*2	//dst的值是src值的2倍

在这里插入图片描述

如果不需要便利数组中所有的维度,可以在foreach的循环中忽略它们,如下所示把一个二维数组打印成一个方形的阵列。它在外层循环中便利第一个维度,然后再内层遍历第二个维度。
在这里插入图片描述

复制

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4FMulKqY-1692507609620)(C:\Users\史飞洋\AppData\Roaming\Typora\typora-user-images\1682411818189.png)]
数组的复制可以直接用数组名进行复制

比较

​ 在不使用循环的情况下,也可以利用“==”或者“!=”来比较数组的内容,不过结果仅限于 内容相同或者不相同。

bit [31:0] src[5] = ‘{0,1,2,3,4},
dst[5] = ‘{5,4,3,2,1};
if (src==dst) $display("src == dst"); // 比较数组
else $display("src != dst");
dst = src; // 数组复制
src[0] = 5; // 只改变一个元素的值
//所有元素是否相等
$display("src %s dst",(src==dst)?"==":"!=");
//使用数组片段对第1-4个元素进行比较
$display("src[1:4] %s dst[1:4] ",(src[1:4]==dst[1:4])?"==":"!=");


若要得到数组中的每个元素是否相等,可以用for循环遍历数组的每一个元素,并进行比较。

bit [31:0] src[5] = ‘{0,1,2,3,4},
		   dst[5] = ‘{5,4,3,2,1};
dst = src; // 数组复制
src[0] = 5; // 只改变一个元素的值
for(int i=0; i<$size(src); i++) begin
	if (dst[i]==src[i])
		$display("src[%d] == dst[%d]",i,i);
	else
		$display("src[%d] != dst[%d] ",i,i);
end

在这里插入图片描述

若要得到数组中的每个元素是否相等,可以用foreach循环遍历数组的每一个元素,并进行比 较。

bit [31:0] src[5] = ‘{0,1,2,3,4},dst[5] = ‘{5,4,3,2,1};
dst = src; // 数组复制
src[0] = 5; // 只改变一个元素的值
foreach(dst[i]) begin
	if (dst[i]==src[i])  $display("src[%d] == dst[%d]",i,i);
	else  $display("src[%d] != dst[%d] ",i,i);
end

在这里插入图片描述
关联数组

int arr[string];
arr=`{"1s":'h12',
	  "2nd":'h23'}
arr["1s"]
队列

队列的基本操作

  • 队列的声明是使用带美元符号的下标:[ ] 。队列元素的编号从 0 到 ]。队列元素的编号从0到 ]。队列元素的编号从0。队列的常量中只有大括号而没有数组常量中开头的单引号。注意不要对队列使用构造函数new[ ]

  • 队列在声明以后,只能通过索引或方法两种方式进行初始化。

  • 队列的方法有insert 、pop_front、push_back、delete等。

  • 如果把 放在一个范围表达式的右边,则代表最大值,如果 放在一个范围表达式的右边,则代表最大值,如果 放在一个范围表达式的右边,则代表最大值,如果放在一个范围表达式的左边,则代表最小值。队列的常量不需要” “初始化.

队列的插入和删除可以用函数也可以用**“位拼接符{}”**

在这里插入图片描述

结构体

关键字struct的功能少,它只是一个数据的集合,其通常的使用的方式是将若干相关的变量组合到一个struct结构定义中。

struct {bit [7:0] r, g, b;} pixel; // 创建一个pixel结构体
//为了共享该类型,通过typedef来创建新类型
typedef struct {bit [7:0] r, g, b;} pixel_s;
//为了便于硬件使用,还有压缩格式:
typedef struct packed {bit [7:0] r, g, b;} pixel_s;
非压缩结构体
typedef struct{
bit [7:0] r;
bit [7:0] g;
bit [7:0] b;
} pixel_t;
压缩结构体
typedef struct packed{
bit [7:0] r;
bit [7:0] g;
bit [7:0] b;
} pixel_t;

typedef struct {
bit [7:0] r;
bit [7:0] g;
bit [7:0] b;
} pixel_s;
pixel_s my_pixel; // 声明变量
my_pixel = '{'h10,'h10,'h10}; //结构体类型的赋值
typedef struct packed{
bit [7:0] r;
bit [7:0] g;
bit [7:0] b;
} pixel_s;
pixel_s my_pixel; // 声明变量
体会压缩结构体中 带' 和 不带' 的赋值的区别
my_pixel = {8'h10, 8'h10, 8'h10}; //结构体类型的赋值 相当于拼位操作符
my_pixel = '{8'h10, 8'h10, 8'h10}; //结构体类型的赋值 常量赋值方式

非压缩结构体

在这里插入图片描述

压缩结构体
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J9mUxUd9-1692507609638)(C:\Users\史飞洋\AppData\Roaming\Typora\typora-user-images\1682414778397.png)]
r [23:16] g [15: 8] b [ 7: 0]

  • 在压缩结构体中,不加“ ”的“ {} ”赋值相当于拼位操作符,如果赋值时不加位宽,则数据为默认结构体中属性的类型位宽,例如bit [7:0] g,赋值’h10,则十六进制的10相当于10000,只能取到后两位00,因为bit类型默认是2位宽。
union联合—图片加载失败
  • 结构体联合时,需要注意的是两个结构体指向了同一块区域,当一个结构体的值改变之后,其实是它所指向的那片内存中的值改变了,故另一个结构体打印出来的是已经改变的值,还需要注意的是不论在何时,SV代码中变量的类型、默认类型和位宽都需要注意
枚举类型
  • 枚举类型创建一种相关但是独立的常量,例如状态机中的状态或者指令中的操作码。可以自动为列表中的常量分配不同的数值,其值必须在{min,max}中,注意定义枚举类型时的位宽所能比表示的最大值和最小值,其默认是int型常量
typedef enum{init,decend,idle} fsmstate_e;
//声明枚举类型,其中init默认为0,decend为1,idle为2.
fsmstate pstate;创建一个枚举类型的变量
typedef enum{first=1,second,third} ordinal_e//初始化错误
ordinal_e postion;//postion缺省值为0,故first赋值为1是错误的。

typedef enum{ad=0,first=1,second} ordinal_e;
oedinal_e postion;//初始化正确。
string字符串—未写
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值