SV芯片验证之定长数组

声明:本内容来自于学习路科验证发布在B站上的免费视频课程后的笔记

一、非组合型数组unpacked array

1、在verilog中,数组经常会被用来存储数据

reg [15:0] RAM [0:4095];

//RAM是数组名,[0:4095]是元素,表示有4096个元素,每个元素有16位。reg是元素的类型

2、在SV中,就将上面这种方式声明的数组称之为非组合型数组它表示数组中的成员之间存储的数据是相互独立

wire [7:0] table [3:0]; //有4个元素,每个元素有8个bit。这些元素的类型是线网类型。

3、在SV中,它保留了verilog中非组合型数组的声明方式,同时也扩展了一些类型:event、logic、bit、byte、int、longint、shortreal、real。它也保留了verilog索引非组合型数组和数组片段的方式,这种方式为数组和数组片段的拷贝带来了方便。

int a1 [7:0] [1023:0];

int a2 [1:8] [1:1024]; //[1:8]是高维,[1:1024]是低维

a2 = a1; //复制一整个数组

a2[3] = a1[0]; //此处的a2[3]等同于a2[3][1:1024],表示将右边a1的1024个元素赋值给左边的a2的1024个元素

4、 声明非组合型数组的方式

logic [31:0] data [1024];

logic [31:0] data [0:1023];

此处不理解,我的理解是应该为8个和16个?

int arr1 [7:0][3:0]占据了32个word(32-bit)空间;int是2值逻辑

integer arr2 [8][4]会占据64个word(32-bit)空间;integer是4值逻辑

 

二、组合型数组packed array

1、在SV中,将verilog的向量作为组合型数组的声明方式。

wire [3:0] select; //4-bit的组合型数组。select是数组名

reg [63:0] data;

2、多维组合型数组声明:维度在数组名的左边;从左到右,高维-->低维

logic [3:0][7:0] data;

//2维组合型数组。理解成data有4个元素,每个元素的位宽是8位。

数组data在软件中需要2个字word(32-bit)来存储。因为logic是四值逻辑,每一位有0,1,x,z四种值。

bit [3:0][7:0] data2; 

数组data2在软件中用1个字word(32-bit)来存储的。因为bit是二值逻辑,每一位只有0,1两种值。

3、组合型也可以用来声明定义结构体的存储方式

typedef struct packed {

   logic [7:0] crc;

   logci [63:0] data;

} data_word;

data_word [7:0] array;

因为声明了packed,所以crc和data的数据是连续存储的;如果没有声明packed,那么crc和data的数据是分开存储的

4、组合型数组和其数组片段可以被用来拷贝赋值

logci [3:0][7:0] data;

wire [31:0] out = data;

wire sign = data [3][7]; //将data数组的第4个元素中的第8位赋值给sign。

wire [3:0] nib = data [0][3:0];//data数组的第1个元素的前4位赋值给nib。

logic [15:0] word;

assign word = data[1:0]; //切片后赋值,data数组的第1和第2个元素赋值给16-bit的word。

5、混合型数组:先看右边的[3:0][4:0]里的左边的[3:0]是高维,[4:0]是低维;然后看左边的[1:0][2:0]里的[1:0]是高维,[2:0]是低维。

int [1:0][2:0] arr [3:0][4:0]; //4维数组,从高到低的维度是:4x5x2x3

三、数组的初始化

1、组合型数组初始化和向量初始化相同

logic [3:0][7:0] a = 32'h0; //向量赋值

注:非组合型数组不能如上所示赋值,因为它的数据存储方式是非连续性的。

它能这样来赋值:logic a [3:0][7:0] = '{default:0};

logic [3:0][7:0] b = {16'hz, 16'h0}; //拼接操作,将16位的z和16位的0拼接起来

logic [3:0][7:0] c = {16{2'b01}}; //复制操作,复制16次2位的01

对于组合型数组,由于它能被视为向量,因此在赋值时,即便左右两侧的操作数的大小和维度不相同,也是可以做赋值操作的。

如果左右两侧的尺寸不同,则会通过截取或者扩展右侧操作数的方式来对左侧操作数赋值。

bit [1:0][15:0] a; //32位两值逻辑向量

logic [3:0][7:0] b; //32位四值逻辑向量

logic [15:0] c; //16位的四值逻辑向量

logic [39:0] d; //40-bit的四值逻辑向量

b = a; //将32位的数组赋值给32位的数组

c = a; //高16位会被截取掉

d = a; //a会扩展高8位,且给它们补0

2、非组合型数组初始化

1) 通过'{}对数组里面的每一个维度进行赋值。

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

2) 通过'{}default关键词完成赋值操作

int a1 [0:7][0:1023] = '{default: 8'h55}; //所有元素默认为十六进制的55

3)非组合型数组里的元素数据成员或者数组本身也可以为其赋值

byte a [0:3] [0:3];

a[1][0] = 8'h5; //赋值给一个元素

a[3] = '{'hF, 'hA, 'hB, 'hE}; //赋值给4个元素

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

logic [31:0] a [2:0][9:0];

logic [0:31] b [1:3][1:10];

a = b;

注:非组合型数组和组合型数组之间无法直接相互赋值。

四、循环结构foreach

1、SV中用foreach循环来对一维或者多维数组进行循环索引,而不用指定该数组的维度大小。

int sum [1:8][1:3];

foreach ( sum [i, j] ) 

   sum [i] [j] = i + j;

2、foreach循环结构中的变量无需声明

3、foreach循环结构中的变量是只读的(它们可以被引用,但不能修改),它的作用域仅限于此循环结构中。

五、系统函数

1、$dimension(数组名array_name):返回数组的维度

2、$left(array_name, dimension):返回数组指定维度的最左索引值(msb)

MSB是Most Significant Bit的缩写,指最高有效位。

logic [1:2] [7:0] word [0:3] [4:1]; //此处不太理解最左索引值是什么,以及下面为啥会返回这4个数值。我理解成返回该维度最左侧的位数值

$left(word,1); //返回0。第1维的位数是从0位到第3位。

$left(word,2); //返回4。第2维的位数是从4位到第1位。

$left(word,3); //返回1。第3维的位数是从1位到第2位。

$left(word,4); //返回7。第4维的位数是从7位到第0位。

3、${right, low, high}(array_name, dimension)

4、$size(array_name, dimension);//返回指定维度的尺寸大小

5、$increment(array_name, dimension); //如果指定维度的最左索引值大于或等于最右索引值,那么返回1,否则返回-1.

6、$bits(expression)可以用来返回数组存储的比特数目

wire [3:0] [7:0] a [0:15]; 

$bits(a); //返回512=16*8*4

struct packed {

   byte tag;

   logic [31:0] addr;

} b;

$bits(b); //返回40。byte是8-bit

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值