SystemVerilog中数组的维度相关概念解析

SystemVerilog中数组的维度相关概念解析

1. sv多维数组相关概念解析

首先看下SystemVerilog标准中对packed(合并)和unpacked(非合并)数组的定义
在这里插入图片描述

简单说来就是定义在数组名左边的是packed部分,右边的是unpacked部分
合并数组部分定义的维度在内存空间中是连续排放的,非合并数组是非连续存放,以32位内存系统为例两种数组的内存存储形式如下图所示:
在这里插入图片描述

多维数组里packed和unpacked维度示意如下(ijk三个维度对应packed,lmn三个维度对应unpacked):
bit [i][j][k] array [l][m][n];

再引申一下看看多维数组的下标对应情况
下面是sv语法中的描述:
在这里插入图片描述

可见在进行多维数组引用时,packed部分的维度在引用时比unpacked部分要高,unpacked部分的维度越靠近数组名越低,packed部分也是越靠近数组名越低。
总结下来数组的维度排序从低到高依次是:
1、先从左到右依次对unpacked部分维度排序
2、再从左到右依次对packed部分维度排序

还是用上面多维数组的例子:
// packed unpacked
bit [l][m][n] array [i][j][k] ;
对应数组的维度如下:
//维度 0 1 2 3 4 5
引用时对应下标array[i][j][k][l][m][n]

看看下面的示例

   initial begin
      //  l     m    n      i   j    k
      bit[4:0][0:2][0:0] a [2][0:3][5:0];
      int i,j,k,m;

      foreach(a[i, j, k, l, m, n]) begin
         $display("i=%0d, j=%0d, k=%0d, l=%0d, m=%0d, n=%0d", i, j, k, l, m, n);
      end
   end

打印信息(部分截取):

i=0, j=0, k=5, l=4, m=0, n=0
i=0, j=0, k=5, l=4, m=1, n=0
i=0, j=0, k=5, l=4, m=2, n=0
i=0, j=0, k=5, l=3, m=0, n=0
i=0, j=0, k=5, l=3, m=1, n=0
i=0, j=0, k=5, l=3, m=2, n=0
i=0, j=0, k=5, l=2, m=0, n=0
i=0, j=0, k=5, l=2, m=1, n=0
i=0, j=0, k=5, l=2, m=2, n=0
......
i=0, j=0, k=4, l=2, m=1, n=0
i=0, j=0, k=4, l=2, m=2, n=0
i=0, j=0, k=4, l=1, m=0, n=0
i=0, j=0, k=4, l=1, m=1, n=0
i=0, j=0, k=4, l=1, m=2, n=0
i=0, j=0, k=4, l=0, m=0, n=0
i=0, j=0, k=4, l=0, m=1, n=0
......
i=0, j=0, k=2, l=4, m=2, n=0
i=0, j=0, k=2, l=3, m=0, n=0
i=0, j=0, k=2, l=3, m=1, n=0
i=0, j=0, k=2, l=3, m=2, n=0
i=0, j=0, k=2, l=2, m=0, n=0
i=0, j=0, k=2, l=2, m=1, n=0
i=0, j=0, k=2, l=2, m=2, n=0
i=0, j=0, k=2, l=1, m=0, n=0
i=0, j=0, k=2, l=1, m=1, n=0
i=0, j=0, k=2, l=1, m=2, n=0
i=0, j=0, k=2, l=0, m=0, n=0
......
i=0, j=0, k=1, l=1, m=0, n=0
i=0, j=0, k=0, l=2, m=2, n=0
i=0, j=0, k=0, l=1, m=0, n=0
i=0, j=1, k=3, l=3, m=0, n=0
i=0, j=1, k=3, l=3, m=1, n=0
i=0, j=1, k=3, l=3, m=2, n=0
i=0, j=1, k=3, l=2, m=0, n=0
i=0, j=1, k=3, l=2, m=1, n=0
i=0, j=1, k=3, l=2, m=2, n=0
......
i=0, j=2, k=2, l=1, m=0, n=0
i=0, j=2, k=2, l=1, m=1, n=0
i=0, j=2, k=2, l=1, m=2, n=0
i=0, j=2, k=2, l=0, m=0, n=0
i=0, j=2, k=1, l=3, m=1, n=0
i=0, j=2, k=1, l=3, m=2, n=0
i=0, j=2, k=1, l=2, m=0, n=0
i=0, j=2, k=1, l=2, m=1, n=0
i=0, j=2, k=1, l=2, m=2, n=0
i=0, j=2, k=1, l=1, m=0, n=0
i=0, j=2, k=1, l=1, m=1, n=0
i=0, j=3, k=4, l=4, m=1, n=0
i=0, j=3, k=4, l=4, m=2, n=0
i=0, j=3, k=4, l=3, m=0, n=0
i=0, j=3, k=4, l=3, m=1, n=0
i=0, j=3, k=4, l=3, m=2, n=0
......
i=0, j=3, k=0, l=1, m=1, n=0
i=0, j=3, k=0, l=1, m=2, n=0
i=0, j=3, k=0, l=0, m=0, n=0
i=0, j=3, k=0, l=0, m=1, n=0
i=0, j=3, k=0, l=0, m=2, n=0
i=1, j=0, k=5, l=4, m=0, n=0
i=1, j=0, k=5, l=4, m=1, n=0
......

