2. Verdi环境搭建与工程加载

Verdi 的调试能力并不是在打开波形那一刻才开始的,而是从环境变量、编译数据库和设计层次加载方式就已经决定。很多“信号拉不出来”“层次树是空的”“源码点不进去”的问题,根源都在环境搭建阶段。本节围绕 Verdi 启动流程、KDB/FSDB 编译、设计层次加载以及验证平台信号可见性配置四条主线展开,目标是让读者能够独立完成一次可复现的工程加载。

一、Verdi 启动流程与关键环境变量

Verdi 的启动本质上是“先定位安装目录,再加载配置,最后打开数据库或波形”。在 Linux 环境下,通常先设置 VERDI_HOME,再把 $VERDI_HOME/bin 加入 PATH,同时设置许可证相关的 LM_LICENSE_FILE 或 SNPSLMD_LICENSE_FILE。一个典型的环境准备片段如下:

export VERDI_HOME=/tools/synopsys/verdi/V-2023.03
export PATH=$VERDI_HOME/bin:$PATH
export LM_LICENSE_FILE=27000@lic_server
export NOVAS_HOME=$VERDI_HOME   # 兼容旧脚本

启动方式有两种常见形态:一是直接执行 verdi 打开图形界面,再通过 File → Open 加载 KDB 或 FSDB;二是带参数启动,例如 verdi -dbdir ./simv.daidir/kdb -ssf dump.fsdb &,一次性把设计数据库和波形都挂载进来。后者在回归调试中效率更高,因为它省去了手工点选路径的步骤。需要注意的是,-dbdir 指向的是 KDB 目录,而不是 FSDB 文件;-ssf 才是波形文件。两者混用会导致“设计树为空但波形能打开”或“设计树正常但波形加载失败”两类典型现象。

二、KDB 与 FSDB 的编译生成

KDB(Knowledge Database)是 Verdi 用于保存设计层次、源码映射和信号属性的编译数据库,FSDB(Fast Signal Database)则是仿真过程记录的波形数据库。二者由不同工具在不同阶段生成,理解这一点是排障的关键。

KDB 通常由 VCS 在编译阶段通过 -kdb 选项生成,并配合 -lca 启用更完整的调试信息。示例编译命令如下:

vcs -full64 -sverilog -debug_access+all \
    -kdb -lca \
    -f filelist.f \
    -top tb_top \
    -o simv

编译完成后,会在 simv.daidir 下生成 kdb 目录。若缺少 -kdb,Verdi 打开时只能看到源码,无法建立完整的层次与信号索引;若缺少 -debug_access+all,则部分信号在波形中不可见或无法被 force。FSDB 则由仿真运行阶段的 PLI 接口生成,需要在 testbench 中调用 $fsdbDumpfile 与 $fsdbDumpvars:

initial begin
    $fsdbDumpfile("dump.fsdb");
    $fsdbDumpvars(0, tb_top, "+all");
    $fsdbDumpMDA();
end

其中 0 表示转储所有层次,+all 表示包含多维数组和记忆体,$fsdbDumpMDA() 用于转储多维数组。若只写 $fsdbDumpvars(1, tb_top),则只记录 tb_top 下一层,深层信号在 Verdi 中会显示为“未记录”,而不是“不存在”,这是初学者最容易误判的地方。

Verdi 工程加载链路:环境 → 编译 → 数据库 → 波形 → 可见性 环境变量 VERDI_HOME PATH / LICENSE VCS 编译 -kdb -lca -debug_access+all KDB 数据库 simv.daidir/kdb 层次 / 源码映射 FSDB 波形 $fsdbDumpvars dump.fsdb Verdi 加载 verdi -dbdir kdb -ssf dump.fsdb 验证平台信号可见性配置 dump 层次深度 · +all 选项 · MDA 转储 · 接口/类信号映射 · force 权限

三、设计层次加载与源码映射

当 KDB 与 FSDB 都准备好后,Verdi 打开工程时会做三件事:解析 KDB 中的层次树、把层次节点映射到源码文件与行号、把 FSDB 中的信号名与层次节点做匹配。如果源码映射失败,双击信号只会跳到空文件或错误行号,常见原因是编译时源码路径与当前路径不一致。此时可以在 Verdi 中通过 Tools → Source Path Mapping 添加路径重映射,或在编译时使用 -y 与 +incdir+ 明确指定搜索路径。

层次加载的另一个关键点是顶层选择。若编译时 -top 指定为 tb_top,但实际仿真中真正被例化的顶层是 soc_top,Verdi 的层次树会以 tb_top 为根,导致部分 DUT 层次被折叠。建议在编译前确认顶层一致,或在 Verdi 中使用 Hierarchy → Set Top 手动切换根节点。切换后,信号列表会重新按新根节点组织,之前保存的波形分组可能需要重新绑定。

四、验证平台信号可见性配置

验证平台中大量信号位于 interface、class、package 或 generate 块内,默认情况下不一定出现在波形窗口。要让这些信号可见,需要从三个层面处理。

第一层是转储范围。使用 $fsdbDumpvars(0, tb_top, "+all") 可以覆盖绝大多数层次,但 +all 会显著增大 FSDB 体积。工程中更常见的做法是分层转储:对 DUT 使用 0 全层次,对验证平台只转储关键接口和 monitor 信号。例如:

$fsdbDumpvars(0, tb_top.u_dut, "+all");
$fsdbDumpvars(1, tb_top.u_axi_if);
$fsdbDumpvars(1, tb_top.u_monitor);

第二层是接口与类信号。SystemVerilog interface 中的信号在 KDB 中通常以 interface_name.signal_name 形式出现,若 interface 通过 virtual interface 传递,需要在编译时保留调试信息。class 内部变量默认不进入波形,需要借助 $fsdbDumpvars 对 class 句柄所在层次转储,或使用 Verdi 的 Signal → Add to Waveform 从类作用域中手动添加。

第三层是 force/deposit 权限。若需要在 Verdi 中直接修改信号值,编译时必须包含 -debug_access+all,否则信号只能观察不能驱动。对于三态信号和双向端口,还需要确认 +all 是否覆盖了 +struct 与 +packed 选项,否则结构体成员可能显示为合并后的位向量。

判断可见性配置是否成功的快速方法:在 Verdi 中打开 Hierarchy 窗口,展开到目标信号所在层次,若信号名显示为灰色或带锁图标,说明未转储或未授权;若信号名正常但波形为一条直线,说明已转储但该时间段无翻转,需要检查仿真时间范围与触发条件。

五、一次可复现的加载检查清单

把上述过程固化为可重复执行的检查顺序,可以显著减少环境类问题。建议按以下顺序确认:环境变量是否指向正确版本;编译是否带 -kdb -lca -debug_access+all;KDB 目录是否生成;FSDB 是否由 $fsdbDumpfile 正确命名;$fsdbDumpvars 的层次与选项是否覆盖目标信号;Verdi 启动参数中 -dbdir 与 -ssf 是否分别指向 KDB 与 FSDB;源码路径是否需要重映射;顶层是否与编译一致。任何一步缺失,都会在后续调试中以“信号找不到”或“源码跳转失败”的形式暴露出来。

完成以上配置后,Verdi 才真正具备“从波形反查设计、从设计定位信号”的能力。下一阶段的所有故障定位操作,都建立在本节所搭建的这条加载链路之上。