4. 覆盖率数据库与报告生成

仿真跑完只是第一步,真正决定覆盖率闭环能否推进的,是“数据能不能被正确读出、正确聚合、正确解读”。VCS 在仿真过程中把覆盖率信息写入覆盖率数据库(coverage database),而 urg(Unified Report Generator)负责把这些数据库合并、过滤并渲染成可读报告。理解这两者的关系,才能避免“跑了半天却看不出哪里没覆盖”的困境。

一、VCS 覆盖率数据库:simv.vdb 的目录结构

使用 -cm 编译并仿真后,VCS 默认在当前目录生成 simv.vdb 目录。它不是单个文件,而是一棵按层次组织的数据库树。典型结构如下:

simv.vdb/
├── snps/                 # 元数据与设计层次信息
├── design/               # 设计覆盖率(行/条件/分支/状态机/翻转)
│   └── tb_top/
│       └── dut/
├── test/                 # 测试覆盖率(testbench 侧)
├── assert/               # 断言覆盖率
├── group/                # 覆盖组(covergroup)数据
└── simv.db               # 数据库索引与配置

关键点在于:每次仿真默认会覆盖或追加到同一个 vdb。如果希望保留多次运行的独立数据,应在仿真时用 -cm_name 指定不同名字,例如 -cm_name run_smoke、-cm_name run_regress,从而得到 simv.vdb.run_smoke 这类独立目录。合并时再把这些目录一起交给 urg,这是回归覆盖率聚合的标准做法。

覆盖率数据库是二进制格式,不要手工编辑。需要查看原始数据时,用 urg -dir simv.vdb -show tests 之类的命令读取,而不是直接打开文件。

二、urg 报告生成:从数据库到可读报告

urg 的基本调用形式是:

urg -dir simv.vdb -format both -report urgReport

其中 -dir 可以接受多个数据库目录,实现多轮回归合并;-format both 同时生成 HTML 与文本报告;-report 指定输出目录。生成后目录中会出现 dashboard.html、tests.html、groups.html 等页面,以及对应的 .txt 文本版本。

合并多个数据库时,urg 会按“同一覆盖点取并集”的方式聚合:只要任意一次运行命中过该覆盖点,合并结果就视为已覆盖。这正是回归覆盖率能提升的原因。需要注意,合并的前提是各次运行的编译配置一致,否则覆盖点无法对齐,urg 会给出不匹配警告。

VCS 覆盖率数据库 → urg 报告生成链路 仿真运行 simv -cm line+cond -cm_name run_smoke simv.vdb.run_smoke design / test / assert group 覆盖率数据 urg 合并 -dir run1 run2 run3 覆盖点取并集 urgReport HTML + 文本 dashboard.html 常见 urg 过滤与提取选项 -metric line+cond+fsm 只统计指定覆盖率类型 -mod dut_top 限定模块/层次范围 -show tests 列出各测试对覆盖的贡献 -elfile exclude.el 排除指定覆盖点 -report urgReport 指定输出目录 -format text 仅生成文本报告

三、HTML 与文本报告解读

HTML 报告的入口是 dashboard.html,它给出整体覆盖率概览:按 line、condition、branch、toggle、fsm、assert、group 分类列出“已覆盖/总数/百分比”。点击某一类可下钻到具体模块,再下钻到具体行或条件。文本报告(如 dashboard.txt、groups.txt)内容等价,适合在终端或 CI 日志中快速查看。

解读时重点关注三类信息:

  • 未覆盖项的具体位置:HTML 中未覆盖的行/条件通常以红色或黄色高亮,并给出源码行号,直接对应到 RTL 或 testbench。
  • 覆盖组的 bin 命中情况:groups.html 会列出每个 covergroup 的每个 bin 是否命中,未命中的 bin 就是需要补激励的目标。
  • 测试贡献度:配合 -show tests,可以看到每个 test 命中了哪些覆盖点,从而判断哪些用例是冗余的、哪些场景还缺。

四、覆盖率指标提取与常见过滤选项

在回归流程中,通常不满足于“看报告”,而是要把覆盖率数字提取出来做门禁判断。urg 支持通过 -metric 指定统计类型,通过 -mod 限定模块,通过 -elfile 排除不关心的覆盖点。例如只关心 DUT 顶层及其子模块的行覆盖率与条件覆盖率:

urg -dir simv.vdb.run1 simv.vdb.run2 \
    -metric line+cond \
    -mod dut_top \
    -elfile exclude.el \
    -format both \
    -report cov_merge

其中 exclude.el 用于排除已知不可达或不需要统计的覆盖点,常见写法是按模块或按行号排除:

// exclude.el 示例
module dut_top.legacy_block {
  line 120-135;
}
module dut_top.debug_only {
  all;
}

提取出的数字可以进一步用脚本解析 dashboard.txt 中的百分比字段,写入回归结果表,作为“覆盖率是否达标”的自动判断依据。常见门禁阈值示例:行覆盖率 ≥ 95%、条件覆盖率 ≥ 90%、断言覆盖率 ≥ 85%,未达标则回归失败并输出未覆盖清单。

过滤选项会直接影响最终百分比。使用 -elfile 排除覆盖点后,分母会变小,覆盖率数字会上升。因此排除项必须经过评审并记录在案,不能为了“好看”而随意排除。

把数据库、合并、报告、过滤、提取串起来,覆盖率数据才真正成为可驱动验证收敛的闭环输入,而不是一份看完就丢的静态报告。