由此得到如下结论:

foreach遍历顺序是从索引最大的维度往最小的维度开始遍历(图中的n->m->l->k->j->i)
foreach中数组下标的写法(a[i,j,k,l,m,n])与引用数组时(array[i][j][k][l][m][n])不同,但是维度索引规则对应的维度与之相同

2. 再看一道面试题

bit[3:0][7:0] a;
bit[7:0] b [0:3];
以上两种情况 $size()对数组的求解结果是多少?

本质问题就是求数组的最低维度大小。

按照上面的数组维度规则不难得出最低维度求解顺序:
1、先看unpacked部分最左边的维度 $size(b) = 4
2、没有unpacked部分就再看packed部分最左边的维度 $size(a) = 4

下面做实验验证下:

   initial begin
      bit[3:0][7:0] a = {8'h11, 8'h22, 8'h33, 8'h44};
      bit[7:0] b [0:3]= {8'h11, 8'h22, 8'h33, 8'h44};

      $display("size of a is %0d", $size(a));

      foreach(a[i]) begin
         $display("a[%0d] = 'h%0h", i, a[i]);         
      end

      $display("size of b is %0d", $size(b));
      foreach(b[i]) begin
         $display("b[%0d] = 'h%0h", i, b[i]);         
      end
   end

打印结果:

size of a is 4
a[3] = 'h11
a[2] = 'h22
a[1] = 'h33
a[0] = 'h44
size of b is 4
b[0] = 'h11
b[1] = 'h22
b[2] = 'h33
b[3] = 'h44

3. 总结

本文从systemverilog标准中关于packed和unpacked数组的定义出发,结合标准中对于多维数组的一些维度遍历、索引描述,得出多维数组遍历或者引用时数组下标与声明时的下标排列顺序之间的关系,并结合代码示例进行了案例讲解,希望对大家在进行多维数组使用时能有帮助。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在SystemVerilog,有三种类型的数组:静态数组(Static Arrays),动态数组(Dynamic Arrays)和关联数组(Associative Arrays)。它们各自具有不同的用途和特点。 1. 静态数组(Static Arrays): - 静态数组在编译时分配内存空间,并且其大小在声明时被确定。 - 静态数组可以是一维或多维的,元素类型可以是基本数据类型或用户定义类型。 - 静态数组的元素数量是固定的,不支持动态添加或删除元素。 - 静态数组适用于需要事先知道大小的情况,例如存储预定义的数据集。 2. 动态数组(Dynamic Arrays): - 动态数组在运行时动态分配内存空间,其大小可以根据需要进行调整。 - 动态数组只能是一维的,元素类型可以是基本数据类型或用户定义类型。 - 动态数组支持动态添加或删除元素,并且可以使用内置函数进行元素的插入、删除和查找操作。 - 动态数组适用于需要根据运行时条件动态调整大小的情况,例如存储可变长度的数据。 3. 关联数组(Associative Arrays): - 关联数组使用键值对的形式来存储和访问数据,其键和值可以是任意类型。 - 关联数组在运行时动态分配内存空间,并且其大小可以根据需要进行调整。 - 关联数组支持动态添加或删除键值对,并且可以使用内置函数进行键值对的插入、删除和查找操作。 - 关联数组适用于需要根据键来查找和操作数据的情况,例如存储符号表或哈希表。 总之,静态数组适用于大小已知且固定的情况,动态数组适用于大小可变的情况,而关联数组适用于根据键进行访问和操作的情况。根据具体的需求和应用场景,选择合适的数组类型可以提高代码的效率和可读性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值