SystemVerilog阵列操作SystemVerilog Array Manipulation

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

发布了91 篇原创文章 · 获赞 7 · 访问量 5261

猜你喜欢

转载自blog.csdn.net/qq_43042339/article/details/104456110