SystemVerilog数组类型

时间:2022-07-22
本文章向大家介绍SystemVerilog数组类型,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.动态数组

  • SV提供了可以重新确定大小的动态数组;
  • 动态数组在声明时需要使用中括号[],表示不会在编译时为其定制尺寸,而在仿真运行时确定;
  • 动态数组一开始的元素个数为空,需要使用new[]来分配空间;
int dyn [], d2[];   //声明动态数组
initial begin
  dyn=new[5];   //分配5个元素
  foreach (dyn[j])  dyn[j]  =j;   //对元素进行初始化
  d2=dyn;   //复制一个动态数组
  d2[0]=5;  //修改复制值
  $display (dyn[0],d2[0]);  //显示数值0和5
  dyn=new[20] (dyn);   //分配20个整数值并进行复制
  dyn=new[100] ;  //分配100个新的整数值  旧值不再存在
  dyn.delete();   //删除所有元素
end
  • size()可以返回动态数组的大小;
  • delete()清空动态数组,使其尺寸变为0;
  • 动态数组在声明时也可以完成初始化;
bit [7:0] mask[]=’{8’b0000_0000, 8’b0000_0001, 8‘b0000_0011,8’b0000_0111,
8’b0000_1111, 8’b0001_1111, 8’b0011_1111, 8’b0111_1111, 8’b1111_1111};

2.队列

  • SV引入队列类型,结合了数组和链表;
  • 可以在队列任何位置添加和删除数据成员;
  • 可以通过索引访问队列的任何一个成员;
  • 通过[] 声明队列。队列的索引值从0到;
  • 可以通过内建方法push_back(val)、push_front(val)、pop_back()和pop_front()来顺序添加或者移除数据;
  • 通过insert(val,pos)在指定位置插入数据;
  • 通过delete()删除所有数据成员;
int j=1,
q2[$] ={3,4},   //队列常量不需要用’
q[$]={0,2,3};    //{0,2,3}

initial begin
  q.insert(2,j);   //{0,1,2,3}在第二元素之前插入j
q.delete(2);   //{0,2,3}删除第二个元素

q.push_front(6);   //{6,0,2,3}在队列前面插入6
j=q.pop_back;     //{6,0,2}  j=3 移除最后一位
q.push_back(8);  //{6,0,2,8}在队列末尾插入8
j=q.pop_front;   //{0,2,8}  j=6  移除第一位
foreach (q[i])
  $display(q[i]);   //打印整个队列
q.delete();   //删除队列
end
  • 通过连接运算符将队列进行拼接或者顺序重置;
  • 过连接运算符可以实现数据插入或者移除队列的效果;
  • 通过空的连接运算符可以实现队列的清空;
int j=1,
q2[$] ={3,4},   //队列常量不需要用’
q[$]={0,2,5};    //{0,2,5}

initial begin 
q={q[0],j,q[1:$]};     //{0,1,2,5}在2之前插入1
q={q[0:2],q2,q[3:$]};   //{0,1,2,3,4,5}在q中插入一个队列
q={q[0],q[2:$]};    //{0,2,3,4,5} 删掉第二个元素

q={6,q} ;   //{6, 0,2,3,4,5}在队列前面插入
j=q[$];   //等同于j=5
q=q[0:$-1];  //{6, 0,2,3,4} 在队列末尾移除数据
q={q,8};   //{6, 0,2,3,4,8}末尾插入8
j=q[0];    //等同于j=6
q=q[1:$];   //{0,2,3,4,8} 移除第一个数
q={};     //删除队列
end

3.关联数组

  • 对于超大容量的数组,可以使用SV提供的关联数组类型,保存稀疏矩阵的元素,即只为实际写入的元素分配空间;
  • 关联数组的索引类型可以是整形、字符串或者其他类型;
  • 仿真器可以采用树或者哈希表的形式存放关联数组;
  • 声明方式:采用在方括号中放置数据类型的形式,如[int];

关联数组声明、初始化、使用:

bit[63:0]  assoc[byte] , idx=1;
initial begin
    //对稀疏分布的元素进行初始化
    repeat(64) begin
     assoc[idx]=idx;
     idx=idx<<1;
    end

    //使用foreach遍历数组
    foreach (assoc[i])
         $display("assoc[%h]=%h",i,assoc[i]);
    //使用函数遍历数组
    if (assoc.first(idx))begin
     do
        $display("assoc[%h]=%h",idx,assoc[idx]");
        while(assoc.next(idx));  //得到下一个索引
    end
    //找到并删除第一个元素
    assoc.first(idx);
    assoc.delete(idx);
    $display("the array now has %0d elements",assoc.num);
end

4.缩减方法

  • 基本的数组缩减方法是把一个数组缩减成一个值;
  • 数组缩减方法有sum(求和)、product(积)、and(与)、or(或)和xor(异或);
tybe b[$] ={2,3,4,5};
int w;
w=b.sum(); //14=2+3+4+5
w=b.product(); //120=2*3*4*5
w=b.and();  //0000_0000= 2 & 3  & 4 & 5

5.定位方法

  • 在非合并数组中,可以使用数组定位方法,其返回值将是一个队列而不是一个数据成员;

数组定位方法:max、min、unique(独一无而的)

int f[6]='{1,6,2,6,8,6};  //定长数组
int d[]='{2,4,6,8,10};  //动态数组
int q[$]={1,3,5,7};   //队列

tp[$];   //保存结果的临时队列
tp=q.min();   //{1}
tp=d.max();   //{10}
tp=f.unique();  //{1,6,2,8}
  • 使用foreach循环可以实现数组的完全搜索;但使用SV定位只需要一个操作:find with;

//find with定位

int d[]='{9,1,8,3,4,4},tp[$];
//找出所有大于3的元素
tp=d.find with(item>3);  //{9,8,4,4}

//foreach等效代码

tq.deldte();
foreach(d[i])
    if(d[i]>3)
        tp.push_back([i]);

//其他定位方法

tq=d.find_index with (item>3) ;
tq=d.find_first with (item>99) ;   //{} 没有找到
tq=d.find_last with (item==4) ;    // {4}
tq=d.find_first_index with (item==8) ;  //{2} d[2]=8
tq=d.find_last_index with (item==4) ;  //{5} d[5]=4

6.排序方法

  • 通过排序改变数组中元素的顺序,如正排序、匿排序或者打乱顺序;
int d[]=   '{9,1,8,3,4,4};
d.revrse();  //逆排序'{4.4.3.8.1.9};
d.sort();   //从小到大' {1,3,4,4,8,9};
d.rsort();  //从大到小 '{9,8,4,4,3,1};
d.shuffle();  //乱序排列

END