![[Verilog HDL]第七章 调试用系统任务和常用编译预处理语句](http://pic.xiahunao.cn/yaotu/[Verilog HDL]第七章 调试用系统任务和常用编译预处理语句)
一、调试显示类系统任务1. $monitor 监控打印任务1. 核心特性仿真启动仅初始化一次参数信号任意跳变自动打印无需重复调用2. 配套控制开关$monitoron开启监控、$monitoroff关闭监控3. 语法模板$monitor(格式字符串, 参数1,参数2...);4. 底层执行位置层次化事件队列监控队列同一时间片所有赋值完成后执行永远打印更新后最新数值5. 使用场景多模块长期监测信号变化无需反复写打印语句。2. Verilog 层次化事件队列区分display/strobe 底层原理同一仿真时刻5 个队列固定执行先后顺序动态事件队列 → #0 延时队列 → 非阻塞更新队列 → 监控队列 → PLI 队列动态事件队列最先执行 执行阻塞赋值、计算右侧表达式、$display打印、assign 连续赋值 缺陷$display会在非阻塞变量更新前执行容易打印旧值、不定态 x。#0 延时队列存放带 #0 延迟的阻塞赋值动态队列跑完才执行。非阻塞更新队列统一批量刷新所有左侧寄存器变量。监控事件队列最后执行$monitor、$strobe全部变量刷新完毕再输出一定打印当前周期最终值。PLI 队列C 语言交互接口。3. display 与 strobe 核心区分任务执行队列打印结果适用场景$display动态队列赋值未完成可能打印旧值即时查看中间运算值$strobe监控队列时间片全部赋值结束后打印结果准确时序逻辑打印避免时序 bug二、时间读取系统函数time/realtime1. timescale 时间尺度指令语法格式timescale 时间单位 / 时间精度约束规则精度≤单位单位 / 精度仅支持 1/10/100单位 fs/ps/ns/us/ms/s。模块内所有 #延时、time/realtime 均以该单位为基准。精度代表最小仿真刻度延时数值会四舍五入到精度整数倍。 示例timescale 10ns/1ns单位 10ns精度 1ns#1.6 等价 16ns。2. $time 系统函数返回 64 位整数会根据 timescale 单位四舍五入存在时间误差。例题timescale 10ns/1ns#1.6 延时后 $time 输出 2。3. $realtime 系统函数返回实数完整保留小数无取整精准获取仿真时间。同上例题延时后输出 1.6适合需要精确时间的仿真场景。三、仿真流程控制任务finish/stop1. $finish退出整个仿真软件结束全部仿真进程可带参数输出不同等级调试信息。2. $stop仅暂停仿真保留仿真窗口可手动继续运行多用于分段调试波形。3. 适用场景测试用例跑完调用$finish中间关键节点插入$stop断点调试。四、存储器初始化 $readmemb / $readmemh1. 基础语法$readmemb(文件名, 存储器数组)读取二进制文本文件$readmemh(文件名, 存储器数组)读取十六进制文本文件扩展语法可指定加载起始、结束地址。2. 数据文件规范数字仅允许对应进制可包含空白、换行、注释地址标识十六进制数字指定下一行数据存入的存储单元下标不定态规则单 bit x/z 小写4bit 完整字节全不定输出大写 X/Z无数据地址默认填充 x。3. 加载匹配规则未指定起止地址从存储器最低下标连续填充文件与代码地址范围不匹配、数据数量不符仿真直接报报错仅仿真可用不能综合硬件电路。示例代码reg [7:0] mem[0:15]; initial begin $readmemb(init.dat, mem); end五、随机激励 $random 系统函数1. 基础用法{$random}%N生成 0~N-1 无符号随机整数拼接 {} 消除符号位 示例rand {$random}%60生成 0~59 随机数。2. 仿真实战场景随机延时# 20 * (1{$random}%3)随机脉冲高低电平、随机输入总线构建全覆盖测试激励仅适用于 Testbench 仿真无法综合生成电路。完整随机脉冲示例reg [9:0] dout; integer delay1,delay2; initial begin #10 dout0; for(k0;k100;kk1)begin delay1 20 * ({$random}%6); delay2 20 * (1{$random}%3); #delay1 dout 1 ({$random}%10); #delay2 dout 0; end end六、编译预处理指令 开头编译阶段执行1. 宏定义 define语法define 宏名 替换字符串调用宏名。特性单纯文本替换无语法检查编译报错在展开后才出现。支持层叠嵌套宏宏名区分大小写建议大写区分变量。易错坑宏末尾不能加分号分号会一同带入替换产生语法错误运算类宏不加括号运算优先级错乱。2. 文件包含 include作用将外部.v 完整文本插入当前文件实现多模块拆分复用语法include 文件名.v支持相对 / 绝对文件路径规则支持多层嵌套包含可同一行写多个 include被包含文件宏定义全局生效工程用途顶层文件包含所有子模块简化编译脚本。3. 时间尺度 timescale前文 3.1 完整讲解全局 / 模块单独定义多模块可设置不同单位精度。4. 条件编译ifdef /else / endif1. 语法结构ifdef 宏名 程序段1 else 程序段2 endif2. 执行逻辑定义过目标宏则编译第一段否则编译 else 分支3. 工程用途区分仿真 / 综合两套代码、多版本硬件兼容、屏蔽调试代码4. 拓展配套指令ifndef未定义则编译、elsif 多分支。七、本章重点汇总1. 打印系统任务核心考点事件队列执行顺序决定打印结果display即时、strobe/$monitor 同步延时打印最终值。%m格式符自动打印模块层级路径多模块调试必备。x/z 打印固定规则单 bit 小写、4bit 完整字节全不定大写 X/Z。2. 时间系统函数易错点time受timescale影响会四舍五入存在仿真时间误差高精度仿真必须用realtime 实数。timescale 精度不能大于时间单位延时会自动对齐精度整数倍。3. 存储器与随机激励专用任务readmemb/readmemh 仅仿真文件地址标识 、进制格式严格匹配否则加载失败。{$random} 消除符号位生成 0~N-1 随机数用于构建随机测试激励不能综合硬件。4. 四大预处理指令必考区分define 文本直接替换无语法校验严禁末尾加分号。include 拼接外部源文件支持多层嵌套模块化工程必备。timescale 统一模块仿真单位与精度影响时间系统函数输出。ifdef 条件编译一套代码适配仿真、综合多场景屏蔽调试代码。5. 通用仿真任务通用规则全部以 $ 开头系统任务仅仿真 Testbench 可用无法综合生成数字电路。多模块调试优先使用monitor自动监测、strobe 时序打印规避赋值时序错位打印错误。仿真结束用finish退出软件中间断点调试使用stop 暂停。6. 高频踩坑清单混淆display与strobe 时序时钟沿赋值后打印旧值。define 宏末尾写分号展开后产生多余分号语法报错。timescale 精度大于单位语法违规。$readmem 文件进制与存储器匹配错误、地址范围不匹配导致加载 x。直接使用 $random 不加大括号出现负数随机数。组合逻辑内混用非阻塞赋值未把中间变量加入敏感列表输出延迟一拍。