第三章 波形调试技巧:如何高效使用Verdi/DVE定位UVM问题

说实话,很多做UVM验证的工程师,写testbench的时候头头是道,一遇到波形就抓瞎。我见过太多人盯着波形看半天,愣是看不出问题在哪。其实不是你不会看波形,而是你没掌握方法。

今天我就把压箱底的波形调试技巧掏出来。这些方法,都是我这些年踩坑踩出来的。

3.1 别急着看波形,先想清楚要看什么

很多人一上来就打开Verdi,把信号全拖进去。结果呢?满屏都是线,看得眼花缭乱。我个人的习惯是——先问自己三个问题:

  • 这个bug是什么现象?
  • 它可能发生在哪个模块?
  • 我需要看哪些关键信号?

举个例子。有一次我遇到一个AXI总线读数据错位的问题。我没有直接去看所有信号,而是先锁定了几个关键点:araddr、rdata、rvalid、rready。就这四个信号,配合时钟,基本就能定位问题。

我的小技巧:在UVM的monitor里,用`uvm_info把关键事务打印出来。然后对照波形看,事半功倍。我曾经靠这个办法,半小时就找到了别人查了两天的bug。

3.2 Verdi的"三板斧":你必须要会的三个操作

Verdi功能很强大,但说实话,日常调试90%的时间,你只需要用好三个功能。我把它们叫做"三板斧"。

第一板斧:信号追踪(Trace Signal)

这个功能太实用了。你选中一个信号,按快捷键"T",Verdi会自动帮你找到这个信号的驱动源。我经常用它来追根溯源——比如看到某个信号值不对,直接trace回去,看它是怎么被赋值的。

// 举个例子,你在波形里看到apb_wdata的值不对
// 选中apb_wdata,按T
// Verdi会跳转到驱动它的代码位置
// 可能是这样的:
always @(posedge clk) begin
    if (apb_sel & apb_write)
        apb_wdata <= paddr_data;  // 哦,原来是paddr_data传错了
end

第二板斧:波形比较(Waveform Compare)

这个功能我强烈推荐。特别是在做regression debug的时候,把pass的波形和fail的波形放在一起比较,差异一目了然。

操作步骤:

  1. 打开pass的波形文件(.fsdb)
  2. 再打开fail的波形文件
  3. 使用Tools -> Waveform Compare功能
  4. Verdi会自动标出所有不同的地方

我记得有一次,一个DMA传输的bug,我对比了两次波形,发现只是差了一个时钟周期。顺着这个线索,很快就定位到了是握手信号的时序问题。

第三板斧:条件触发(Trigger Setup)

这个功能很多人不知道。你可以设置条件,让Verdi只显示满足条件的波形段。比如我只想看apb_error为高的时候发生了什么:

// 在Verdi的Trigger Setup里设置:
// Condition: apb_error == 1
// 然后Verdi会自动跳转到所有apb_error为高的时刻

3.3 DVE的独门绝技:UVM事务级调试

虽然现在Verdi用得更多,但DVE在某些场景下依然有它的优势。特别是配合UVM的事务级调试。

DVE有一个功能叫"Transaction View",可以直接显示UVM的事务。你想想看,不用去波形里找一个个信号,直接看事务级别的信息,多爽。

调试方式 信号级 事务级
查看内容 单个bit/byte 完整的packet/transaction
调试效率 低,需要手动组合信号 高,直接看事务内容
适用场景 时序问题、接口协议 数据一致性、协议完整性

3.4 实战案例:一个APB接口的bug定位

光说不练假把式。我拿一个真实的案例来演示。

现象:APB slave的某个寄存器读出来一直是0,但明明写进去了数据。

我的调试步骤:

  1. 先看波形中的apb_write和apb_sel信号——确认写操作确实发生了。

  2. 再看paddr和pwdata——确认地址和数据都是对的。

  3. 然后看penable——嗯,这里有问题!penable的拉高时机不对。

// 正确的APB写时序应该是:
// T1: psel拉高,pwrite拉高,paddr有效
// T2: penable拉高,pwdata有效
// T3: 传输完成

// 但波形显示:
// T1: psel拉高,penable同时拉高
// 这违反了APB协议!

注意:很多APB的bug都出在penable的时序上。我曾经因为这个原因,浪费了整整一天。后来我学乖了,遇到APB问题,第一个就查penable。

3.5 高效调试的五个习惯

最后,我总结几个好习惯。这些习惯帮我省了无数时间:

  • 习惯一:每次仿真都dump波形。别省那点磁盘空间,没有波形你什么都查不了。
  • 习惯二:在UVM的driver和monitor里加打印。打印信息和波形对照着看,效率翻倍。
  • 习惯三:学会用Verdi的bookmark功能。看到关键位置就打个标记,回头好找。
  • 习惯四:不要只看一个模块的波形。把上下游模块的波形也拉出来,看数据流是否通畅。
  • 习惯五:遇到复杂问题,先写一个调试计划。列出要检查的信号和时序关系,按图索骥。

嗯,这些就是我这些年用Verdi和DVE调试UVM环境的心得。说白了,波形调试就是个熟练活。多练、多总结,你也能成为高手。

下一章,我会讲怎么用UVM的callback机制来做定向调试。那个更有意思,到时候见。