【路科V0】systemVerilog基础6——数组类型

本文深入介绍了SystemVerilog中的动态数组、队列和关联数组。动态数组允许在运行时调整大小,队列结合了数组和链表特性,支持灵活的数据插入和删除;关联数组则提供了一种散列存储方式,适用于稀疏数据。文中详细展示了各种操作方法,如初始化、复制、缩减、定位和排序,并给出了实例演示。
摘要由CSDN通过智能技术生成

数组类型

  • 动态数组
  • 队列
  • 关联数组 

动态数组

        与之前的定长数组相比,SV还提供了可以重新确定大小的动态数组。

        动态数组在声明时需要使用[ ]这表示不会在编译时为其制定尺寸,而是在仿真运行时来确定。

int dyn[], d2[];                 //声明动态数组
initial begin
    dyn = new[5];                 //A:分配五个元素
    foreach (dyn[j]) dyn[j] = j;  //B:对元素进行初始化
    d2 = dyn;                     //C:复制一个动态数组
    d2[0] = 5;                    //D:修改复制值
    $display(dyn[0],d2[0]);        //E:显示数值(0和5)
    dyn = new[20](dyn);            //F:分配20个整数值并进行复制
    dyn = new[100];                //G:分配100个新的整数值//旧值不复存在
    dyn.delete () ;                //H::删陈所有几系
end

动态数组的内建方法

size()//可以返回动态数组的大小。
delete()//可以清空动态数组,使其尺寸变为0。

动态数组在声明时完成其初始化

bit [7:0] mask[] ='{8'b0000_0000,8 'b000o_0001,
                    8 ' b0000 0011, 8 'b0000_0111,
                    8 ' b0000_1111,8 'b0001_1111,
                    8 ' b0011_1111,8 'b0111_1111,
                    8 ' b1111_1111};

队列

  • 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(1,j) ;      //{0,1,2,3}在第一个元素之前插入j
    q.delete(1);           //{0,2,3}删除第一个元素

//下面的操作执行速度很快
    q.push_front(6);    //{6,0,2,3} 在队列前面插入
    j = q.pop_back ;    //{6,0,2}  j = 3
    q.push_back(8) ;    //{6,0,2,8} 在队列末尾插入
    j = q.pop_front;    //{0,2,8} j = 6
  //索引元素  
    foreach (q[i])     $display(q[i]) ;    //打印整个队列
    q.delete();         //删除队列
end

关联数组 

        如果想要在仿真时创建一个大的数组,也许动态数组是一个选择,不过有的时候,我们并不需要那么大的一个数组。

         由于处理器在访问存储时的访问是随机或者散乱的,这意味在一个测试中,处理器也许只会访问几百个存储地址,而剩下大多数的地址都将被初始化为0并且浪费了仿真时的存储空间。

        SV引入了关联数组可以用来存放散列的数据成员。这一点同其它脚本语言例如Perl或者Python类似,关联数组的索引类型除了为整形以外还可以为字符串或者其它类型,而关联数组存储的数据成员也可以为任意类型
 

byte assoc [byte], idx = 1; //关联数组索引的类型的byte,存储的元素也是byte
initial begin
//对稀疏分布的元素进行初始化
//可以看到索引值变量的变化是不连续的,但这并不会影响关联数组对数据的存储
do begin
    assoc[idx] = idx;
    idx = idx << 1;
end while (idx != 0) ;

//使用foreach遍历所有索引值
//非连续的索引值,依然会被foreach循环到
foreach(assoc[i])
    $display ("assoc[%h] = %h", i, assoc[i]);//使用函数遍历所有索引值
if (assoc.first(idx)) // Get first index。通过内置函数first()找到第一个索引值
    do
    $display ("assoc[%h]=%h", idx,assoc[idx]);
    while (assoc.next (idx)); // Get next index。通过内置函数next()找到其他索引值
//查找并删除第一个元素
 void' (assoc.first(idx)) ;
 void' (assoc.delete(idx)) :
 $display("The array now has %0d elements", assoc.num()) ;
end
/*inputfile 包括:42 min_address 1492 max_address*/
//索引类型字符串,存储类型整型
int switch[string], min_address,max_address,i, file;
initial begin
    string s;
    file = $fopen ("switch.txt", "r");//通过系统函数fopen打开文件
    while( !$feof(file)) begin
        $fscanf(file,"%d %s",i, s) ;
//通过系统函数fscan,对文件中每一行内容进行扫描格式化到变量i和s中
//s作为索引值,i作为存放数值,存放到关联数组switch中
            switch[s]= i ;
end

$fclose(file);//获取最小地址
//如果没有找到字符串,对int数组使用默认值0
//变量min_address和 max_address通过关联数组可以索引到与之关联的数据
min_address switch["min_address"];
//获取最大地址
//如果最大值不存在,使用1000
if (switch.exists ("max_address"))
    max_address=switch["max_address"];
else
    max_address=1000 ;//打印所有的switches
foreach (switch[s]) 
    display ("switch[%s]=%0d",s, switch[s]);
end

三种数组的公共方法

缩减方法

        基本的数组缩减方法是把一个数组缩减成一个值。
        最常用的缩减方法是sum,它对数组中的所有元素求和。

byte 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 

其它的数组缩减方法还有

product(积)
and(与)
or(或)
xor(异或)。

定位方法

对于非合并数组,可以使用数组定位方法,其返回值将是一个队列而非一个数据成员。

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}

数组的搜索

  • foreach
  • find.. . with(在查找满足条件的数据成员时,更为方便。)
int d[]=’{9,1,8,3,4,4} , tq[$];//找出所有大于3的元素
tq = d.find with (item >3) ;// {9,8,4,4}
//等效代码
ta.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);//{}–没有找到
tq = d.find_first_index with (item==8);//{2} d[2]=8
ta = d.find_last with (item==4);//{4]
tq = d.find_last_index with (item==4); // {5} d[5]=4

排序方法

        可以通过排序方法改变数组中元素的顺序,可以对它们进行正向、逆向或者乱序的排列。

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}乱序排列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值