全部教程

验证方法论

验证工程师的实战经验:测试规划思维、覆盖率驱动的判断力与调试直觉。

  1. 01一页看懂覆盖率:Functional 与 Code Coverage 的区别分清 Functional Coverage(你声明自己关心什么)和 Code Coverage(工具从 RTL 自动统计出什么)——这是一道常见的面试题,也是整个模块的立足点——在讲任何 covergroup 语法之前先把这件事说清楚。
  2. 02深入 Functional Coverage:bins、Cross 与配置项第 1 章留到这里的 covergroup/coverpoint 完整语法:显式 bins、illegal_bins、ignore_bins、transition bins、带非法组合排除的 cross coverage、option.at_least/weight/goal,以及 get_coverage() 与 get_inst_coverage() 的区别——全部建立在 axil_regfile 真实的地址空间与响应码之上。
  3. 03Code Coverage:Line 与 Branch一份真实的 line/branch coverage 报告到底在统计什么,精确到每一条语句和每一个 case 分支——建立在 axil_regfile 真实的写响应逻辑和这个项目自己真实的测试历史之上,其中包含一个真实的、至今仍然存在的缺口:写路径上两种错误响应从来都没有被测过。
  4. 04Code Coverage:Toggle位级别的 0->1/1->0 活动,跟控制流完全无关——axil_regfile 自己的测试历史里有一个真实的发现:第 1 章专门点出、说很难实现的 AW/W 独立性逻辑,从来没有真正翻转过;s_axi_wstrb 在这个项目写过的每一个测试里都被钉死在同一个常量值上。
  5. 05Code Coverage:FSMState coverage 与 transition coverage,给出精确的定义,直接建立在 axil_regfile 的 aw_have/w_have 锁存逻辑之上——其中一个状态在设计上就结构性地不可能到达,还有一个第 4 章 toggle 报告已经找到的真实缺口,这次用第三种方式再次现身。
  6. 06覆盖率驱动验证:闭合这个环没有新语法——讲的是一个验证工程师真正会拿第 1-5 章的发现去做的事:把覆盖率跨多个测试合并起来,判断每一个缺口到底是真的、结构上不可能、还是没什么价值,把值得补的补上,剩下的写成一条 waiver,而不是悄悄放着不管。
  7. 07什么是验证计划,为什么它要放在最前面“你会怎么验证这个模块”背后真正问的是什么——不是要测哪些测试,而是在任何测试存在之前,什么才算一份验证计划:一份从 spec 推导出来的、前瞻性的文档,跟这个赛道已经为 axil_regfile 建好的测试代码和覆盖率报告都不是一回事。
  8. 08从 Spec 到功能清单一套可重复使用的技术,把一份规格书拆解成功能清单,而不是依赖读完之后想到什么就写什么——直接应用在 axil_regfile 的 AXI4-Lite 基础和寄存器映射上,产出的清单已经明显比这个项目里任何一个测试实际测过的东西更广。
  9. 09场景分类法:合法、边界、非法、并发把一个功能变成场景的四类检查清单,套用在第 2 章 axil_regfile 的 23 项功能清单上——这也是这个模块真正的回报:单靠这套分类法作用在 spec 上,就能抓到 Coverage 模块后来靠测量才找到的那些真实缺口,外加几个 Coverage 从来没有单独抓到过的。
  10. 10基于风险的优先级:先写什么第 3 章那套分类法产出的场景,并不是每一个都同样值得先写。一套似然度/影响力框架,套用在 axil_regfile 真实的开放缺口上——其中一项还有能找到的最有力证据:这块 RTL 恰好已经产生过一个真实的、上线过的 bug。
  11. 11作为活文档的验证计划:可追溯性这个模块的收尾:一条把 spec 要求、计划条目、覆盖率条目、真正的测试串起来的链条,套在 axil_regfile 真实的开放缺口上核实——以及一份会不断吸收新信息的验证计划,信息来源既有测量,也有它自己的规划过程,而不是写一次就冻结。
  12. 12失败到底出在哪:先查这四个地方“说说你会怎么调一个失败的测试”背后真正问的是什么——在碰任何波形之前,一个失败在结构上只可能出在四个地方之一:DUT、testbench、环境,或者压根不是 bug——全部立足于 axil_regfile 上三个真实的、已经记录在案的事件。
  13. 13读懂失败的特征在做深入的诊断工作之前,一个失败呈现出来的样子,本身就已经是它属于第 1 章四个类别里哪一个的线索——是立刻、确定性地出错,还是跟顺序有关,还是压根没跑到仿真那一步就失败了,还是恰好对上了 spec 定义好的某个结果——全部立足于 axil_regfile 那三个真实事件当初实际呈现出来的样子。
  14. 14诊断方法:隔离、插桩、假设、确认真正把第 2 章读特征给出的假设变成确认的那套可重复流程——通过对比它在一个真实的结构性 bug 和一个真实的时序 bug 上分别是怎么展开的来教这套方法,两个都已经记录在 axil_regfile 上,不重新完整讲一遍这两个事件。
  15. 15把 Bug 写下来,闭合这个环确认了根因不是一次调试的终点——一份写得好的记录才是,用 uvm-advanced 第 1 章自己已经发表过的那条 bug 说明作为范例。收尾这个模块,也收尾整个 dv-methodology 赛道,把从 spec 到计划、到覆盖率、到测试、到 bug、到书面记录、再回到计划的整个环追一遍。