IC学习笔记:05.SystemVerilog队列及数组方法【转载自知乎IC】

SystemVerilog队列及数组方法,介绍内容如下:

  1. 队列
  2. 队列声明格式
  3. 队列的方法
  4. 队列的注意事项
  5. 队列举例
  6. 数组方法
    6.1 数组缩减方法
    6.2 数组定位方法
    6.3 数组排序方法
    队列
    SystemVerilog引入了队列的数据类型,使用方便,性能上比动态数组好很多。

队列可以存储任意的数据类型,包括SystemVerilog内建的数据类型,也可以是用户自定义的数据类型。队列相当于维护了一个表格,其中表格可以实现任意的增删改查。

队列的顺序是由用户来维护的。

队列声明格式
SystemVerilog队列的声明格式为 data_type queue_name [$]。

例如,int data_q [ ] , 其 中 i n t 为 队 列 中 存 储 的 数 据 类 型 为 i n t 型 数 据 , 声 明 队 列 时 使 用 符 号 [ ],其中int为队列中存储的数据类型为int型数据,声明队列时使用符号[ ]intint使[]。

队列的方法
SystemVerilog队列提供了如下方法:

queue_name.size                  //返回queue的大小
queue_name.insert(index,item)    //在index索引处插入item元素
queue_name.delete(index)         //刪掉某元素或整个queue
queue_name.pop_front()           //去除第一个元素(队首)
queue_name.pop_back()            //去除最后一个元素(队尾)
queue_name.push_front()          //插入元素到queue(0)(队首)
queue_name.push_back()           //插入元素到queue($)(队尾)

其中,关于队列队首和队尾的方法,可以使用下图形象的了解和记忆请添加图片描述
队列的注意事项

  1. 队列的存储空间无限大,理论上为物理内存的最大空间,从0到$。
  2. 可以在队列的任意地方实现元素的增删改查。
  3. 注意不要对队列使用构造函数new[]。

队列举例

int j = 1,
q2[$]={3,4}, // Queue literals do not use‘
q[$]={0,2,5}; // {0,2,5}
initial begin
  q.insert(1, j); // {0,1,2,5} Insert 1before 2
  q = {q[0:2],3,4,q[3]}; // {0,1,2,3,4,5}Insert queue in q
    q.delete(1); // {0,2,3,4,5} Delete elem.#1
// These operations are fast
  q.push_front(6);// {6,0,2,3,4,5} Insert at front
  j = q.pop_back;// {6,0,2,3,4} j = 5
  q.push_back(8);// {6,0,2,3,4,8} Insert at back
  j = q.pop_front;// {0,2,3,4,8} j = 6
  foreach (q[i])
    $display(q[i]);// Print entire queue
  q.delete(); // {} Delete entirequeue
end

本例中展示了队列的一些方法,首先声明了q2和q队列,后分别演示了insert/delete/push_front/push_bask等方法,其中每一行代码后的注释,说明了代码执行的结果。

int q[$] = {2, 4, 8};    
int p[$];    
int e, pos;
e = q[0];   // 读取第一个(最左边)条目。
e = q[$];   // 读取最后一个(最右边)条目。
q[0] = e;   // 写第一个元素
p = q;   // 读和写整个队列(拷贝)
q = {q, 6};     //在队列的尾部插入'6'


q = {e, q};          // 在队列的头部插入'e'
q = q[1:$];          // 删除第一个(最左边)元素
q = q[0:$-1];          // 删除最后一个(最右边)元素
q = q[1:$-1];          // 删除第一个和最后一个元素
q = {};          // 清除队列(删除所有的元素)
q = {q[0:pos-1], e, q[pos:$]};    // 在位置'pos'处插入'e'
q = {q[0:pos], e, q[pos+1:$]};    // 在位置'pos'之后插入'e’

本例展示了使用拼接符 {} 对队列进行操作,其执行结果如代码后的注释所示。

SV数组方法
SV提供了很多数组方法,这些方法用于任何一种非合并的数组类型,包括定宽数组,动态数组,队列和关联数组。这些方法有繁有简,种类繁多,包括求和,求积,排序等。

