1、定宽数组的声明和初始化
(1)需要给出数组的上下界,因为下界索引几乎都是0,可用更便捷的方式来表示。
例如:
int exa[16]; //和下述数组宽度一致
int exa0[0:15];
位与数组的下标
在Verilog中,reg、wire等变量索引是位的下标,往往是从大到小,即[15:0],因为从左往右是从高位到低位,是指一个数据的类型。
SV中数组的下标意义不同,数组是一个个元素的集合,往往是从左往右是从0到16。
(2)设置多维数组
int array1[0:7][0:3];
int array2[8][4];
//上述两种都是表示8行4列的数组
array1[7][3]=1; //设置最后一个元素为1
注意:当越界读取数据时,四状态类型(如logic)返回X,双状态类型(int、bit)返回0。适用于所有数组类型(定宽数组、动态数组、关联数组、队列)。
2、常量数组
用单引号加大括号来初始化数组,例:
int a[4] = `{0,1,2,3}; //对四个元素进行初始化
int a[4] ;
a = `{0,1,2,3}; //同上对数组进行赋值
a[0:1] = `{2,4,3}; //为前三个元素赋值
a = `{4{8}}; //四个值全部为8
a = `{9,8,default:1}; //{9,8,1,1}
//定义多维数组:
int md[2][3] = `{`{1,2,3},`{3,4,5}};
3、基本的数组操作_for\foreach
在SV中,$size函数返回数组的宽度,数组常见的操作方式就是for、foreach循环。
initial begin
bit[31:0] src[5],dst[5]; // 数据类型为bit型,32位
for(int i=0;i<$size(src);i++) //i为for循环中的局部变量
src[i] = i;
foreach(dst[j]) //遍历整个数组
dst[j] = src[j]*2; //dst的值是src的两倍
end
针对foreach对多维数组的操作,形式为[i,j].例:
int md[2][3] = `{`{1,2,3},`{3,4,5}}; //定义2X3 的多维数组
initial begin
$display("Initial value:"); //输出
foreach(md[i,j]) //正确的语法格式
$display("md[%0d][%0d] = %0d",i,j,md[i][j]);
end
//完成对整个数组的遍历
foreach和for的转换:以int a[4];为例,foreach(a[i]) 等于 for(int i=0;i<=4;i++)。
4、数组的复制和比较
可以在不使用循环的情况下进行聚合比较和复制(聚合操作适用于整个数组而不是单个元素),只限于等于比较或不等于比较。操作符?:
例:
initial begin
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所有元素复制dst
src[0] = 5;
//所有元素是否相等
$display("src %s dst",(src==dst)?"==":"!="); //在display函数里使用?:
//对每个元素进行逐个比较
$display("src[1:4] %s dst[1:4]",(src[1:4]==dst[1:4])? "==":"!=");
end
5、合并数组
声明:合并的位和数组大小必须在变量名前指定。数组大小的定义格式必须[msb:lsb].
//合并数组的声明和用法
bit[3:0][7:0]bytes; //四个字节组装成32比特
bytes=32'hCafe_Data;
&display(
bytes,, //显示所有字节
bytes[3],, //最高位字节“CA”
bytes[3][7]); //最高位比特位“1”
@操作符只能用于标量或者合并数组。