【路科V0】systemVerilog基础5——数组声明与数组操作

数组声明

非组合型(unpacked)

特点:消耗更多的存储空间,但是更易于查找元素 

对于Verilog,数组经常会被用来做数据存储,例如

reg [15:0] RAM [0:4095] ;//存储数组

SV将Verilog这种声明数组的方式称之为非组合型声明即数组中的成员之间存储数据都是互相独立的。
Verilog也不会指定软件去如何存储数组中的成员。

wire [7:0] table [3:0];

【路科V0】systemVerilog基础5——数组声明与数组操作_第1张图片

        SV保留了非组合型的数组声明方式,并且扩展了允许的类型,包括event,logic,bit,byte,int,longint,shortreal和real类型。
        SV也保留了Verilog索引非组合型数组或者数组片段的能力,这种方式为数组以及数组片段的拷贝带来了方便。

int a1 [7:0][1023:0];//非组合型数组
int a2 [1:8][1:1024];//非组合型数组
a2 = a1;// 拷贝整个数组
a2[3] = a1[0];// 拷贝一个数组片段

 声明数组的方式,以下两种皆可

logic [31:0] data [1024]; //指定内部元素个数
logic [31:0] data [0:1023];//指定元素索引值范围

组合型(packed) 

优点:与非组合型相比,更节省空间 

 SV将Verilog的向量作为组合型数组声明方式

wire [3:0] select; // 4比特的组合型数组
reg [63:0] data; //64比特的组合型数组
//组合型数组,该数组的每一个元素均为1比特

SV也进一步允许多维组合型数组的声明

logic [3:0][7:0] data; //2维组合数组
//索引范围声明在左侧
//数组的维度,从左到右来识别

 定义结构体的存储方式

        组合型(packed)除了可以运用的数组声明,也可以用来定义结构体的存储方式

typedef struct packed {
logic [ 7:0] crc;
logic [63:0] data;} data_word;
data_word [7:0] darray;// 1位组合型数组,元素也为组合型结构体

        组合型数组和其数组片段也可以灵活选择,用来拷贝和赋值等

logic [3:0][7:0] data;//2维组合型数组
wire [31 :0] out = data;//整个数组wire sign = data[3][7];//单个比特
wire [3:0] nib = data [0][3:0];//数组片段byte high_byte;
assign high_byte = data[3]; // 8比特的数组片段logic [15:0] word;
assign word = data[1:0];// 2个数组片段

数组操作 

初始化

 组合型(packed)数组

 组合型(packed)数组初始化时,同向量初始化一致:

logic [3:0][7:0] a = 32’ h0;//向量赋值
logic [3:0][7:0] b = {16’ hz,16’ h0};//连接运算符
logic [3:0][7:0] c = {16{2’ b01}} ; //复制运算符

非组合型(unpacked)数组

非组合型(unpacked)数组初始化时,则需要通过’{ }来对数组的每一个维度进行赋值。

int d [0:1][0:3]= ’ { ’{7,3,0,5},’{2,0,1,6} };
//d[0][0]=7
//d[0][1]=3
//d[0][2]=0
//d[0][3]=5
//d[1][0]=2
//d[1][1]=0
//d[1][2]=1
//d[1][3]=6

赋值

 非组合型数组

         非组合型数组在初始化时,也可以类似结构体初始化,通过’{ }和default关键词即可以完成

int a1 [0: 7][0:1023]= ’ {default:8’h55} ;

        非组合型数组的数据成员或者数组本身均可以为其赋值

byte a [0:3]10:3];
a[1][0] =8’h5;//为单个元素赋值
a[3] = ’{’hF, ’ hA, ’ hC, ’ hE};//给数组片段中的所有元素进行赋值

组合型数组

        以下是组合型数组的赋值方法

logic [1:0][1:0][7:0] a; //3维数组
a[1][1][0] = 1’b0; // 为1比特赋值
a = 32’hF1A3C5E7;//给整个数组赋值
a[1][0][3:0] =4’hF; //给一个数组片段赋值
a[0] = 16’hFACE;//给一个数组片段赋值
a = {16’bz,16’b0} ; //通过连接运算符赋值

拷贝

组合型数组

        对于组合型数组,由于数组会被视为向量,因此当赋值左右两侧操作数的大小和维度不相同时,也可以做赋值
        如果当尺寸不相同时,则会通过截取或者扩展右侧操作数的方式来对左侧操作数赋值。

bit [1:0][15:0] a; // 32位2值逻辑向量
logic [3:0][7:0] b; //32位4值逻辑向量
logic [15:0] c; // 16位4值逻辑向量
logic [39:0] d; //40位4值逻辑向量
b = a; // 32位数组赋值给32位数组
c = a;//高16位被截断
d = a; //高8位填充为0

非组合型数组

        对于非组合型数组,在发生数组间拷贝时,则要求左右两侧操作数的维度和大小必须严格一致。

        这是由于非组合型数组的元素都是独立存放的。

logic [31:0] a [2:0][9: 0];
logic [0:31] b [1:3][1:10];
a = b; //非组合型数组赋值于非组合型数组

非组合型数组无法直接赋值给组合型数组,同样地,组合型数组也无法直接赋值给非组合型数组。

foreach循环结构

SV添加foreach循环来对一维或者多维数组进行循环索引,而不需要指定该数组的维度大小。

int sum [1:8] [1:3];
foreach ( sum[i,j] ) sum[i][j] = i +j; //数组初始化

foreach循环结构特点: 

  • foreach循环结构中的变量无需声明
  • foreach循环结构中的变量是只读的,其作用域只在此循环结构中

系统函数

$dimensions(array_name)//用来返回数组的维度。
$left(array_name,dimension)//返回指定维度的最左索引值(msb)
$right(array_name,dimension)
$low(array_name,dimension)
$high(array_name,dimension)

$size(array_name,dimension)//可以返回指定维度的尺寸大小。
$increment(array_name,dimension)//如果指定维度的最左索引值大于或等于最右索引值,那么返回1,否则返回-1。
$bits(expression)//可以用来返回数组存储的比特数目。

举例: 

logic [1:2][7:0] word [0:3][4:1];
//$left (word,1) will return 0
//$left (word,2) will return 4
//$left (word,3) will return 1
//$left(word,4) will return 7
wire [3:0][7:0] a [0:15];// $bits(a)返回512
struct packed {[byte tag; logic [31:0] addr;} b;// $bits(b)返回40

你可能感兴趣的:(数字验证,数字验证,systemVerilog)