1-数组(定长数组,动态数组,关联数组,合并数组,非合并数组)
参考资料:
(1).公众号-芯片学堂;
(2) system verilog绿皮书;
(3) 公众号-jerryIC验证;
(4) 硅芯思见:【108】聊点$display的一点事情 (qq.com)
(5) Verilog系列:【53】动态数组 (qq.com)
(6) 硅芯思见:【128】动态数组的创建不一定非要new[] (qq.com)
1.定长数组(静态数组)与动态数组
1.1定长数组(一维&多维)
(1)定长数组在声明时,必须指定数组的长度或者上下边界;在仿真编译完成后,系统需要为分配的内存空间大小就是已知的、确定的;
(2)定长数组示例(声明&初始化):
注:如果代码试图从一个越界的地址中读取数据,sv将返回数组元素类型的缺省值;
(3)数组的基本操作(for & foreach);
1.2动态数组
注1:静态数组的大小在编译的时候就确定了;但存在一种情况,当定义数组时,指定了数组的大小,而实际使用时可能并不一定要使用定义时指定的那么大的数组,这时会造成存储空间的浪费,于是引入了静态数组;
(1)动态数组在声明时,不需要指定数组长度;在仿真运行时,动态指定; 声明时,使用[];
(2)动态数组在使用前,需要使用构造函数new[]指定其数组长度或者通过将已经分配空间大小的数组复制给未指定空间大小的数组,从而间接的实现并指定空间大小数组的构造或者直接使用具体的数值对数组进行赋值;
(3)size()用于获取当前数组的大小,其返回的是数组的大小,但是实际数组有效索引的最大值为size()-1;
(4)访问有效索引值之外的索引对应的元素,仿真器不会报错,只会得到相应数据类型的默认值;
(5)为有效索引值之外的索引所对应的元素赋值是没有意义的;赋值后,读取该索引对应的值,依然为相应数据类型的默认值;
(6)动态数组在使用完后,可以通过delete()删除数组占用的空间,删除后的数组大小为0;
(7)使用new_array_name=new[number](array_name)对新的数组进行初始化分配空间时,需要注意指定的数组空间的大小number与将要复制的数组的大小 array_name.size(),以免数据丢失;
注1:如果number>array_name.size(),多出来的索引对应的值为相应数据类型的默认值;
注2:如果number<array_name.size(),只会对array_name的部分元素进行复制;
(8)动态数组声明与使用示例:
1.3定长数组与动态数组的区别
(1)定长数组在仿真程序编译时,长度就已经指定;而动态数组在仿真运行时,再根据上下文确定长度然后实例化;
2.关联数组
2.1关联数组的特点
(1)关联数组的元素在被使用之前不会消耗内存资源;
(2)关联数组的索引可以是任何数据类型;
(3)关联数组类似于python中的字典与perl中的哈希;
2.2关联数组的使用
(1)关联数组的声明语法: data_type array_id[index_type](data_type为数组元素的类型, array_id为数组名字, index_type是索引的类型);
(2)关联数组的使用方法: foreach循环遍历, first, next, exists, delete函数;
(3)注意事项:当通过一个不存在的索引去访问关联数组时,会返回数组类型的默认值,而不是边界溢出然后报错;
(4)关联数组声明,初始化和使用示例
3.合并数组与非合并数组
(1)合并数组与非合并数组和前面提到的数组类型不在一个维度上;任何数组类型都可以合并,包括动态数组,队列和关联数组(目前不支持通过$display直接显示unpacked array, unpacked struct, unpacked union等数据;但是对于packed类型,可以通过$display直接输出显示);
(2)合并和非合并实际上是多维向量为了方便不同的访问场景而衍生出来的切片分段的组织方式;合并数组是连续比特存放的,非合并的不一定;本质上而言,合并和非合并是数据集合的一种组织方式,方便存储管理;
(3)合并和非合并在声明时的差异:如果将数组维度写到数组名的前面,表示这部分合并;如果将数组维度写到数组名后面,表示这部分非合并;
(4)合并和非合并数组的选择:当需要和标量进行相互转换时,使用合并数组会非常方便;当需要等待数组中的变化时,则必须使用合并数组(@操作符只能用于标量或者合并数组);
(5)合并和非合并示例:
logic[31:0] mem[1024]; 数组名mem,写在其前面的维度是[31:0],这一部分是合并的,即每32bit连续存放在一起;写在其后面的维度是1024,与写成[0:1023]相同,这部分是非合并的;
bit[6:0][7:0] data; //一个由7个(即[6:0]) 8bit(即[7:0])宽度的数拼出的合并数组;
bit[9:0][3:0]data;//一个由10个4bit宽度的数拼出的合并数组;