(二)SV数据类型、数组

一、数据类型

1、在Verilog中,数据类型分为两类:variable型和net型,且均为四值逻辑。

2、在System Verilog中,数据类型有两个属性:type和data type,

  • type表明该数据是variable型还是net型;
  • data type表明数据是4值逻辑和2值逻辑

3、SV中用logic代替reg,wire,方便使用,但logic只能有一个驱动,当信号有个多个驱动时,不能定义为logic,如双向总线,只能使用线网类型,如wire。

4、若未赋予初值:logic 类型:默认返回X;int 或bit:默认返回0;

类型分类:

1、按逻辑类型分:

四值逻辑类型:integer(32位)、reg、logic、net-type(例如wire、tri)
二值逻辑类型:byte、shortint(16位)、intbit、longint(64位)

2、按符号类型分:

有符号类型:byte、shortint、int、longint、integer
无符号类型:bit、logic、reg、net-type(例如wire、tri)

说明:

  • 1、若把有符号数赋值给无符号数,会把符号位当做实际值来赋值,所以加强制转换类型unsigned('a);如:有符号数和无符号数的相互转换
program test;
byte  a = 8'b1000_0000;
byte  a1;
bit [7:0] b1 = 8'b0011_1000;
bit [7:0] c1 = 8'b1000_0001;
bit [8:0] b,c;
bit [7:0] d;
initial begin
    //把有符号数赋值给无符号数
	$display("a=%0d",a);
	$display("a=0x%x",a);
	b=a;
	$display("b=%0d",b);
	$display("b=0x%x",b);
	c=unsigned'(a);
	$display("c=%0d",c);
	$display("c=0x%x",c);
	d=a;
	$display("d=%0d",d);
	$display("d=0x%x",d);
	
    //把无符号数赋值给有符号数
	$display("b1=%0d",b1);
	$display("b1=0x%x",b1);
	$display("c1=%0d",c1);
	$display("c1=0x%x",c1);

	a1=b1;
	$display("a1=%0d",a1);
	$display("a1=0x%x",a1);
	a1=c1;
	$display("a1=%0d",a1);
	$display("a1=0x%x",a1);	

	a1=356;//a1只有8bit位宽,超过的高位被舍去,溢出
	$display("a1=%0d",a1);
	$display("a1=0x%x",a1);

end
endprogram

打印结果:
a=-128(以补码形式存储)
a=0x80
b=384
b=0x180
c=128
c=0x080
d=128
d=0x80
b1=56
b1=0x38
c1=129
c1=0x81
a1=56
a1=0x38
a1=-127(以补码形式存储)
a1=0x81
a1=100
a1=0x64
  • 2、若四值逻辑赋值给二值逻辑,X给二值逻辑是0,若位宽不匹配(最好保持位宽一致),由低位到高位赋值;若一个数不写位宽默认为32位,如'h10

二、数组

 1、定宽数组:

一维数组:
int  array[0:15];  //16个整数[0],[1]……[15]
int  array[16];     //16个整数[0],[1]……[15]
二维数组:
int array[0:1][0:2];                      
int array[2][3]=' {'{0,1,2}, '{3,4,5}}; //紧凑声明并初始化(注意初始化需要加符号 ' 来标识

2、合并数组、非合并数组

合并数组:   bit [3:0][7:0] array1;

非合并数组:bit [7:0] array2[0:3];

说明:

  • 两者在内存中存储方式不同,array1在内存只在连续的存储空间上占用一个字(只占用一个int),而array2在内存是在不连续的存储空间上占用一个字(占用4个int).

3、 动态数组:

         在程序执行之前不知道数组宽度,可以用[ ]留空来定义动态数组。此时数组最开始是空的,但在调用之前,必须用new[ ]来指定宽度

module test;
    int dyn[], d2[];          //声明动态数组,此时相当于定义了动态数组的指针(句柄)
    initial begin             
    dyn=new[5];               // 分配5个元素和对应内存空间,默认值为0
    foreach(dyn[j]) dyn[j]=j; // 对元素进行初始化
    d2=dyn;                   //复制一个动态数组,只是复制了数组的值,并没有复制地址
    d2[0]=5;                  //更改元素的值
    $display(d2);             
    $display(dyn);            
    dyn=new[20](dyn);         //分配20个整数值并进行复制, 新的数组的开始5个数用旧的元素覆盖
	$display(dyn);
    dyn=new[100];             //分配100个新的元素, 旧值不复存在
	$display(dyn);
    dyn.delete();             //删除所有元素
end
endmodule

4、队列

SV引入对列,结合了链表和数组的优点,可以在队列中的任何地方添加或者删除元素;队列的声明使用[$],元素的编号从0到$;队列索引可以使用相应函数或者用q[0:$]、q[$:其他]:把$放在一个范围表达式的左边,那么$代表最小值;把$放在一个范围表达式的右边,那么$代表最大值。对列的赋值与数组不同没有符号“   '   ”。

module test;
    int j=1,
    q2[$]={3,4},
    q[$]={0,2,5};     //声明队列,并初始化一些元素
    initial begin
    q.insert(1, j);   // 在q队列的第二个元素(排列位置从0开始数)之前插入j,// 队列q变成{0,1,2,5}
    q.insert(3,q2[0]);//在q队列的第四个元素(排列位置从0开始数)之前
    q.insert(4,q2[1]);// 插入队列q2的元素,队列q变成{0,1,2,3,4,5}
    $display(q);
    q.delete(1);     //删除第1个元素(排列位置从0开始数), 队列变成{0,2,3,4,5}
    q.push_front(6); //在队列前插入6, q队列变成{6,0,2,3,4,5}
    j = q.pop_back;  //把最后一个元素pop出来,赋值给j, j=5, q队列变成{6,0,2,3,4}
    q.push_back(8);  //在队列尾部插入8, q队列变成{6,0,2,3,4,8}
    j = q.pop_front; //把第一个元素pop出来,赋值给j, j=6, q队列变成{0,2,3,4,8}
    foreach (q[i])
    $display(q[i]);  //打印整个队列
    q.delete();      //删除整个队列
end
endmodule

三、数组操作

 1、for与foreach

module test;
	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]);//i为外循环,j为内循环
	for(int i;i<2;i++)
		for(int j;j<3;j++)
			$display("md[%0d][%0d]=%0d",i,j,md[i][j]);//结果与上面相同
	end
