第一百三十一章 集成
十月二十八日,周三。
方宇明在早上的站会上说:「今天的目标,KV-cache 前端集成测试,端到端跑通。」
他没有多说,把手边的进度表推到桌子中间,上面用红框标出了这一行:KV-cache frontend integration — target: Oct 31。
今天是 28 号,还有三天,他们决定今天就跑。
集成测试的准备工作颜天磊做了一周。
他的工作是把四个部分连起来:仲裁模块(自己写的)、SRAM 接口(连接到贺志明的单元模型)、优先级队列(孟思远写的辅助模块)、miss 回填路径(从主存模拟器拉数据回来的那条路)。四个部分之前都单独测过,现在要第一次接在一起,走完一条真实的端到端路径。
端到端是指:一个推理请求进来,仲裁模块判断是命中还是未命中,命中就直接从 SRAM 读数据返回,未命中就走回填路径从主存拉数据、写进 SRAM、再返回。整个链条走完,从输入到输出,不断在中间某个地方。
颜天磊在周二晚上把 testbench 写完,连接检查跑了两遍,没有明显的接口错误。
测试在上午十点开始。
孟思远在仿真环境里构造了一批测试用例:前二十个请求全部命中(SRAM 里预先填好了数据),后十个请求全部未命中(SRAM 里没有,需要回填)。这样可以分两段验证,先看命中路径,再看未命中路径。
命中路径跑完:全部通过。

二十个请求,每个都在仲裁模块里走了 DISPATCH\_HIT 状态,从 SRAM 读到数据,在正确的时钟周期返回,时序没有违例,数据没有错误。
「命中路径,好的,」颜天磊说。
然后是未命中路径。
第六个未命中请求卡住了。
仿真停在 cycle 1847,miss 路径的回填操作卡在等待信号上,不往下走了,仿真进入了一个死循环——回填控制器一直在等一个确认信号,但那个信号始终没有到来。
颜天磊把 waveform 打开,把那个信号找出来,向上追溯。
「这个信号,」他说,「应该是 SRAM 写操作完成之后拉高的——你们看 SRAM 接口那边有没有发出去。」
贺志明过来看了一眼,「SRAM 的写完成信号是发出去了,」他说,「但看一下地址计数器,那个信号是在计数器到达什么值的时候发出的?」
孟思远把地址计数器的波形调出来,「在计数器等于 CACHE\_DEPTH 的时候,」他说。
贺志明盯着波形,「CACHE\_DEPTH 是什么值?」

「256,」颜天磊说。
「你们的地址计数器从 0 开始,」贺志明说,「最后一个有效地址是 255——计数器等于 256 的时候,实际上已经越界了,写完成信号发出来的时候地址是无效的。」
颜天磊反应过来,「是差一错误,」他说,「边界条件——计数器应该在等于 CACHE\_DEPTH - 1 的时候触发,不是 CACHE\_DEPTH。」
「对,」贺志明说。
这是孟思远写的那段代码里的问题。
他翻出来,找到那一行:
```verilog if (wr_addr == CACHE_DEPTH) begin wr_done <= 1'b1; end ```
改成:
```verilog if (wr_addr == CACHE_DEPTH - 1) begin wr_done <= 1'b1; end ```
两个字符的差距。
改完之后重新编译,重新跑仿真。

这次未命中路径的六个卡住的请求全部正常走完了——回填操作在正确的时钟周期触发写完成,确认信号在正确的时刻到来,后续的请求继续处理。
十个未命中请求,全部通过。
孟思远把结果打印出来,放在方宇明桌上,「全绿,」他说。
方宇明看了一遍,在进度表上那一行旁边打了一个勾,「十月二十八日,」他说,「提前三天。」
他停了一下,「差一错误,」他说,「你们第一次找到它花了多长时间?」
「大概四十分钟,」颜天磊说。
「不算慢,」方宇明说,「这种错误很常见,重要的是不要绕过去,要把原因找清楚——你们知道为什么会出现这个边界条件问题吗?」
「计数器设计的时候,」孟思远说,「我是用 CACHE\_DEPTH 作为上限,但没有想到地址是从 0 开始的,最后一个有效地址是 CACHE\_DEPTH - 1,所以触发条件写错了。」
「那下次怎么避免?」
「写测试用例的时候,」孟思远说,「专门测边界——第一个地址、最后一个地址、越界地址,三个边界都要测。」

「好,」方宇明说,「写进测试规范里。」
那天下午,陆衍在 B207 待了一会儿。
颜天磊在整理今天的测试报告,贺志明在看一份关于时钟树综合的文档,孟思远在更新测试用例,把边界测试补进去。
陆衍发了一条消息给豆包:「集成测试通过了,提前三天,命中路径和未命中路径都通过,有一个差一错误被发现修好了。」
豆包回:「差一错误(off-by-one)是计算机里最常见的 bug 类型之一——从有了数组就有了这个问题。孟思远的反应很好,知道下次怎么防,这比这次改对更重要。」
陆衍:「他当时说要专门测边界。」
豆包:「这句话值钱。」
陆衍看着 B207 里的三个人,各自在做各自的事,安静,专注。窗外已经快黑了,上海十月末的傍晚比上个月暗得早一些。
砺火一号的 KV-cache 前端,今天走通了第一条完整的路径。
它还不是硅,但它第一次真实地运行了。