问题一:如何区分组合数组与非组合数组?
你能区分以下数组哪些是组合数组哪些是非组合数组吗?
logic [8:0][7:0] array0;
logic [7:0] array1 [8:0];
logic array2 [8:0][7:0] ;
答案就是:只有第一个数组array0是组合数组,其余都是非组合数组。
哪如何区分与记忆呢?
首先明白维数在数组名左边意味着packed即告诉编译器要打包的意思,而在右边意味着unpacked即告诉编译器要不用打包的意思。
然后我们要明白组合数组就是将数组中的每一位打包即packed起来,组成一个矢量,而非组合数组数组中的每一个元素都是独立的数据,而为了区分组合数组即是packed的操作。将数组名左边的[MSB:LSB]或[LSB:MSB]作为打包packed作为组合数组,并且只有当数组中的全部元素都packed时,才被成为组合数组,若只有低维packed,而高维没有仍旧是非组合数组。
高维与低维都打包即为组合数组:
//高维与低维都打包即为组合数组:
logic [8:0][7:0] array0;
低维打包,高维不打包为非组合数组:
//低维打包,高维不打包为非组合数组:
logic [7:0] array1 [8:0];
高维与低维都不打包即为非组合数组:
//高维与低维都打包即为组合数组:
logic array2 [8:0][7:0] ;
顺便说一句如何区分数组的高维与低维?
在C语言中比如一个二维数组: int array3 [9][8] ;我们知道左边的[9]为第二维即高维,而右边的[8]为第一维即低维,SV中也是一样的,只要高维与低维都在数组名的同一侧(左侧或右侧都行)那么都是左边的为高维右边的为低维。
logic [8:0][7:0] array0;//维数都在数组名左侧,左高右低,[8:0]为第二维即高维,[7:0]为第一维即低维
logic array2 [8:0][7:0] ;//维数都在数组名右侧,左高右低,[8:0]为第二维即高维,[7:0]为第一维即低维
但如果维数在数组名的两侧,那么右侧的为高维左侧的为低维,与verilog类似。
logic [7:0] array1 [8:0];//维数在数组名的两侧,右高左低,8:0]为第二维即高维,[7:0]为第一维即低维
问题二:组合数组与非组合数组有什么区别?
组合数组与非组合数组主要区别有三点:
1)在内存中的存储方式不一样。
组合数组:在内存中连续存储,非组合数组:在内存中非连续存储。
2)赋值不一样
组合数组:因为组合数组可以看成矢量,因此只要总的位宽相同,就可以在进行赋值
logic [8:0][7:0] array4; //9*8
logic [7:0][8:0] array5; //8*9
//因为array4与array5的总位宽相同因此可以直接进行赋值
array4 = array5;
非组合数组:因为非组合数组中的每一个元素的都是独立的数据,因此必须维数与每一个维数中的元素个数都相等时,才可以赋值
logic array6 [8:0][7:0] ; //共二维,高维为9低维为8
logic array7 [7:0][8:0] ; //共二维,高维为8低维为9
logic array8 [9:1][8:1] ; //共二维,高维为9低维为8
//array6 与array7 维数相同,但每一个维数中的元素个数不相同,因此不能直接赋值
array6 = array7 ;//错误!!!
//array6 与array8 维数相同且每一个维数中的元素个数也相同,因此可以直接赋值
array6 = array8 ;//正确!!!
//
3)初始化方式不一样
组合数组:可以按照矢量的方式直接进行初始化
logic [8:0][7:0] array9 = 72'd55;
非组合数组:对每一维以数组的方式进行初始化,单引号与大括号的结合。
logic array9 [2:0][3:0] = '{'{1,2,3,4},'{5,6,7,8},'{9,0,0,0}};