news 2026/7/7 3:06:04

systemverilog--队列学习

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
systemverilog--队列学习

近期在写功能模块的sv-ref_model时,想到使用队列来实现会方便很多,搜索队列的使用会有很多帖子,自己也是在前辈的基础上稍作总结,作为自己的记录,也供后续参考。

一、队列的核心概念

队列是一种大小可动态调整的有序集合,特点如下:

  • 索引访问:支持像数组一样用索引([0][1]…)访问元素,索引从 0 开始,$表示最后一个元素的索引。
  • 高效增删:在队列的头部和尾部添加 / 删除元素的时间复杂度为 O (1),比动态数组更高效。
  • 存储类型:可以存储基础类型(intbitbytestring)或复杂类型(类句柄、结构体)。
  • 声明语法:使用[$]标识,格式为数据类型 队列名[$];

二、队列的基础操作(核心)

下面通过代码示例展示队列的初始化、增删、访问、清空等基础操作,这些是日常使用中最频繁的操作。

1. 声明与初始化
module test_queue; initial begin // 1. 声明空队列 int q1[$]; string q2[$]; // 2. 声明并初始化队列(用{}赋值,元素用逗号分隔) int q3[$] = {10, 20, 30}; // 初始元素:10、20、30 int q4[$] = '{40, 50, 60}; // 也可以用'{}(SystemVerilog推荐写法) // 3. 打印队列(%p是格式化打印复合类型的占位符) $display("q1(空队列):%p", q1); $display("q3:%p", q3); $finish; end endmodule

输出结果

q1(空队列):'{} q3:'{10, 20, 30}
2. 元素的添加(头部 / 尾部)

队列提供了专门的方法用于在头部 / 尾部添加元素,也支持插入到指定位置:

module test_queue; initial begin int q[$] = {1, 2, 3}; $display("初始队列:%p", q); // 1. 尾部添加元素:push_back(最常用) q.push_back(4); // 队列变为:{1,2,3,4} $display("push_back(4)后:%p", q); // 2. 头部添加元素:push_front q.push_front(0); // 队列变为:{0,1,2,3,4} $display("push_front(0)后:%p", q); // 3. 插入到指定索引位置:insert(索引, 元素) q.insert(2, 99); // 在索引2的位置插入99,队列变为:{0,1,99,2,3,4} $display("insert(2,99)后:%p", q); $finish; end endmodule

输出结果

初始队列:'{1, 2, 3} push_back(4)后:'{1, 2, 3, 4} push_front(0)后:'{0, 1, 2, 3, 4} insert(2,99)后:'{0, 1, 99, 2, 3, 4}
3. 元素的移出/删除(头部 / 尾部 / 指定位置)
module test_queue; initial begin int q[$] = {0, 1, 99, 2, 3, 4}; $display("初始队列:%p", q); // 1. 尾部移出元素:pop_back(返回被移出的元素) int val1 = q.pop_back(); // 删除4,val1=4,队列变为:{0,1,99,2,3} $display("pop_back后:%p,被删除元素:%0d", q, val1); // 2. 头部移出元素:pop_front(返回被移出的元素) int val2 = q.pop_front(); // 删除0,val2=0,队列变为:{1,99,2,3} $display("pop_front后:%p,被删除元素:%0d", q, val2); // 3. 删除指定索引的元素:delete(索引) q.delete(1); // 删除索引1的99,队列变为:{1,2,3} $display("delete(1)后:%p", q); // 4. 清空整个队列:delete()(无参数) q.delete(); // 队列变为空 $display("delete()后(清空队列):%p", q); $finish; end endmodule

输出结果