endmodule

打印结果
Initial value:
md[0][0]=0
md[0][1]=1
md[0][2]=2
md[1][0]=3
md[1][1]=4
md[1][2]=5
md[0][0]=0
md[0][1]=1
md[0][2]=2
md[1][0]=3
md[1][1]=4
md[1][2]=5

说明:

  • 在foreach循环中只需要指定数组名并在其后方括号中给出索引变量,SV会自动遍历数组中的元素。索引变量将会自动声明,并只在循环内收敛。

 2、  复制

1、对于数组复制,可以利用赋值符号“=”直接进行数组的复制。

module test;
    bit [31:0] src[5] = ‘{0,1,2,3,4},
    dst[5];
    dst = src;    // 数组复制
    src[0] = 5;   // 只改变一个元素的值
    $display(dst);//打印dst,看其是否得到了src的值,元素[0]是旧的值还是新值;
    $display(src);//打印src,看是否改变了src[0]的值
endmodule

3、比较

在不使用循环的情况下,也可以利用“==”或者“!=”来比较数组的内容,比较结果是比较数组中所有元素的位置和内容的结果若要得到数组中的某元素是否相等,可以用for或者foreach遍历数组中的元素,并进行比较

program test10;
    bit [31:0] src[5] = '{0,1,2,3,4},dst[5] = '{5,1,2,3,4};
    initial begin
        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])?"==":"!=");
    end
endprogram


打印结果:
src != dst
src == dst
src[1:4] == dst[1:4] 

四、打印转义字符说明:

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值