第一百二十七章 合并
颜天磊用了三天时间改 DISPATCH_MISS。
他做的第一件事是把两层优先级判断写在纸上——不是画在白板上,是写在 A4 纸上,一条一条列出来,然后一行行看哪里有重复。
第一层判断的是请求是不是缓急请求,第二层在同优先级里按到达时间排队。这两层逻辑在原来的设计里是串行执行的,颜天磊想看的是有没有可能把它们折叠成一个判断。
他折腾了两天,找到了一个合并方案:先对到达时间排序,缓急请求在排序键里直接权重更高,相当于把两层判断合并进同一个比较操作里,组合逻辑从两级变成了一级。
改完之后跑 Design Compiler,得到了新的时序报告。
DISPATCH_MISS 那条路径,slack 从零点三纳秒升到了零点八纳秒。
颜天磊把这个数字发给贺志明,「好一些了,」他说,「从零点三到零点八。」
贺志明那天下午过来,把 DC 的综合报告打开,细看了几分钟,「你这个合并做了,」他说,「思路对。但零点八在 28nm 下不够——你现在用的是 FreePDK45,是 45nm 的库,等我们拿到真实工艺的标准单元库,时序会更紧,加上工艺角的变动,这个零点八可能直接变负。」

「所以还是得加寄存器,」颜天磊说。
「还是得加,」贺志明说,「但合并这步做了是好事,你先把逻辑层级减下来,然后再在剩下的地方打断,代价最小——要是不合并直接加寄存器,你可能要加两级,延迟代价加倍。」
「那我现在在哪里加?」
贺志明指了一下报告里的那段路径,「在比较操作结束之后、出队信号发出之前,」他说,「这里是组合逻辑最长的那段,打断。」
颜天磊花了一个晚上加了 pipeline register。
代价是在仲裁周期里多了一个时钟延迟——原来从请求到出队是三个时钟周期,现在变成了四个。
他把改完的版本发给贺志明,「你说会影响回填延迟的 spec,」他说,「我查了一下文档,KV-cache miss 的回填延迟预算是十五个时钟周期,加一个周期的仲裁延迟,剩下的预算还够。」

「你查过了,」贺志明说,「好,那就加。」
加了寄存器之后再跑一次 DC,新的时序报告出来了。
DISPATCH_MISS 那条路径的 slack:一点四纳秒。
贺志明看到这个数字,「这才是真实工艺可以用的数字,」他说,「一点四,考虑工艺角和温度变化,还有余量。你去把这次修改写进设计文档,把第一版的零点三、合并之后的零点八、加寄存器之后的一点四,三个数字都写进去,写清楚每次改动做了什么。」
「这要写进去?」颜天磊说,「只是过程数字。」
「过程数字比结论数字更重要,」贺志明说,「结论告诉你现在是什么状态,过程告诉你为什么这样做——下一次如果有人改这段代码,不知道这段历史,很可能以为那个 pipeline register 是多余的,给删掉了。」
颜天磊点了一下头,打开文档,把三个数字和修改记录整整齐齐地写了下去。

方宇明那天下午过来看了最终版的时序报告,「仲裁模块这段,」他说,「可以往下走了。」
「KV-cache buffer 这边,」贺志明接了一句,「Cadence 的授权下周到,我拿到 Virtuoso 就开始做 SRAM 单元的自定义版本,到时候你们的行为模型换成真实单元,时序数字会更准。」
「还要再跑一次,」颜天磊说。
「还要再跑一次,」贺志明说,「但那次的数字你可以信——不是教学用的库,是真实工艺的库。」
方宇明看了一眼颜天磊白板上的那几行字,「进度表里,」他说,「这块打完,下一个里程碑是整块 KV-cache 前端逻辑的集成测试,包括仲裁、SRAM 接口、优先级队列、miss 路径,全部接上,走通一个完整的端到端路径。」
「时间线,」颜天磊说。
「Cadence 来了、SRAM 单元出来,大概还要三周,」方宇明说,「十月底。」

「好,」颜天磊说,「十月底。」
那天晚上,陆衍在 B207 的门口站了一会儿,没有进去。
颜天磊在屏幕前看设计文档,把那几个数字又看了一遍;贺志明已经走了;孟思远在整理下一批仿真用例。
陆衍拿出手机,发给豆包一条消息:「仲裁模块时序修完了,slack 一点四纳秒,贺志明说可以了。下一步十月底,集成测试。」
豆包回了一句:「一点四纳秒,这个数字在一个月前没有——它是慢慢从数字里找出来的。」
陆衍:「对,慢慢找出来的。」
他把手机放进口袋,往走廊另一头走了。B207 里的灯还亮着,会亮到很晚。