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循环。

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

队列的声明是使用带有美元符号的下标:[\]。队列元素的编号从О到。例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()来删除所有数据成员。

四、其他

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

相关推荐
ALINX技术博客7 天前
算力跃升!解析可嵌入整机的 6U VPX 异构高性能射频信号处理平台 AXW23
射频工程·fpga·基带工程
简简单单做算法7 天前
【第1章】基于FPGA的图像形态学处理学习教程——目录
fpga·图像形态学处理·膨胀·腐蚀·开运算·闭运算
做一个快乐的小傻瓜8 天前
易灵思FPGA的RISC-V核操作函数
fpga·risc-v·易灵思
风已经起了12 天前
FPGA学习笔记——用Vitis IDE生成工程(串口发送)
笔记·学习·fpga开发·fpga·1024程序员节
ALINX技术博客13 天前
ALINX 携手 PhineDesign 亮相日本 DSF2025,用 FPGA 产品力响应时代技术浪潮挑战!
fpga开发·fpga
讽刺人生Yan13 天前
RFSOC学习记录(六)混频模式分析
学习·fpga·rfsoc
讽刺人生Yan14 天前
RFSOC学习记录(五)带通采样定理
学习·fpga·rfsoc
讽刺人生Yan15 天前
RFSOC学习记录(四)MTS时序分析
学习·fpga·rfsoc
南檐巷上学15 天前
Vivado调用FFT IP核进行数据频谱分析
fpga开发·fpga·vivado·fft·快速傅里叶变化
北城笑笑17 天前
FPGA 49 ,Xilinx Vivado 软件术语解析(Vivado 界面常用英文字段详解,以及实际应用场景和注意事项 )
fpga开发·fpga