1、调试思维筑基:从“代码写对了”到“证据链闭环”的思维转变

说实话,我刚入行那会儿,调试就是“盯着代码看”。觉得代码逻辑没问题,仿真跑不过?那肯定是工具抽风了。结果呢?被 mentor 骂了三次,才明白一个道理:调试不是证明代码对,而是证明代码为什么错

你想想看,我们做验证的,每天花在调试上的时间有多少?我统计过,至少 40%。但很多人调试效率极低,为什么?因为思维没转过来。今天咱们就聊聊这个。

从“代码写对了”到“证据链闭环”

什么叫“证据链闭环”?说白了,就是你的每一个结论,都必须有对应的波形、日志、断言来支撑。不能靠“我觉得”、“我记得”、“应该是这样”。

举个例子。有一次我遇到一个 FIFO 满标志异常。同事说:“这代码我看了三遍,逻辑没问题。” 我说:“那你给我看波形,满标志拉高时,写指针和读指针分别是多少?” 他愣住了。这就是典型的“我觉得对”。

正确的做法是什么?

  • 现象:FIFO 满标志在深度为 8 时提前拉高
  • 证据 1:写指针 = 7,读指针 = 0,差值 = 7 ≠ 8
  • 证据 2:比较器用的是“大于等于 8”,而不是“等于 8”
  • 证据 3:修改后波形对比,满标志正常

这三条证据串起来,才叫闭环。少一条,你都不敢说“修好了”。

核心转变:从“我的代码没问题” → “我的证据链能证明问题在哪”。

每次调试前,问自己一句:如果我现在离职了,下一个人看我的调试记录,能复现我的结论吗?

调试的黄金三原则:复现、隔离、定位

这三个词,我建议你贴在工位上。我自己的调试流程,几乎每次都按这个顺序走。跳步?跳过一步,后面大概率要返工。

第一原则:复现

复现不了的问题,等于不存在。但很多新手会犯一个错:复现条件太模糊。

我曾经遇到一个 bug,只在“某些时候”出现。同事说:“多跑几次就好了。” 我说不行。后来我花了三天,把随机种子、配置参数、输入序列全部固定下来,终于找到了一个 100% 复现的条件。

复现的关键:

  • 固定随机种子:用 +ntb_random_seed 或类似机制
  • 记录输入序列:把激励 dump 成文件
  • 保存配置快照:所有寄存器值、参数、宏定义

我的习惯:每次发现新 bug,第一件事不是看代码,而是写一个复现脚本。脚本里把种子、配置、波形 dump 命令全写好。这样下次回归测试时,一键就能复现。

第二原则:隔离

隔离,就是把问题范围缩小。系统那么大,你不能上来就怀疑是 CPU 核的问题。先确认是软件还是硬件,再确认是哪个模块。

我常用的隔离方法:

  1. 二分法:把信号路径切成两半,看哪一半出问题
  2. 替换法:用理想模型替换怀疑的模块,看现象是否消失
  3. 强制赋值法:在 testbench 里 force 某个信号,看下游反应

举个例子。有一次 AXI 总线读数据一直返回错误。我没急着看代码,而是先做了个实验:用 force 命令把读数据通道的 ready 信号一直拉高。结果错误消失了。这说明问题不在从设备,而在主设备侧的握手逻辑。

注意:隔离时不要同时改多个地方。我曾经一次改了三个信号,结果问题消失了,但根本不知道是哪个改好的。这种“蒙对”的修复,迟早会反噬你。

第三原则:定位

定位,就是找到根因。这一步最考验功力。很多人卡在“现象看到了,但不知道为啥”。

我的定位三板斧:

步骤 做什么 工具/方法
1 看波形,找异常时刻 Verdi、DVE 的波形对比功能
2 追信号,看驱动源 Verdi 的 schematic trace、驱动列表
3 加断言,验证假设 assert 语句、$error 打印

我个人习惯,定位时一定开两个窗口:左边波形,右边代码。看到异常信号,立刻在代码里搜它的驱动逻辑。然后加一句 $display 或 assert,重新跑一遍,看打印信息是否匹配我的猜测。

嗯,这里要注意:不要一次加太多打印。我见过有人一口气加了 50 个 $display,结果 log 文件几十万行,根本找不到重点。我的做法是:每次只加 2-3 个关键信号的打印,跑一轮,分析一轮,再决定下一步。

避坑指南

我曾经犯过的错

  • 复现时没固定种子,导致同一个 bug 时有时无,浪费了两天
  • 隔离时同时改了三个地方的代码,结果问题“修好”了,但回归测试挂了五个用例
  • 定位时只看波形不看代码,盯着一个信号看了半小时,后来发现是 testbench 里 force 错了

这些坑,你大概率也会遇到。提前知道,能省不少时间。

小结

调试思维,说白了就是三个字:讲证据。别信感觉,别信记忆,信波形、信日志、信断言。黄金三原则——复现、隔离、定位——每一步都不能跳。跳了,你就是在赌运气。

下一章,咱们聊聊具体的调试工具和波形分析方法。到时候我会分享一些 Verdi 的小技巧,保证实用。