覆盖率优化与验证收敛策略

📅 2026/7/2 13:30:14 👁️ 阅读次数 📝 编程学习
覆盖率优化与验证收敛策略

覆盖率优化与验证收敛策略

覆盖率数据收集完了,数字不达标怎么办?本文是覆盖率系列的第二篇,聚焦优化与收敛——覆盖率未达标分析、.el 豁免文件管理、FSM 深度解读、CDV 三阶段验证法,以及实战案例。

本系列共两篇:① 理论与实战篇 | ② 优化收敛策略篇(本文)


一、覆盖率未达标时的分析与优化

1.1 定位未覆盖点

在 Verdi 中直接点击红色未覆盖行或低覆盖率信号/状态,思考为何测试激励没有触发这些代码。

1.2 常见原因与解决方案

原因解决方案
激励不足优化随机约束增加多样性,或针对边界场景编写定向测试用例
环境配置/约束冲突检查验证环境,确保约束条件正确且无冲突
设计/代码冗余与设计工程师确认后,对冗余代码进行豁免(Waive)

1.3 覆盖率豁免操作

对于确认无需覆盖的代码,在 Verdi 中右键点击该行 → 选择Exclude进行豁免。

关键注意:豁免操作必须File → Save Exclusions保存到.el文件后才生效。下次打开数据库时,可通过-elfile waivers.el加载。

1.4 合理豁免的场景

  • 模块复用:同一模块多次例化且功能相同,只需分析其中一个实例
  • 厂商 IP:第三方提供的库模型,可 exclude
  • 不可达代码:由于参数配置导致不可能执行的分支

二、直接用例与随机用例的协同策略

2.1 核心定义

直接用例随机用例
定义激励序列仿真前已完全确定激励由随机生成器在约束下动态产生
目标精准验证已知功能和关键路径高效探索庞大验证空间,冲击边角情况
可控性极强,完全确定、可重复体现在约束规则上,而非具体数值
覆盖率贡献单次通过后重复仿真价值有限更换种子即可自动提升覆盖率

2.2 实战策略:三阶段验证法

  1. 冒烟测试阶段— 用少量直接用例验证基本功能(复位、标准操作、已知边界)
  2. 随机探索阶段— 大量随机用例覆盖功能空间,推动覆盖率收敛
  3. 查漏补缺阶段— 针对覆盖率报告中的盲区编写定向用例

直接用例如同"精确制导导弹",目标明确攻克已知堡垒;随机用例如同"智能侦察集群",在规则下大规模探索发现未知雷区。两者相辅相成。

三、状态机覆盖率深度解读

3.1 FSM 覆盖率报告核心结构

一份典型的 FSM 覆盖率报告包含:

  • 综合覆盖率分数— 宏观指标,必须深入细节
  • 状态列表— 所有状态及是否被进入过(√ 已覆盖 / × 未覆盖)
  • 状态转移矩阵— 所有转换路径及是否被测试,这是报告的精髓

一个拥有 N 个状态的 FSM,理论上最多有 N×(N-1) 种转换需要测试。

3.2 分步解读流程

第一步:定位未覆盖项— 寻找所有被标记为 Uncovered 的状态和转移路径

第二步:分析原因

原因类型示例
激励不足需构造特定错误场景才能进入 ERROR 状态
设计冗余/不可达3-bit 编码共 8 种但只定义了 5 个有效状态
环境约束限制配置寄存器被约束在固定值,阻止了某些路径

第三步:关联其他覆盖率— 未覆盖状态通常对应case语句中未执行的分支,交叉验证可精确定位 RTL 位置

3.3 FSM 覆盖率提升策略

策略说明
优化随机约束引导随机生成器产生能触发特定状态转移的数据包/控制信号
编写定向测试针对随机激励难以覆盖的极端边角情况
审查与豁免确认冗余/不可达逻辑后豁免,但必须谨慎并留文档

四、.el 豁免文件管理

4.1 创建豁免文件

两种方式:

  • GUI 操作:Verdi 中右键 Exclude → Save Exclusions 保存为.el文件
  • 手动编写:直接编辑.el文件指定豁免行

4.2 加载豁免文件

有两种加载方式:

方式一:仿真后查看时加载(Verdi)

