DESIGN TRACK · 第 15 章

验证:证明 RTL 做对了

用参考模型、随机激励、断言和覆盖率寻找反例

建议用时:10-16 小时本章目标:建立自检查验证环境,覆盖正常、边界、背压、复位和非法访问,并把每条规格映射到测试或断言。

先写验证计划

验证计划不是测试名称清单,而是需求到证据的映射。对每条需求记录刺激方法、检查方法和覆盖点。例如“结果背压期间保持稳定”应由随机切换 out_ready 的测试、scoreboard 数据比较,以及一条稳定性断言共同覆盖。单纯看到波形“像是对的”不能规模化,也无法防止回归。

测试平台通常由 driver、monitor、reference model、scoreboard 组成。driver 只遵守协议发送事务;monitor 从引脚恢复已完成的事务;参考模型用软件算法算期望值;scoreboard 按事务顺序比较期望与实际。不要在 driver 中偷看 DUT 内部状态,否则会掩盖协议错误。

从定向测试走向约束随机

先用少量定向测试打通基本路径:长度 1、最大长度、全 0、全 1、立即接受结果。随后随机化数据、批长度、输入气泡和输出背压。随机测试必须记录 seed,失败才能复现。参考模型可以很简单:在每次输入握手时累加,在输出握手时与 DUT 比较。

property p_output_stable_when_stalled;
  @(posedge clk) disable iff (!rst_n)
    out_valid && !out_ready |=>
      out_valid && $stable(out_sum);
endproperty
assert property (p_output_stable_when_stalled);

property p_no_input_when_idle;
  @(posedge clk) disable iff (!rst_n)
    !busy |-> !in_ready;
endproperty

断言适合协议不变量:状态合法、计数不越界、背压时稳定、一次 start 对应一次完成。它不能替代端到端数据检查,两者要并用。

覆盖率告诉你还没验证什么

代码覆盖率回答哪些 RTL 结构被执行,功能覆盖率回答规格空间是否被探索。功能覆盖点至少包含批长度分桶、连续输入与带气泡输入、不同背压长度、复位发生在 IDLE/RUN/RESULT,以及 overflow 和中断使能组合。交叉覆盖能暴露“每项都测过,但关键组合没测过”。

100% 行覆盖并不等于正确:如果检查器写错,错误结果也能通过。对参考模型做小规模独立单元测试;故意修改一次 RTL,确认测试确实失败。这种 mutation check 能发现“永远绿”的无效验证环境。

本章交付物

  • 需求追踪表:每条规格对应 test、assertion 或 coverpoint。
  • 可复现的一键回归命令,失败日志包含 seed、事务序列和时间。
  • 至少 5 条协议断言与一个独立 scoreboard。
  • 覆盖率报告以及对未覆盖项的解释,不能仅报一个百分比。
通过标准:连续运行数百个随机种子无失败;故意破坏最后一个样本、ready 或复位逻辑时,回归会可靠报错。

工具与延伸资料

← 第 14 章:用 SystemVerilog 实现 RTL