一、数据类型
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位)、int、bit、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]