2. 验证计划与签核标准

在复杂SoC验证中,验证计划不是一份“任务清单”,而是把设计规格(Spec)中的功能承诺,翻译成可执行、可度量、可签核的验证契约。它向上承接架构与微架构规格,向下约束激励生成、覆盖率采集和回归策略,最终决定“什么时候可以停”。如果验证计划只写“验证DMA功能”“验证中断控制器”,那么覆盖率驱动签核就无从谈起,退出标准也只能靠感觉判断。

从Spec到验证计划:把自然语言变成可验证断言

Spec通常以自然语言描述功能、接口、时序和异常行为。验证计划的第一步是提取“可观测、可激励、可判定”的验证点。以AXI总线从设备接口为例,Spec中可能写着:“当写响应通道返回SLVERR时,主机应能通过中断状态寄存器读取错误原因。”这句话可以拆成三个验证点:写响应错误注入、中断状态寄存器更新、主机读取路径。每个验证点再细化为验证项,例如:

  • 功能点:写响应SLVERR注入后,中断状态寄存器bit[3]置1;
  • 激励:通过VIP强制B通道响应为SLVERR;
  • 检查:读取中断状态寄存器,比较期望值;
  • 覆盖率:错误类型交叉写地址区域、突发长度、响应延迟。

验证计划通常包含以下字段:验证项ID、所属功能域、Spec引用、验证方法(定向/随机/形式)、激励描述、检查机制、覆盖率模型、优先级、签核责任人。其中“检查机制”必须明确是scoreboard、断言还是参考模型,不能只写“检查正确性”。

验证计划不是一次性文档。随着Spec更新、RTL变更和覆盖率反馈,验证项应持续增删改,并保留变更记录,确保签核时能追溯到最终版本。

覆盖率驱动签核:从“跑了很多用例”到“覆盖了该覆盖的”

覆盖率驱动签核的核心逻辑是:用覆盖率模型量化“验证空间”的探索程度,用回归结果证明“已覆盖空间”的正确性。覆盖率通常分为代码覆盖率和功能覆盖率。代码覆盖率包括行覆盖、条件覆盖、翻转覆盖、FSM覆盖等,由工具自动采集;功能覆盖率由验证工程师根据验证计划编写covergroup,描述设计意图的交叉组合。

以DMA控制器为例,功能覆盖率可以定义如下:

covergroup dma_cg @(posedge clk);
  cp_burst_len: coverpoint burst_len {
    bins len_1  = {1};
    bins len_4  = {4};
    bins len_8  = {8};
    bins len_16 = {16};
  }
  cp_src_region: coverpoint src_addr[31:28] {
    bins region0 = {4'h0};
    bins region1 = {4'h1};
    bins region2 = {4'h2};
  }
  cp_dst_region: coverpoint dst_addr[31:28] {
    bins region0 = {4'h0};
    bins region1 = {4'h1};
  }
  cx_burst_region: cross cp_burst_len, cp_src_region, cp_dst_region;
endgroup

假设cross共产生4×3×2=24个交叉仓,回归后报告显示覆盖了21个,剩余3个未覆盖。此时不能简单认为“覆盖率87.5%可以接受”,而要分析未覆盖仓是否可达。如果某个交叉仓对应“burst_len=16且源地址在region2且目的地址在region1”,而Spec明确禁止该组合,则应在covergroup中设置ignore_bins或illegal_bins,而不是强行激励。如果该组合合法但未被激励命中,则需要补充定向用例或调整随机约束。

签核准则与退出标准:把“感觉够了”变成“证据充分”

签核准则(Sign-off Criteria)是验证完成前必须满足的量化条件,退出标准(Exit Criteria)是项目层面允许流片或交付的门槛。两者通常包括:

维度典型指标示例阈值
功能覆盖率所有covergroup覆盖仓100%,或未覆盖仓有书面豁免
代码覆盖率行覆盖、条件覆盖、翻转覆盖行覆盖≥99%,条件覆盖≥95%
回归通过率随机回归用例通过率连续3轮100%通过
缺陷收敛未关闭缺陷数量与严重度无致命/严重缺陷,一般缺陷≤3且已评估
断言覆盖断言触发与成功证明所有断言至少触发一次,无未证明断言

退出标准还需要定义“覆盖率闭包”流程:当覆盖率未达到100%时,必须对每个未覆盖项给出豁免理由,例如“该交叉仓对应Spec禁止场景”“该翻转位为测试模式保留位,功能模式下不可达”。豁免必须由设计、验证和系统负责人共同评审,不能由验证工程师单方面决定。

从Spec到签核:验证计划与覆盖率驱动闭环 设计规格 Spec 功能描述 / 接口时序 异常行为 / 性能约束 验证计划 验证项ID / Spec引用 激励 / 检查 / 覆盖率模型 优先级 / 责任人 覆盖率模型 代码覆盖:行/条件/翻转 功能覆盖:covergroup 交叉覆盖 / 断言覆盖 回归执行 随机+定向 多轮收敛 覆盖率分析 未覆盖仓分类 可达性判断 豁免/补激励 签核准则 覆盖率阈值 回归通过率 缺陷收敛 退出标准 流片/交付 评审签署 证据归档 覆盖率反馈:补充验证项 / 调整约束 / 更新计划 关键判断: 覆盖仓命中 → 检查通过 → 计入签核证据 未覆盖仓 → 可达性分析 → 补激励或豁免 回归失败 → 缺陷修复 → 重新回归 Spec变更 → 验证计划更新 → 覆盖率模型同步

签核评审:证据链比数字更重要

签核评审会上,验证团队需要展示的不是“覆盖率99.2%”这一个数字,而是完整的证据链:验证计划版本、覆盖率报告、回归日志、缺陷列表、豁免记录、断言证明结果。评审者会重点追问:未覆盖的0.8%是什么?为什么可以豁免?豁免是否经过设计确认?回归是否在最终RTL版本上执行?如果这些问题无法回答,即使覆盖率数字很高,签核也不能通过。

一个实用的做法是建立“签核检查表”,每个验证项对应一行,包含:验证项ID、覆盖率状态、回归状态、缺陷状态、豁免状态、评审结论。只有当所有行都标记为“通过”或“已批准豁免”时,该功能域才允许签核。这样,验证计划、覆盖率、签核准则和退出标准就形成了一个可追溯、可审计的闭环。

覆盖率100%不等于设计正确。覆盖率只证明“该激励的场景被触发了”,不证明“检查机制一定能发现错误”。因此,签核时必须同时确认scoreboard、断言和参考模型的有效性,必要时通过故障注入验证检查机制本身。