verdi-cov-covdirsimv.vdb-elfilewaivers.el

方式二:编译/仿真阶段直接排除(推荐用于固定豁免项)

vcs-full64\-cmline+cond+fsm+tgl+branch\-cm_excl_filecoverage_exclusions.el\-cm_dir./cov_db/simv.vdb\<其他编译选项>

.el文件示例:

// 排除调试代码 EXCLUDE LINE "counter" "counter.sv" 13 // 排除不可达条件 EXCLUDE COND "counter" "counter.sv" 13 // 排除默认分支 EXCLUDE BRANCH "counter" "counter.sv" 16

选择建议:固定且确认的豁免项建议用-cm_excl_file在编译时就排除,这样生成的.vdb数据更干净;临时调试的豁免项用 Verdi GUI 操作后保存。

4.3 关键注意事项

要点说明
版本更新RTL 代码修改后 checksum 变化,.el 文件中的条目会出现异常图标,需逐一处理
Save As处理完豁免条目后,千万不要直接覆盖原文件,必须 Save As 新文件
批量操作使用urg -dump full_exclusions导出所有豁免
绕过 checksum-excl_bypass_checks选项仅对行覆盖率有效
核心原则豁免前务必与设计工程师确认逻辑是否真的无需覆盖

4.4 覆盖率分析完整工作流速查

阶段核心操作产出所用工具
环境设置加载环境变量、配置工具激活的环境shell
编译+仿真运行测试用例、-cm收集数据.vdb数据库VCS/simv
数据合并urg合并多测试 vdbmerged.vdbURG
报告解读Verdi/DVE 分析未覆盖区域漏洞列表Verdi/DVE
优化迭代改约束/写定向测试/合理豁免更高覆盖率全链路

这个5阶段闭环就是 CDV(Coverage-Driven Verification)的核心——覆盖率驱动验证,每轮迭代都从报告解读开始,直到所有关键指标达标。

五、实战案例:4-bit 逻辑运算单元

以一个 4-bit 逻辑运算单元logic_op的验证为例,12 个测试用例的回归结果:

指标结果是否达标
DUT 行覆盖率97.06%✅ 达标
DUT 条件覆盖率88.46%⚠️ 接近目标,已知 RTL bug 导致部分路径不可达
DUT 分支覆盖率93.33%✅ 达标
DUT 翻转覆盖率19.87%❌ 但 4-bit 设计此值属正常

分析结论:2 个失败测试(xnor、mode_switch)均因同一已知 RTL bug。通过覆盖率分析成功定位验证盲点,指导了后续测试优化。

CDV 三阶段实操复盘

阶段用例数LineBranchConditionToggle关键操作
冒烟测试4 个直接用例60%55%50%8%复位、ADD、SUB、基本边界
随机探索6 个随机用例95%→97%85%→93%75%→85%15%→19%随机 opcode+addr,种子轮换
查漏补缺2 个定向用例97.06%93.33%88.46%19.87%针对 xnor/mode_switch 写定向测试

可以看到:随机探索阶段是覆盖率跃升的关键,Line/Branch/Condition 都有 10~20% 的跳跃;而查漏补缺阶段精准补盲,Condition 从 85% 提升到 88.46%(差值看似不大,但覆盖的是最难触发的角落路径)。

六、总结

覆盖率优化与收敛的五大要点:

  1. 代码覆盖率是底线— 低覆盖率一定意味着验证不充分
  2. 功能覆盖率是深度— 100% 代码覆盖不等于没有 bug,需要功能覆盖补盲
  3. 断言覆盖率是保障— 协议检查和属性约束的触发情况
  4. 豁免必须谨慎— 每一条 exclude 都需要设计工程师确认和文档记录
  5. 三阶段验证法— 冒烟 → 随机探索 → 查漏补缺,直接用例和随机用例协同

覆盖率不是终点,而是验证收敛的度量工具。结合代码覆盖率、功能覆盖率和断言覆盖率,构建多维度验证度量体系,才能真正为流片加上最后一道安全锁。


参考资料

  • Synopsys VCS User Guide — Coverage Metrics & -cm_excl_file
  • Synopsys Verdi User Guide — Coverage Exclusion Manager
  • 《Writing Testbenches using SystemVerilog》— Janick Bergeron