SV学习笔记——数组、队列
一、定宽数组
定宽数组是静态变量,编译时便已经确定其大小,其可以分为压缩定宽数组和非压缩定宽数组:压缩数组是定义在类型后面,名字前面;非压缩数组定义在名字后面。Bit [7:0][3:0] name; bit[7:0] name [3:0];
1.1定宽数组声明
数组的声明有两种方式:
int array1 [15:0];//完整声明,表示array1[0]…array1[15]
int array2 [16];>//紧凑声明,表示array2[0]…array2[15]
多维数组的声明:
//多维数组如果位宽都在变量名的右边,那么左边的是高纬度而右边的是低维度。
//如下例所示,[7:0]表示的是高纬度,[3:0]表示的是低纬度。
int array3 [7:0] [3:0];//完整声明
int array4 [8] [4]; //紧凑声明
1.2定宽数组初始化
``
int array5[4] = '{0,1,2,3};//对4个元素初始化
int array6[5];
array6 = '{4,3,2,1,0};
array5 = '{4{8}};//四个值全部都是8
array6 = '{9,8,default:-1};//{9,8,-1,-1,-1}
1.3合并型数组和非合并型数组`
向量数组会分为两种数组,一种是合并型数组,另一种是非合并型数组,示例如下:
bit [3:0] [7:0] pack;//合并型数组,[3:0]是高纬度,而[7:0]是低维度
bit [7:0] unpack [3:0];//非合并型数组,[3:0]是高纬度,而[7:0]是低维度
合并型数组占用的存储空间如下:
非合并型数组占用的存储空间如下:
上图表示合并型数组pack占用了1个word的存储空间,而非合并型数组占用了4个word的存储空间。
1.4数组的基本操作(foreach循环)
在SV中引入了新的循环方式foreach,比for循环更加简洁。
代码示例:
bit [3:0] a1[5];
bit [4:0] a2[5];
initial begin
for(int i = 0; i < $size(a1); i++)begin //$size(a1)=5
a1[i] = i;
$display("a1[%0d] = %0d",i,a1[i]);
end
foreach(a2[j])begin
a2[j] = a1[j] * 2;
$display("a2[%0d] = %0d",j,a2[j]);
end
end
其中 s i z e ( ) 是系统函数,可以得到括号内的维度,默认是最高维度,想得到第二个维度的话就需要写成 size()是系统函数,可以得到括号内的维度,默认是最高维度,想得到第二个维度的话就需要写成 size()是系统函数,可以得到括号内的维度,默认是最高维度,想得到第二个维度的话就需要写成size(src,2),而对于 s i z e ( a 1 ) 的 a 1 而言,这是一个非合并型数组,所以右边的 5 是高纬度,因此 size(a1)的a1而言,这是一个非合并型数组,所以右边的5是高纬度,因此 size(a1)的a1而言,这是一个非合并型数组,所以右边的5是高纬度,因此size(a1)=5。
仿真结果
a1[0] = 0
a1[1] = 1
a1[2] = 2
a1[3] = 3
a1[4] = 4
a2[0] = 0
a2[1] = 2
a2[2] = 4
a2[3] = 6
a2[4] = 8
二、动态数组
2.1动态数组声明
定宽数组是固定了存储空间的一种数组类型,如果需要在程序运行的过程中对存储空间进行改变就需要动态数组。
动态数组在最开始的声明时,需要使用’[]'来表示,此时存储空间为0,而在后面程序运行过程中需要使用’new[]'来分配存储空间给数组使用。
代码示例:
int dynamic_array1[];//动态数组的声明
initial begin
dynamic_array1 = new[5];//给动态数组分配了5个元素的存储空间
end
2.2动态数组初始化
在分配完存储空间后,还需要对动态数组赋初值。
代码示例
int dynamic_array2[];//动态数组的声明
initial begin
dynamic_array2 = new[5];//给动态数组分配了5个元素的存储空间
foreach(dynamic_array2[i])begin
dynamic_array2[i] = i;//对元素初始化,即{0,1,2,3,4}
$display("dynamic_array2[%0d] = %0d",i,dynamic_array2[i]);
end
end
仿真结果:
在仿真开始前,动态数组里面的元素为空,即没有元素
在仿真开始后,对动态数组的初始化完成,{0,1,2,3,4}。
dynamic_array2[0] = 0
dynamic_array2[1] = 1
dynamic_array2[2] = 2
dynamic_array2[3] = 3
dynamic_array2[4] = 4
2.3动态数组操作(复制,删除)
代码示例:
int dynamic_array3[];//动态数组的声明
int dynamic_array4[];//动态数组的声明
initial begin
dynamic_array3 = new[5];//给动态数组分配了5个元素的存储空间
foreach(dynamic_array3[i])begin
dynamic_array3[i] = i;//对元素初始化,即{0,1,2,3,4}
$display("@1:dynamic_array3[%0d] = %0d",i,dynamic_array3[i]);
end
dynamic_array4 = dynamic_array3;//将dynamic_array3复制给dynamic_array4
foreach(dynamic_array4[j])begin
$display("@2:dynamic_array4[%0d] = %0d",j,dynamic_array4[j]);
end
dynamic_array3 = new[7](dynamic_array3);//重新分配了7个数值,并将旧的5个元素复制给新的
foreach(dynamic_array3[k])begin
$display("@3:dynamic_array3[%0d] = %0d",k,dynamic_array3[k]);
end
dynamic_array3 = new[9];//重新分配9个数值,而旧值不存在
foreach(dynamic_array3[l])begin
$display("@4:dynamic_array3[%0d] = %0d",l,dynamic_array3[l]);
end
dynamic_array3.delete();//删除所有元素
foreach(dynamic_array3[m])begin
$display("@5:dynamic_array3[%0d] = %0d",m,dynamic_array3[m]);
end
end
仿真结果:
@1:dynamic_array3[0] = 0
@1:dynamic_array3[1] = 1
@1:dynamic_array3[2] = 2
@1:dynamic_array3[3] = 3
@1:dynamic_array3[4] = 4
@2:dynamic_array4[0] = 0
@2:dynamic_array4[1] = 1
@2:dynamic_array4[2] = 2
@2:dynamic_array4[3] = 3
@2:dynamic_array4[4] = 4
@3:dynamic_array3[0] = 0
@3:dynamic_array3[1] = 1
@3:dynamic_array3[2] = 2
@3:dynamic_array3[3] = 3
@3:dynamic_array3[4] = 4
@3:dynamic_array3[5] = 0
@3:dynamic_array3[6] = 0
@4:dynamic_array3[0] = 0
@4:dynamic_array3[1] = 0
@4:dynamic_array3[2] = 0
@4:dynamic_array3[3] = 0
@4:dynamic_array3[4] = 0
@4:dynamic_array3[5] = 0
@4:dynamic_array3[6] = 0
@4:dynamic_array3[7] = 0
@4:dynamic_array3[8] = 0
三、队列
3.1队列的声明
队列可以在任何地方添加或者删除元素,这是数组无法做到的事情。
队列的声明是使用 符号,即 [ 符号,即[ 符号,即[],队列元素的索引是从0到$。队列也不需要new[]来创建空间,可以直接增加或者减少元素空间。
对于队列的一个简单使用就是通过其操作push_back()和pop_front()来实现FIFO,可以在仿真中模拟FIFO行为。
代码示例:
int queue1[$];
3.2队列的初始化
对队列进行初始化或者赋值时,不需要用到’。注意:在仿真开始之前,队列里是没有元素的,是仿真开始后,才会给队列分配存储空间。
代码示例:
int queue1[$] = {3,5,7};
initial begin
for(int i = 0;i < 3; i++)begin
$display("queue1[%0d] = %0d",i,queue1[i]);
end
end
仿真结果:
queue1[0] = 3
queue1[1] = 5
queue1[2] = 7
3.3队列的基本操作
代码示例:
int j = 4;
int queue1[$] = {3,5,8};
initial begin
queue1.insert(1,j);//{3,4,5,8}
for(int i = 0; i<$size(queue1); i++)begin
$display("@1:queue1[%0d] = %0d",i,queue1[i]);
end
queue1.delete(1);//{3,5,8}
for(int i = 0; i<$size(queue1); i++)begin
$display("@2:queue1[%0d] = %0d",i,queue1[i]);
end
queue1.push_front(2);//{2,3,5,8}
for(int i = 0; i<$size(queue1); i++)begin
$display("@3:queue1[%0d] = %0d",i,queue1[i]);
end
j = queue1.pop_back();//{2,3,5}
for(int i = 0; i<$size(queue1); i++)begin
$display("@4:queue1[%0d] = %0d",i,queue1[i]);
end
queue1.push_back(8);//{2,3,5,8}
for(int i = 0; i<$size(queue1); i++)begin
$display("@5:queue1[%0d] = %0d",i,queue1[i]);
end
j = queue1.pop_front();//{3,5,8}
for(int i = 0; i<$size(queue1); i++)begin
$display("@6:queue1[%0d] = %0d",i,queue1[i]);
end
end
仿真结果:
@1:queue1[0] = 3
@1:queue1[1] = 4
@1:queue1[2] = 5
@1:queue1[3] = 8
@2:queue1[0] = 3
@2:queue1[1] = 5
@2:queue1[2] = 8
@3:queue1[0] = 2
@3:queue1[1] = 3
@3:queue1[2] = 5
@3:queue1[3] = 8
## @4:queue1[0] = 2
@4:queue1[1] = 3
@4:queue1[2] = 5
@5:queue1[0] = 2
@5:queue1[1] = 3
@5:queue1[2] = 5
@5:queue1[3] = 8
@6:queue1[0] = 3
@6:queue1[1] = 5
@6:queue1[2] = 8
四、关联数组
4.1关联数组的声明
当需要创建超大容量的数组时,可以用关联数组来完成,相比于动态数组,动态数组在创建大容量时需要在最开始就确定存储空间,即使是没有使用到的内存,也会分配空间,而关联数组则可以只对需要的内存分配存储空间,这样可以节省占用内存空间。
代码示例:
bit [63:0] associate_array [int];//声明关联数组
4.2关联数组的初始化
代码示例:
bit [63:0] associate_array[int];
bit [63:0] index = 1;
initial begin
repeat(64)begin
associate_array[index] = index;
index = index <<1;
end
foreach(associate_array[i])
$display("associate_array[%0d] = %0d",i,associate_array[i]);
end
仿真结果(部分):
associate_array[1] = 1
associate_array[2] = 2
associate_array[4] = 4
associate_array[8] = 8
associate_array[16] = 16
associate_array[32] = 32
associate_array[64] = 64
associate_array[128] = 128
associate_array[256] = 256
associate_array[512] = 512
associate_array[1024] = 1024
associate_array[2048] = 2048
associate_array[4096] = 4096