1.6数组的方法
SystemVerilog提供了很多数组的方法,可以用于任何一种非合并的数组类型,包括定宽数组、动态数组、队列和关联数组。
1.6.1数组缩减方法
基本的数组缩减方法是把一个数组缩减成1个值,缩减方法可以用来计算数组中所有元素的和、积或逻辑运算。其他数组缩减方法还有or和xor。SystemVerilog没有提供专门从数组里随机选取一个元素的方法,对于顶宽数组、队列、动态数组和关联数组,可以使用$urandom_randge($size(array)-1)。如果想要从一个关联数组中随机抽取一个元素,你需要逐个访问该元素之前的元素,原因是没有办法直接访问第N个元素。
// 数组缩减方法 byte b[$] = {2,3,4,5}; int w; w=b.sum(); w=b.product(); w=b.and(); // 声明并初始化一个有7个元素的关联数组 int aa[int] = '{0:1, 5:2, 10:4, 15:8, 25:32, 30:64}; int idx,element,count; element = $urandom_range(aa.size()-1); foreach(aa[i]) if (count++ == element) begin idx = i; break; end $display("element #%0d aa[%0d] = %0d", element, idx, aa[idx]);
1.6.2数组定位方法
使用min和max函数可以找出数组中的最小值和最大值。这些方法也适用于关联数组。unique方法返回的是在数组中具有唯一值的队列,即派出掉重复的数值。表达式with可以指示SystemVerilog如何进行搜索。在条件语句with中,item被称为重复参数,它代表了数组中一个单独的元素。item是缺省的名字,你也可以指定别的名字,只要在数组方法的参数列表中列出来就可以了。返回值为索引的数组定位方法,其返回的队列类型是int而不是integer。但sum方法使用数组元素的位宽进行计算,所以如果数组元素是单比特的,计算结果也只有一个比特,而不是预期的结果,使用with表达式可以避免这个问题。
// 数组定位方法:min,max,unique int f[6] = '{1,6,2,6,8,6}; int d[] = '{2,4,6,8,10}; int q[$] = {1,3,5,7}, tq[$]; tq=q.min(); tq=d.max(); tq=f.unique(); // find int d[] = '{9,1,8,3,4,4}, tq[$]; // 找出所有大于3的元素 tq.find with (item > 3); tq.delete(); foreach (d[i]) if (d[i] > 3) tq.push_back(d[i]); tq = d.find_index with (item > 3); tq = d.find_first with (item > 99); tq = d.find_first_index with (item == 8); tq = d.find_last with (item == 4); tq = d.find_last_index with (item == 4); int count,total, d[]='{9,1,8,3,4,4}; count = d.sum(x) with (x>7) total = d.sum(x) with ((x>7) * x); count = d.sum(x) with (x<8); total = d.sum(x) with (x<8 ? x : 0); count = d.sum(x) with (x == 4);
1.6.3数组的排序
可以对元素进行正排序、逆排序或打乱它们的顺序。与数组定位方法不同,排序方法改变了原始数组,而数组定位方法则是新建一个队列来保存结果。reverse和shuffle方法不能带with条件语句,所以它们的作用范围是整个数组。
int d[] = '{9,1,8,3,4,4}; d.reverse(); d.sort(); d.rsort(); d.shuffle(); // 对结构数组进行排序 struct packed {bit [7:0] r,g,b;} c[]; c='{'{r:7,g:4,b:9},'{r:3,g:2,b:9},'{r:5,g:2,b:1}}; c.sort with (item.r); // 只对红色像素进行排序 c.sort(x) with ({x.g, x.b}); // 先对绿色后对蓝色像素进行排序
1.6.4使用数组定位方法建立计分板
数组定位方法可以用来建立计分板。
// 带数组方法的计分板 typedef struct packed { bit [7:0] addr; bit [7:0] pr; bit [15:0] data; } Packet; Packet scb[$]; function void check_addr(bit [7:0] addr); int intq[$]; intq = scb.find_index() with (item.addr == addr); case (intq.size()) 0: $display("Addr %h not found in scoreboard", addr); 1: scb.delete(intq[0]); default: $display("ERROR:Multiple hits for addr %h", addr); endcase endfunction:check_addr