先写验证计划
验证计划不是测试名称清单,而是需求到证据的映射。对每条需求记录刺激方法、检查方法和覆盖点。例如“结果背压期间保持稳定”应由随机切换 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 或复位逻辑时,回归会可靠报错。
工具与延伸资料
- Verilator documentation:lint 与高性能 RTL 仿真。
- Yosys documentation:RTL 综合与网表处理。
- OpenROAD documentation:开放的 RTL-to-GDS 物理设计流程。
- SkyWater Open Source PDK:开放工艺设计规则与库资料。