定向测试与固定种子随机回归

返回 项目总览。

项目包含 5 个 @cocotb.test()。定向测试保证关键边界一定出现,随机测试则组合更多读写序列;两者由同一个 fifo_step() 和 scoreboard 检查。

五个测试分别证明什么

测试主要检查
reset_flags_are_clean复位后 dout=0,empty/full/almost-full 正确
fill_and_drain_in_order写满、满写保护、FIFO 顺序、最终读空
almost_full_threshold阈值前后 flag 精确翻转
simultaneous_read_write_keeps_order连续同拍读写时 occupancy 与顺序保持
randomized_regression1000 周期不同读写组合,再排空并检查顺序

写满读空

测试依次写入 0–15,确认 full 和 almost-full;再尝试写 0xAA,reference queue 必须仍保持原来的 16 项。随后逐项读出,顺序必须还是 0–15。

这同时检查了容量、overflow protection、数据顺序和 pointer wrap。

almost-full 阈值

先写到 threshold-1,要求 flag 为 0;再写一项到 threshold,要求 flag 为 1。测试关注边界的 off-by-one,而不是只在 full 时观察 flag。

连续同拍读写

先放入 6 个初始元素,再连续 20 拍同时读写 40–59,最后排空。reference queue 长度在并发阶段保持不变,但内容持续滚动,可发现读写顺序或 pointer 更新错误。

固定种子随机流

rng = random.Random(20260527)

1000 个周期中:

  • 写请求概率约 58%;
  • 读请求概率约 52%;
  • din 均匀取 0–255;
  • 测试结束后继续读,直到 reference queue 为空。

固定种子意味着每次得到同一序列。发现 bug 后可以稳定复现、查看波形和缩小失败周期,而不会因为下一次随机流变化而消失。

固定一个种子不是多种子回归

当前只有 20260527 一个 Python seed。1000 周期增加了序列长度,但不等价于覆盖多种随机轨迹。

当前测试没有证明什么

  • 没有 coverage 数据证明每种 occupancy、读写组合或 pointer wrap 被命中多少次。
  • 没有测试 reset 在非空或同拍读写过程中突然拉低。
  • 没有运行不同 DATA_WIDTH、DEPTH、threshold 的配置矩阵。
  • 没有 assertion 检查 count 范围、指针范围或 flag 互斥关系。
  • 没有 fault injection 证明每类检查器都能在预期位置失败。

建议的下一轮测试

  1. seeds 作为环境变量输入,在 CI 中运行一组固定 seed matrix。
  2. 增加 DEPTH=3/10/16 等 2 的幂与非 2 的幂配置。
  3. 非空、full 和同拍读写期间分别注入异步复位。
  4. 统计 occupancy、accepted read/write、empty/full 边界与 wrap 事件覆盖率。
  5. 故意破坏 count、write protection 和 read ordering,验证 scoreboard 会失败。

自测

  1. 为什么 random 1000 周期仍不能替代 almost-full 定向边界测试?
  2. 固定 seed 的主要价值是什么?
  3. 测试结束后排空 reference queue 能额外发现什么问题?

答案要点:随机流不保证精确边界;稳定复现;验证剩余元素的完整顺序且最终 empty 正确。

面试复述要点

我用定向测试锁定 reset、full/empty、almost-full 和并发读写边界,再用固定种子的 1000-cycle random traffic 扩大序列组合。每拍都由 deque model 检查,随机结束后继续 drain,避免尾部数据未被验证。

上一篇:deque 与 Scoreboard。下一篇:CI 与项目复盘。