电子说
在使用SystemVerilog或者UVM进行编码的过程中,经常会用到数组(包括队列等),经常需要对这些数组进行遍历,有时候我们为了遍历这些数组需要获取这些数组有多少个元素之后才会使用for循环对数组进行遍历,为了获取到数组中元素的个数,经常会用到“$size(数组名)”和“数组名.size”两种方式,那么同样是获取数组元素个数会存在两种方式呢?这两种方式有什么样的区别呢?下面我们通过示例进行说明。
1 $size()
$size()函数是用来查询指定数组指定维的元素数,函数返回值为integer型,该函数有两个参数,第一个参数数组名,第二个参数为要查询的数组的维数表达式,其中第二个参数为可选,默认缺省值为1.
【示例】
【仿真结果】
示例中,“num=$size(arr)”没有指定要查询数组的哪一维,则此时默认是查询arr第一维共有2个元素,与“num1=$size(arr,1)”相同,即如果使用$size()时仅指定了数组名,则默认查询的是数组第一维的元素数目;
“num0=$size(arr,0)”中,因为数组arr并没有第0维,所以此时$size()返回为0;
“num2=$size(arr,2)”中,指定查询数组第2维,示例中第2维索引为“[0:2]”,所以此时查询返回值为3;
“num3=$size(arr,3)”中,指定查询数组第3维,示例中第3维索引为“[3:0]”,所以此时查询返回值为4;
“num4=$size(arr,4)”中,指定查询数组第4维,示例中第4维索引为“[4:0]”,所以此时查询返回值为5;
可见,$size()可以通过指定函数的第二个参数查询数组指定维中包含的元素数目;虽然$size()可以返回数组对应维数的元素个数,但是前提是该维数要有对应的存储空间分配,否则将会出现一些不期望的问题。如下例。
【示例】
【仿真结果】
示例中,“num1=$size(arr,2)”获取数组第2维元素个数,但是此时第二维并没有完全分配空间,所以此时在编译阶段就报错了。虽然代码第6行“arr[2]=new[4]”,但这只是给了数组arr第1维中第2个元素对应的动态数组分配了4个存储空间,并没有给arr数组第2维所有的元素分配空间,所以此时如果访问数组第1维第2个元素中包含多少个元素是可以查询到的。如下例。
【示例】
【仿真结果】
示例中,在查询时需要注意此时$size()函数的第一个参数要指定为数组arr第1维中第2个元素,此时编译没有问题主要就是因为对于arr第1维中第2个元素中对应的动态数组进行空间的分配。所以在使用$size()函数时,一定要注意要访问的维度对应的数组元素的空间是否已经分配存在。
2数组名.size()
方法原型如下:
function int size();
该函数的调用方式是通过“数组名.size()”的方式调用,不能在size()函数中指定参数列表。
【示例】
【仿真结果】
示例中,定义了一个定宽数组arr,然后通过“数组名.size()”的方式获取数组中元素的个数,但是这是编译报错,这是因为在SystemVerilog中已经不支持对于定宽数组通过“数组名.size()”的方式获取数组中元素的个数。但是对于动态数组、关联数组、队列还是可以使用的。如下例。
【示例】
【仿真结果】
示例中,分别声明了动态数组、队列和关联数组这些非定宽数组,对这些非定宽数组通过“数组名.size()”的方式获取到了数组中元素的个数分别为4,5,6,可见“数组名.size()”的使用仅限于非定宽类数组。那么对于这类数组可不可以使用$size()方法呢?请看下例。
【示例】
【仿真结果】
示例中,通过$size()方法可以获得动态数组、队列和关联数组这些非定宽数组所包含的元素的个数,但是在使用时,一定要注意对于元素空间的开辟。
从上数这几个示例可以看到,对于非定款数组获取数组元素个数时可以使用size()方法和$size,但是对于定宽数组各维元素个数的获取只能通过$size()方法,同时在使用这些方法时,需要注意数组元素空间的开辟。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !