4. Verdi与DVE调试自动化集成

回归跑完之后,真正消耗工程师时间的往往不是仿真本身,而是“打开调试工具、找到那个用例、加载波形、把上次看过的信号重新拖出来、再切到断言和覆盖率视图”这一整套重复动作。Verdi(VCS 的原生调试环境)和 DVE(Discovery Visualization Environment)都支持通过命令行参数、脚本文件和会话文件在启动时自动完成这些动作。本节的目标是把这些能力组织成一个可复现的调试入口:给定一个失败用例的目录,一条命令就能把波形、信号数据库、断言视图和覆盖率视图全部恢复到可分析状态。

4.1 调试入口需要携带哪些信息

一个可复现的调试入口,本质上是一组“上下文参数”的封装。对 Verdi/DVE 而言,这些参数可以分为四类:

  • 仿真数据库位置:FSDB 波形文件路径(Verdi 常用)或 VPD 波形文件路径(DVE 常用),以及对应的仿真可执行文件与 kernel 数据库(simv.daidir)。
  • 信号数据库:即设计层次与信号清单,通常来自编译产生的 KDB/daidir,配合 .rc 信号配置文件或 Verdi 的 signal.rc,用于恢复上次关注的信号组。
  • 断言视图:SVA 断言在波形中的标注、失败时间点、以及断言源码位置,需要仿真时开启断言记录(如 -assert dumpoff 的反面配置)才能回溯。
  • 覆盖率视图:由 URG 生成的覆盖率数据库(.vdb),在 Verdi/DVE 中以覆盖率浏览器形式加载,用于定位未覆盖的 bin 与对应源码行。

把这四类信息写死在每个人的命令行里是不可复现的。正确做法是让回归平台在用例失败时自动生成一个“调试包”,其中包含一个启动脚本和一个会话文件,工程师只需执行该脚本。

4.2 自动加载波形与信号数据库

Verdi 启动时可通过 -ssf 指定信号配置文件,通过 -nologo 跳过启动画面,通过 -dbdir 指定 KDB 目录。一个典型的自动加载命令如下:

verdi -dbdir ./simv.daidir \
      -ssf ./waves/fail_1024.fsdb \
      -ssf ./waves/fail_1024_assert.fsdb \
      -nologo \
      -play ./debug/session_1024.rc \
      -f ./debug/signals_1024.rc &

其中 session_1024.rc 是 Verdi 会话脚本,用于恢复窗口布局、已打开的信号组、光标位置和时间范围;signals_1024.rc 是信号清单,记录该用例关注的总线、时钟、复位和关键状态机信号。这两个文件由回归平台在用例失败时从模板生成,模板中的变量(用例名、种子、FSDB 路径、失败时间)由平台注入。

DVE 的对应方式是使用 -vpd 指定波形、-sim 指定可执行文件,并通过 -session 加载 DVE 会话文件:

dve -vpd ./waves/fail_1024.vpd \
    -sim ./simv \
    -session ./debug/dve_session_1024.tcl \
    -testplusarg "seed=1024" &

DVE 会话文件本质是 Tcl 脚本,可以在其中调用 wave add、wave format、run 等命令,把信号添加和视图切换写成可执行脚本。相比手工拖拽,这种方式在批量失败用例上优势明显。

失败用例 → 可复现调试入口的数据流 回归平台 用例名 / seed 失败时间 / 退出码 工作目录路径 调试包生成器 模板 + 变量注入 生成 .rc / .tcl 生成 run_debug.sh 调试包内容 session_1024.rc signals_1024.rc run_debug.sh cov_report/ 一键启动 ./run_debug.sh Verdi 自动加载 -dbdir simv.daidir(信号数据库) -ssf fail_1024.fsdb(波形) -play session_1024.rc(视图恢复) DVE 自动加载 -vpd fail_1024.vpd(波形) -sim ./simv(可执行) -session dve_session_1024.tcl 断言视图 SVA 失败点标注 覆盖率视图 URG .vdb 加载

4.3 断言视图与覆盖率视图的自动加载

断言视图的自动加载依赖两个条件:仿真时断言信息被记录进波形,以及 Verdi/DVE 启动时打开断言窗口。在 VCS 编译时使用 -assert svaext 并在仿真时保留断言数据库,FSDB 中就会包含断言活动记录。Verdi 中可通过会话脚本执行 assert -open 打开断言窗口,并用 assert -select fail 直接定位到失败断言。

覆盖率视图的自动加载则依赖 URG 生成的覆盖率数据库。回归平台在用例结束后调用 urg -dir simv.vdb -format both -report cov_report 生成 HTML 与文本报告,同时保留 simv.vdb 供 Verdi 加载。Verdi 中通过 cov -open -db simv.vdb 打开覆盖率浏览器,DVE 中通过 coverage -load simv.vdb 加载。这样工程师在同一个调试会话里就能从波形失败点直接跳到覆盖率未覆盖的 bin。

4.4 可复现调试入口的脚本模板

下面给出一个可直接参考的调试包生成脚本片段。它接收用例名、种子和失败时间作为输入,生成 Verdi 启动脚本与信号配置文件。示例参数为教学假设值,实际使用时由回归平台注入。

#!/bin/bash
# gen_debug_pkg.sh —— 由回归平台在用例失败时调用
CASE=$1          # 例如 fail_1024
SEED=$2          # 例如 1024
FAIL_TIME=$3     # 例如 875000
WORKDIR=$4       # 例如 /regr/run/fail_1024

PKG=$WORKDIR/debug
mkdir -p $PKG

# 1. 生成信号配置文件
cat > $PKG/signals_${SEED}.rc <<EOF
# 关注信号清单(示例)
add wave -group "clk_rst" clk rst_n
add wave -group "bus"     dut.axi_awaddr dut.axi_awvalid dut.axi_awready
add wave -group "fsm"     dut.ctrl_state
EOF

# 2. 生成 Verdi 会话脚本
cat > $PKG/session_${SEED}.rc <<EOF
# 恢复视图布局与光标
window layout restore $PKG/layout_${SEED}.rc
cursor set $FAIL_TIME
zoom fit
assert -open
assert -select fail
cov -open -db $WORKDIR/simv.vdb
EOF

# 3. 生成一键启动脚本
cat > $PKG/run_debug.sh <<EOF
#!/bin/bash
cd $WORKDIR
verdi -dbdir ./simv.daidir \\
      -ssf ./waves/${CASE}.fsdb \\
      -nologo \\
      -play $PKG/session_${SEED}.rc \\
      -f $PKG/signals_${SEED}.rc &
EOF
chmod +x $PKG/run_debug.sh
echo "调试入口已生成: $PKG/run_debug.sh"

这个脚本的关键点在于:所有路径都使用绝对路径或相对于工作目录的固定路径,避免依赖工程师当前所在目录;信号清单和会话脚本按种子命名,便于同一用例不同种子之间的对比;启动脚本本身可执行,工程师只需复制一行命令即可。

4.5 结果判断与常见问题

调试入口是否真正可复现,可以用三个判据检查:第一,在干净终端中执行 run_debug.sh,Verdi/DVE 能自动打开且波形已加载到失败时间附近;第二,信号窗口中已出现信号清单中的分组,无需手工添加;第三,断言窗口显示失败断言,覆盖率浏览器能加载 simv.vdb 并定位到未覆盖 bin。

常见问题包括:FSDB 文件未生成或路径错误,通常是因为仿真时未加 -fsdb 或 $fsdbDumpfile 未设置;断言窗口为空,通常是编译时未开启断言记录;覆盖率数据库加载失败,通常是 URG 未运行或 simv.vdb 被清理。排查时优先检查调试包中的路径是否存在、文件大小是否为零,再检查 VCS 编译与仿真选项是否与模板一致。

建议把调试包生成逻辑做成回归平台的标准后处理步骤,而不是依赖工程师手工执行。这样每个失败用例都天然带有一个可复现的调试入口,团队之间的调试上下文也能通过共享调试包目录来传递。