SystemVerilog中有许多内置方法可帮助进行数组搜索和排序。
数组操作方法只是简单地遍历数组元素,每个元素都用于评估with子句指定的表达式。 iterator参数指定一个局部变量,可在with表达式内使用该局部变量来引用迭代中的当前元素。 如果未提供参数,则item是默认使用的名称。
数组定位器方法
对于其中某些方法,with子句和expresison是必需的,而对于另一些方法,则是可选的。
强制性的“ with”子句
这些方法用于根据给定表达式从现有数组中滤除某些元素。 所有满足给定表达式的元素都将放入数组并返回。 因此,with子句对于以下方法是必需的。
Method name | Description |
---|---|
find() | 返回满足给定表达式的所有元素 |
find_index() | 返回满足给定表达式的所有元素的索引 |
– | – |
find_first() | 返回满足给定表达式的第一个元素 |
find_first_index() | 返回满足给定表达式的第一个元素的索引 |
– | – |
find_last() | 返回满足给定表达式的最后一个元素 |
find_last_index() | 返回满足给定表达式的最后一个元素的索引 |
– | – |
Example
module tb;
int array[9] = '{4, 7, 2, 5, 7, 1, 6, 3, 1};
int res[$];
initial begin
res = array.find(x) with (x > 3);
$display ("find(x) : %p", res);
res = array.find_index with (item == 4);
$display ("find_index : res[%0d] = 4", res[0]);
res = array.find_first with (item < 5 & item >= 3);
$display ("find_first : %p", res);
res = array.find_first_index(x) with (x > 5);
$display ("find_first_index: %p", res);
res = array.find_last with (item <= 7 & item > 3);
$display ("find_last : %p", res);
res = array.find_last_index(x) with (x < 3);
$display ("find_last_index : %p", res);
end
endmodule
Simulation Log
ncsim> run
find(x) : '{4, 7, 5, 7, 6}
find_index : res[0] = 4
find_first : '{4}
find_first_index: '{1}
find_last : '{6}
find_last_index : '{8}
ncsim: *W,RNQUIE: Simulation is complete.
可选的“ with”子句
Methods | Description |
---|---|
min() | 返回具有最小值或表达式的结果为最小值的元素 |
max() | 返回具有最大值的元素,或者其表达式的结果为最大值 |
– | – |
unique() | 返回所有具有唯一值或其表达式求值为唯一值的元素 |
– | – |
unique_index() | 返回具有唯一值或其表达式的结果为唯一值的所有元素的索引 |
Example
module tb;
int array[9] = '{4, 7, 2, 5, 7, 1, 6, 3, 1};
int res[$];
initial begin
res = array.min();
$display ("min : %p", res);
res = array.max();
$display ("max : %p", res);
res = array.unique();
$display ("unique : %p", res);
res = array.unique(x) with (x < 3);
$display ("unique : %p", res);
res = array.unique_index;
$display ("unique_index : %p", res);
end
endmodule
Simulation Log
ncsim> run
min : '{1}
max : '{7}
unique : '{4, 7, 2, 5, 1, 6, 3}
unique : '{4, 2}
unique_index : '{0, 1, 2, 3, 5, 6, 7}
ncsim: *W,RNQUIE: Simulation is complete.
数组排序方法
Method | Description |
---|---|
reverse() | 反转数组中元素的顺序 |
sort() | 按升序对数组进行排序,可以选择使用with子句 |
– | – |
rsort() | 按降序对数组进行排序,可以选择使用with子句 |
shuffle() | 随机化数组中元素的顺序。 with子句在这里是不允许的 |
– | – |
Example
module tb;
int array[9] = '{4, 7, 2, 5, 7, 1, 6, 3, 1};
initial begin
array.reverse();
$display ("reverse : %p", array);
array.sort();
$display ("sort : %p", array);
array.rsort();
$display ("rsort : %p", array);
for (int i = 0; i < 5; i++) begin
array.shuffle();
$display ("shuffle Iter:%0d = %p", i, array);
end
end
endmodule
Simulation Log
ncsim> run
reverse : '{1, 3, 6, 1, 7, 5, 2, 7, 4}
sort : '{1, 1, 2, 3, 4, 5, 6, 7, 7}
rsort : '{7, 7, 6, 5, 4, 3, 2, 1, 1}
shuffle Iter:0 = '{6, 7, 1, 7, 3, 2, 1, 4, 5}
shuffle Iter:1 = '{5, 1, 3, 4, 2, 7, 1, 7, 6}
shuffle Iter:2 = '{3, 1, 7, 4, 6, 7, 1, 2, 5}
shuffle Iter:3 = '{6, 4, 7, 3, 1, 7, 5, 2, 1}
shuffle Iter:4 = '{3, 6, 2, 5, 4, 7, 7, 1, 1}
ncsim: *W,RNQUIE: Simulation is complete.
在类上使用数组排序
class Register;
string name;
rand bit [3:0] rank;
rand bit [3:0] pages;
function new (string name);
this.name = name;
endfunction
function void print();
$display("name=%s rank=%0d pages=%0d", name, rank, pages);
endfunction
endclass
module tb;
Register rt[4];
string name_arr[4] = '{"alexa", "siri", "google home", "cortana"};
initial begin
$display ("
-------- Initial Values --------");
foreach (rt[i]) begin
rt[i] = new (name_arr[i]);
rt[i].randomize();
rt[i].print();
end
$display ("
--------- Sort by name ------------");
rt.sort(x) with (x.name);
foreach (rt[i]) rt[i].print();
$display ("
--------- Sort by rank, pages -----------");
rt.sort(x) with ( {x.rank, x.pages});
foreach (rt[i]) rt[i].print();
end
endmodule
Simulation Log
ncsim> run
-------- Initial Values --------
name=alexa rank=12 pages=13
name=siri rank=6 pages=12
name=google home rank=12 pages=13
name=cortana rank=7 pages=11
--------- Sort by name ------------
name=alexa rank=12 pages=13
name=cortana rank=7 pages=11
name=google home rank=12 pages=13
name=siri rank=6 pages=12
--------- Sort by rank, pages -----------
name=siri rank=6 pages=12
name=cortana rank=7 pages=11
name=alexa rank=12 pages=13
name=google home rank=12 pages=13
ncsim: *W,RNQUIE: Simulation is complete.
数组缩减方法
Method | Description |
---|---|
sum() | 返回所有数组元素的总和 |
product() | 返回所有数组元素的乘积 |
– | – |
and() | 返回所有数组元素的按位与(&) |
or() | 返回所有数组元素的按位或( |
– | – |
xor() | 返回所有数组元素的按位XOR(^) |
module tb;
int array[4] = '{1, 2, 3, 4};
int res[$];
initial begin
$display ("sum = %0d", array.sum());
$display ("product = %0d", array.product());
$display ("and = 0x%0h", array.and());
$display ("or = 0x%0h", array.or());
$display ("xor = 0x%0h", array.xor());
end
endmodule
Simulation Log
ncsim> run
sum = 10
product = 24
and = 0x0
or = 0x7
xor = 0x4
ncsim: *W,RNQUIE: Simulation is complete.
参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-array-manipulation