2. 验证计划制定

验证计划不是把设计规格书抄一遍,而是把“设计要做什么”翻译成“验证要证明什么、用什么手段证明、证明到什么程度算够”。它上承设计规格,下接测试用例、覆盖率收集与签核标准,是数字验证项目中最关键的中间产物。本节围绕四个动作展开:需求分解、覆盖率目标定义、验证策略选择,以及如何在 Cadence vManager 中把计划落成可跟踪、可度量的对象。

一、从设计规格到验证需求分解

设计规格描述的是功能行为,验证需求描述的是“可被激励、可被观测、可被判定”的检查点。分解的核心动作是把每条规格拆成若干条可验证需求(Verification Requirement),每条需求必须能回答三个问题:激励从哪里来、结果在哪里看、判定依据是什么。

以一条典型规格为例:“当 AXI 从设备收到非对齐地址的突发写请求时,应返回 SLVERR,且不修改目标寄存器。”这条规格可拆为三条验证需求:

  • REQ-001:构造非对齐起始地址的 AXI 写突发,检查从设备返回 BRESP=SLVERR。
  • REQ-002:在 REQ-001 场景下,读取目标寄存器,确认其值保持原值不变。
  • REQ-003:对齐地址的同类突发应返回 OKAY 并正确写入,作为对照,防止“一律报错”的假通过。

分解时建议给每条需求标注属性:来源规格条目、优先级(高/中/低)、验证层次(模块级/子系统级/SoC 级)、激励类型(定向/随机)、检查方式(断言/参考模型/记分板)。这些属性直接决定后续策略与覆盖率映射。分解的常见陷阱是把“实现细节”当成需求,例如“状态机在 IDLE 停留 2 拍”,若规格未约束,就不应作为验证需求,否则会锁死实现、产生脆弱的测试。

二、覆盖率目标定义

覆盖率目标要区分三类:代码覆盖率、功能覆盖率和断言覆盖率。代码覆盖率(行、分支、条件、翻转)是“下限”,通常要求行覆盖率与分支覆盖率达到 100%,但达到 100% 并不等于验证充分。功能覆盖率才是验证计划的核心,它把验证需求映射为可采样的覆盖点(coverpoint)与交叉(cross)。

定义功能覆盖率时,先确定采样对象与仓(bin)。例如针对上面的需求,可定义:

covergroup cg_axi_write @(posedge clk);
  cp_addr_align: coverpoint addr[1:0] {
    bins aligned   = {2'b00};
    bins unaligned = {2'b01, 2'b10, 2'b11};
  }
  cp_resp: coverpoint bresp {
    bins okay  = {2'b00};
    bins slverr= {2'b10};
  }
  x_align_resp: cross cp_addr_align, cp_resp;
endgroup

交叉覆盖点 x_align_resp 会强制“非对齐×SLVERR”和“对齐×OKAY”两个组合都被命中,这正是需求 REQ-001 与 REQ-003 的量化表达。覆盖率目标应写成可判定的数字,例如:功能覆盖点 100% 命中、关键交叉 100%、非关键交叉≥95%、代码行覆盖率 100%、分支覆盖率 100%。同时要定义“豁免(waiver)”规则:确实不可达的仓需记录原因并经评审,不能默默忽略。

覆盖率目标应在计划阶段就与设计、系统、验证三方评审确认,而不是仿真跑完再补。目标一旦确定,就作为 vManager 中的度量基线。

三、验证策略选择

策略选择回答“用哪种手段覆盖哪类需求”。常见组合是:定向测试覆盖边界与异常路径,约束随机(CRV)覆盖大组合空间,形式验证(Formal)证明局部断言,硬件加速或 Emulation 覆盖长序列与软硬件协同。选择依据是需求的可控性与状态空间大小。

例如寄存器访问、复位序列、低功耗状态跳转等强时序需求,适合定向测试加断言;数据通路、仲裁、缓存替换等组合爆炸场景,适合约束随机加参考模型;而“任何情况下不会同时授权两个主设备”这类安全属性,适合形式验证直接证明。策略还要明确验证层次:模块级用 UVM 环境快速迭代,子系统级做接口互联,SoC 级跑真实软件负载。

验证计划分解与 vManager 落地关系 设计规格 功能行为 / 接口协议 验证需求分解 REQ-001 非对齐→SLVERR REQ-002 寄存器不变 覆盖率目标 功能覆盖 100% 代码行/分支 100% 验证策略 定向 + 约束随机 断言 + 形式验证 Cadence vManager vPlan 需求树 REQ 节点 + 属性 覆盖率映射 covergroup → REQ 测试用例关联 test → REQ 追溯 回归与度量 run / metric 汇总 签核状态 pass / waiver / open 覆盖率缺口 → 补测试 度量输出 功能覆盖率 96.4% 代码行覆盖率 100% 分支覆盖率 98.7% 未命中:unaligned×OKAY 缺口处理 新增定向用例 调整约束权重 评审 waiver 申请 更新 vPlan 状态

四、在 vManager 中管理验证计划

vManager 的价值在于把上述计划变成“活的对象”。典型落地流程如下:

  1. 在 vPlan 中建立需求树,把 REQ-001 等节点录入,并设置优先级、验证层次、负责人等属性。
  2. 把每条需求与覆盖率模型关联。vManager 支持从 covergroup 或覆盖率数据库导入覆盖项,再映射到需求节点,形成“需求—覆盖点”双向追溯。
  3. 把测试用例(UVM test 或回归列表)关联到需求,明确每条需求由哪些 test 覆盖。
  4. 运行回归后,vManager 汇总各 run 的覆盖率与通过状态,自动计算每条需求的完成度。
  5. 对未命中项,在 vManager 中标记为 open 或提交 waiver,并记录原因与评审人。

一个可参考的 vPlan 需求条目字段示例如下:

字段示例值说明
需求 IDREQ-001唯一标识,便于追溯
描述非对齐 AXI 写返回 SLVERR可验证的行为描述
优先级高决定回归排序
验证层次模块级模块/子系统/SoC
覆盖点x_align_resp关联的 cross
关联测试axi_unaligned_testUVM test 名
目标100%该需求覆盖率目标
状态open / pass / waiver签核状态
常见问题:需求树建得很漂亮,但覆盖率模型没有真正映射到需求节点,导致“覆盖率 100% 却说不清哪条需求被验证”。务必在计划评审时检查追溯链是否完整。

最后,验证计划是动态文档。设计规格变更、覆盖率缺口暴露、策略调整,都应在 vManager 中同步更新需求树与目标值,并保留变更记录。只有计划、覆盖率、测试三者形成闭环,验证签核才有据可依。