SystemVerilog学习(3)——数组

一、定宽数组

        相比于Verilog-1995中的一维定宽数组,SV提供了更加多样的数组类型,功能上也大大增强。

1.1 定宽数组的声明与初始化

         Verliog要求在声明中必须给出数组的上下界。因为几乎所有的数组都使用0作为索引下届,所以SV允许只给出数组的宽度的便捷声明方式,这与C语言是类似的。

//定宽数组的声明
int lo_hi[0:15]    //16个整数[0]...[15]
int c_style[16]    //16个整数[0]...[15] 

        可以通过在变量名后面指定维度的方式来创建多维定宽数组。下面的代码就创建了几个二维的整数数组,大小都是8行4列,最后一个元素的值被设置为1。在Verilog-2001中就引入了多维数组,但是这种便捷的声明方式只在SV中存在。

//多维数组声明
int array2 [0:7][0:3]   //完整的声明
int array3 [8][4]       //紧凑的声明
array2[7][3] = 1;       //设置最后一个元素

         如果试图从一个越界的地址中读取数据,那么SV会返回数组元素的缺省值(例如:四值类型如logic返回X,双状态类型返回0)。

1.2 常量数组

        下面的例子展示了如何使用常量数组,即一个单引号加大括号来初始化数组。在大括号前标上重复次数可以对多个元素重复赋值,还可以为那些没有显示赋值的元素指定一个缺省值。

//初始化一个数组
int ascend[4] = '{0,1,2,3};
int descend[5];

descend = '{4,3,2,1,0};
descend[0:2] = '{5,6,7};
ascend = '{4{8}};             //四个值都是8
descend = '{9,8,default:1};   //{9,8,1,1,1}

1.3 基本的数组操作

        操作数组的常见方式是for和foreach循环。 在foreach循环中,只需要指定数组名并在其后面的方括号中给出索引变量,SV就会自动遍历数组元素。

initial begin
    bit [31:0] src[5],dst[5];
    for(int i = 0 ; i < $size(src) ; i++)
        src[i] = i;
    foreach (dst[j])
        dst[j] = src[j] * 2;
end

二、动态数组

        我们前面介绍的基本的Verilog数组类型都是定宽数组,其宽度在编译的时候就确定了。但是如果直到程序运行之前都不知道数组的宽度呢?例如,你可能想在仿真开始的时候生成一批事务,事务的总量是随机的。如果把这些事务存放到一个定宽数组里,那这个数组的宽度就必须足以容纳最大的事务量,这就造成了资源的浪费,SV提供了动态数组类型,可以在仿真的时候分配空间或调整宽度,这样在仿真中就可以使用最小的存储量。

        动态数组在声明的时候使用空的下标[ ]。这意味着数组的宽度不在编译的时候给出,而在程序运行时再定。数组在最开始的时候是空的,所以你必须调用new[ ]操作符来分配空间,同样在方括号中传递数组宽度。可以把数组名传给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

三、队列 

         SystemVerilog 引进了一种新的数据类型—队列,它结合了链表和数组的优点。队列与链表相似,可以在一个队列中的任何地方增加或删除元素,这类操作在性能上的损失比动态数组小得多,因为动态数组需要分配新的数组并复制所有元素的值。队列与数组相似,可以通过索引实现对任一元素的访问,而不需要像链表那样去遍历目标元素之前的所有元素。

        队列的声明是使用带有美元符号的下标:[$]。队列元素的编号从0到$。例2.19示范了如何使用方法(method)在队列中增加和删除元素。注意队列的常量( literal)只有大括号而没有数组常量中开头的单引号。

        System Verilog 的队列类似于标准模板库(standard template library)中的双端队列。你通过增加元素来创建队列.SystemVerilog 会分配额外的空间以便你能够快速插人新元素。当元素增加到超过原有空间的容量时,SystemVerilog 会自动分配更多的空间。其结果是,你可以扩大或缩小队列,但不用像动态数组那样在性能上付出很大代价,SystemVerilog会随时记录闲置的空间。注意不要对队列使用构造函数new[]。

         可以通过内建方法push_back(val)、push_front(val)、 pop_back()和pop_front()来顺序添加或者移除并且获得数据成员; 可以通过insert(pos, val)来在指定位置插入数据成员; 可以通过delete()来删除所有数据成员。

四、其他 

        关于数组类型,还有关于关联数组,链表,数组方法,数组排序的相关内容,这里不做过多展开。 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

apple_ttt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值