初始队列:'{0, 1, 99, 2, 3, 4} pop_back后:'{0, 1, 99, 2, 3},被删除元素:4 pop_front后:'{1, 99, 2, 3},被删除元素:0 delete(1)后:'{1, 2, 3} delete()后(清空队列):'{}
4. 元素的访问与长度获取
module test_queue; initial begin int q[$] = {10, 20, 30, 40}; // 1. 通过索引访问元素(索引从0开始,$表示最后一个元素) $display("索引0的元素:%0d", q[0]); // 10 $display("最后一个元素(q[$]):%0d", q[$]); // 40 $display("倒数第二个元素(q[$-1]):%0d", q[$-1]); // 30 // 2. 获取队列长度:size()方法 $display("队列长度:%0d", q.size()); // 4 // 3. 修改指定索引的元素 q[1] = 200; // 索引1的元素从20改为200 $display("修改后队列:%p", q); // '{10,200,30,40} $finish; end endmodule

输出结果

索引0的元素:10 最后一个元素(q[$]):40 倒数第二个元素(q[$-1]):30 队列长度:4 修改后队列:'{10, 200, 30, 40}

三、队列的高级操作

1. 队列的切片(截取部分元素)

队列支持用[start:end]的切片语法截取指定范围的元素,返回新的队列:

module test_queue; initial begin int q[$] = {1, 2, 3, 4, 5}; // 1. 截取索引1到3的元素(包含1和3) int q_slice1[$] = q[1:3]; $display("q[1:3]:%p", q_slice1); // '{2,3,4} // 2. 截取从索引2到末尾的元素($表示最后一个索引) int q_slice2[$] = q[2:$]; $display("q[2:$]:%p", q_slice2); // '{3,4,5} // 3. 截取前3个元素(索引0到2) int q_slice3[$] = q[0:2]; $display("q[0:2]:%p", q_slice3); // '{1,2,3} $finish; end endmodule
2. 队列的拼接

使用{}运算符可以将多个队列(或单个元素)拼接成新的队列

module test_queue; initial begin int q1[$] = {1, 2}; int q2[$] = {3, 4}; // 1. 拼接两个队列 int q3[$] = {q1, q2}; $display("q1+q2:%p", q3); // '{1,2,3,4} // 2. 队列与单个元素拼接 int q4[$] = {q1, 99, q2}; $display("q1+99+q2:%p", q4); // '{1,2,99,3,4} // 3. 队列自身拼接(复制两倍) int q5[$] = {q1, q1}; $display("q1复制两倍:%p", q5); // '{1,2,1,2} $finish; end endmodule

最近在调试ref_model时要实现最邻近插值就用到了队列拼接功能,将一个队列q1复制两次,拼接在原有队列q2后面,实现语句:q2={q2, q1, q1}; 这样的实现是不是很简明?!

3. 队列的遍历(foreach 循环)

使用foreach循环可以遍历队列的所有元素,是处理队列数据的常用方式:

module test_queue; initial begin int q[$] = {10, 20, 30, 40}; $display("遍历队列元素:"); foreach (q[i]) begin $display("索引%0d的元素:%0d", i, q[i]); end // 遍历的同时修改元素(比如所有元素乘2) foreach (q[i]) begin q[i] = q[i] * 2; end $display("元素乘2后:%p", q); // '{20,40,60,80} $finish; end endmodule

输出结果

遍历队列元素: 索引0的元素:10 索引1的元素:20 索引2的元素:30 索引3的元素:40 元素乘2后:'{20, 40, 60, 80}
4. 复杂类型队列(类句柄队列)

队列可以存储类的句柄,常用于验证中存储事务对象(如 AHB/AXI 事务),注意需要使用深拷贝避免浅拷贝问题:

// 定义一个简单的事务类 class Trans; int data; // 深拷贝方法:创建新对象并复制属性 function Trans copy(); copy = new(); copy.data = this.data; endfunction endclass module test_queue; initial begin Trans q[$]; // 声明类句柄队列 Trans t1, t2; // 初始化队列 t1 = new(); t1.data = 100; t2 = new(); t2.data = 200; q.push_back(t1); q.push_back(t2); $display("队列元素值:%0d, %0d", q[0].data, q[1].data); // 100, 200 // 深拷贝:添加新对象到队列(避免浅拷贝) q.push_back(t1.copy()); q[2].data = 999; // 修改新对象,原对象不受影响 $display("修改后:%0d(原对象),%0d(新对象)", t1.data, q[2].data); // 100, 999 $finish; end endmodule