这些方法包括:

  1. 数组缩减方法:sum(求和)、product(求积)、and(与)、or(或)、xor(异或)
  2. 数组定位方法:
 —min() //最小
 —max() //最大
 —unique() //唯一
 —find()   //returns all the elements satisfying the givenexpression.
 —find_index()  //returns the index of all the elements satisfying the given expression.
 —find_first() //returns the first element satisfying the givenexpression.
 —find_first_index()   //returns the index of the first element satisfying thegiven expression.
 —find_last()   //returns the last element satisfying the givenexpression.
 —find_last_index()    //returns the index of the last element satisfying thegiven expression.
  1. 数组排序方法:sort、rsort、reverse、shuffle.

数组缩减方法
数组缩减方法包括:sum(求和)、product(求积)、and(与)、or(或)、xor(异或)

bit on[10]; // Array of single bits
int total;
initial begin
  foreach (on[i])
    on[i] = i;// on[i]gets 0 or 1
  // Print the single-bit sum
  $display(“on.sum =%0d”, on.sum);// on.sum =1
  // Print the sum using 32-bittotal
  $display(“on.sum =%0d”, on.sum +32’d0); // on.sum = 5
  // Sum the values using 32-bits astotal is 32-bits
  total = on.sum;
  $display("total = %0d",total); // total = 5
  // Compare the sum to a 32-bitvalue
  if (on.sum>=32’d5) // True
    $display("sum has 5 or more1’s");
    // Compute with 32-bit signed arithimetic
    $display("int sum=%0d", on.sum with (int’(item)));
end

上例演示了sum的使用方法,代码执行结果如注释所示。

int count, total, d[] = ‘{9,1,8,3,4,4};
count = d.sum with (item > 7); // 2: {9, 8}
total = d.sum with ((item > 7) * item); // 17= 9+8
count = d.sum with (item < 8); // 4: {1, 3, 4, 4}
total = d.sum with (item < 8 ? item : 0); // 12=1+3+4+4
count = d.sum with (item == 4); // 2: {4, 4}

上例主要演示 sum with的用法,执行结果如代码后注释所示。

byte b[] = ‘{ 1, 2, 3, 4};
int y;
y = b.sum ; // y becomes 10 => 1 + 2 +3 + 4
y = b.product ; // y becomes 24 => 1 * 2 *3 * 4
y = b.xor with ( item + 4 ); // y becomes12 => 5 ^ 6 ^ 7 ^ 8

logic [7:0] m [2][2] = '{ '{5, 10}, '{15, 20} };
int y;
y = m.sum with (item.sum with (item)); // y becomes 50 => 5+10+15+20

logic bit_arr[1024];
int y;
y = bit_arr.sum with ( int'(item) ); // forces result to be 32-bit
数组定位方法
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();// {1}
tq = d.max();// {10}
tq = f.unique();// {1,6,2,8}

在本例中,min()为获取队列的最小值,max()为获取队列的最大值。unique()为获取唯一值。
注意:tq是一个队列,即本例中的数组方法返回一个队列。

int d[] = ‘{9,1,8,3,4,4}, tq[$]; // Find all elements greater than 3
tq = d.find_with (item > 3); // {9,8,4,4}
// Equivalent code
tq.delete();
foreach (d[i])
  if (d[i] > 3)
    tq.push_back(d[i]);
tq = d.find_index_with (item > 3);       //{0,2,4,5}
tq = d.find_first_with (item > 99);      // {} -nonefound
tq = d.find_first_index_with (item==8);  // {2} d[2]=8
tq = d.find_last_with (item==4);         // {4}
tq = d.find_last_index_with (item==4);   // {5} d[5]=4

上例中,主要演示 find_with/find_index_with/find_first_with/find_last_with/find_first_index_with/find_last_index_with等的使用方法
注意:本例中tq为队列,即本例中的数组方法返回值为一个队列。

数组排序方法\

int d[] = ‘{9,1,8,3,4,4};
d.reverse();// ‘{4,4,3,8,1,9}
d.sort();// ‘{1,3,4,4,8,9}
d.rsort();// ‘{9,8,4,4,3,1}
d.shuffle();// ‘{9,4,3,8,1,4}

reverse()为反转排序,即进行倒序排列,sort()为从小到大排列,rsort()为从大到小排列,shuffle()为打乱,进行随机排列。

  • 0
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值