输出结果

队列元素值:100, 200 修改后:100(原对象),999(新对象)

队列的类型可以是常用的int、bit、byte、logic等,也可以是自定义的类型,那么队列中的每个元素都是一个自定义的变量。

四、队列的常用场景(验证中)

  1. 事务存储:测试平台中存储生成的激励事务、监测到的总线事务(如 AHB/AXI 的读写事务)。
  2. 数据缓冲:在驱动器(Driver)和监视器(Monitor)中缓冲数据,实现异步数据处理。
  3. 动态数据处理:需要频繁添加 / 删除元素的场景(如过滤无效事务、排序事务)。

五、总结

  1. 队列的核心特性:SystemVerilog 队列是动态有序集合,支持索引访问,头部 / 尾部增删元素效率高,声明用[$]
  2. 常用基础操作
    操作/方法说明
    添加

    push_back() :尾部添加

    push_front() :头部添加

    移出

    pop_back() :尾部移出

    pop_front() :头部移出

    清空

    delete() :删除整个队列

    delete(n) :删除指定位置的元素

    长度size() :整个队列内元素个数
  3. 高级操作:支持切片[start:end]、拼接{}foreach遍历,可存储基础类型和复杂类型(类句柄需深拷贝)。
  4. 应用场景:主要用于验证中的事务存储、数据缓冲和动态数据处理,是 Testbench 编写的核心数据类型之一。

有更多的使用方法和注意事项欢迎大家留言讨论。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 22:14:39

35kV-750kV 变电站集中监控系统(涵盖火灾消防、安全防卫、动环、智能锁控、智能巡视等) 设备配置与布置

变电站集中监控系统 35kV-750kV 变电站集中监控系统是对变电站辅助设备进行监视和控制的系统,适用于 35kV-750kV 变电站的设计和建设,涵盖火灾消防、安全防卫、动环、智能锁控、智能巡视等子系统,为变电站运行提供全方位保障。 一、设计原则…

作者头像 李华
网站建设 2026/7/7 14:47:55

美国展台设计搭建公司靠谱的推荐

寻找靠谱美国展台设计搭建公司,选鑫诺展展览就对了!在当今竞争激烈的商业环境中,参加美国的各类展会成为了众多企业拓展海外市场的重要途径。而一个出色的展台,无疑是企业在展会上脱颖而出的关键。那么,如何找到一家靠…

作者头像 李华
网站建设 2026/7/7 15:40:40

【MCP PL-600 Agent部署终极指南】:从零到上线的完整实战手册

第一章:MCP PL-600 Agent 部署概述 MCP PL-600 Agent 是一款专为现代云原生环境设计的监控代理程序,支持跨平台资源采集、日志聚合与实时性能分析。其核心功能包括系统指标收集、容器运行时监控以及与中央管理平台的安全通信。该代理可部署于物理服务器、…

作者头像 李华
网站建设 2026/7/7 18:59:53

Android WheelView滚轮控件终极指南:从入门到精通

作为Android开发者,你是否曾为选择器控件而烦恼?WheelView的出现为你提供了一站式解决方案。这款基于ListView构建的高性能滚轮控件,以其出色的定制能力和流畅的交互体验,正在成为移动应用开发的新宠。 【免费下载链接】WheelView…

作者头像 李华
网站建设 2026/7/7 12:44:42

Claude Code终极美化指南:一键打造高颜值AI编程终端

Claude Code终极美化指南:一键打造高颜值AI编程终端 【免费下载链接】claude-code Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex c…

作者头像 李华
网站建设 2026/7/7 9:14:03

HumanML3D数据集:3D运动生成的终极实践指南

HumanML3D数据集:3D运动生成的终极实践指南 【免费下载链接】HumanML3D HumanML3D: A large and diverse 3d human motion-language dataset. 项目地址: https://gitcode.com/gh_mirrors/hu/HumanML3D 想要快速掌握3D运动生成技术吗?HumanML3D数据…

作者头像 李华