案例研究 · 多 FPGA 系统

把第二块 FPGA 变成第一块的扩展仓

一块板子上两块大 FPGA,用八条 10 千兆串行通道相连。哪块单独都不够用,于是第二块成了第一块的扩展仓: 额外算力,加四千兆字节远程内存,都跨这条链路可达。

AlgoSilicon 工程团队 · 2026

一块板子上有两块大 FPGA:一块是托管射频的 Zynq UltraScale+ RFSoC,一块是 Kintex UltraScale,中间用八条高速串行通道相连。这个设计哪块芯片单独都不够用,于是我们把第二块变成第一块的扩展仓: 模块放过去算,旁边那 4GB DDR4 拿来当远程内存,都跨这条链路可达。整个动手过程由 AI 在 Python2Verilog 框架下完成,工程师只在每一步给方向。

真实的 RFSoC 开发板:Zynq UltraScale+ RFSoC 模块在偏中左,Kintex UltraScale FPGA 在偏中右,左侧一列是射频 SMA 接头,右下是八条 10G 串行链路的 SFP 笼
真实的板子:RFSoC 模块在偏中左,Kintex FPGA 在偏中右,左侧一列是射频接头, 右下的 SFP 笼是八条 10G 链路。两块 FPGA,一条宽链路,四千兆字节 DDR4。

链路:八条通道,每条十千兆

每条通道是两对差分线,一对一个方向,两块芯片之间连了八条。每条通道走 64B/66B 块编码:每 64 位数据配一个 2 位同步头,接收端连续看到足够多的合法同步头就锁定。这些收发器额定速率高达数十千兆每秒,这里跑在十千兆附近。 一条通道双向都跑真实字节、逐字节精确。要拓宽,就把多条通道捆成一条更宽的通道:两条并跑的捆绑已经过了自己的 逐字节闸,而完整的多通道捆绑还在收口,有一个返回方向仍卡在板子上。所以八条通道是物理预留,如今真正在用的链路 只跑一条。而要让这一个方向跑通真实字节,费了一番功夫,下文再讲。

一套我们自己的链路协议

最初用的是 FPGA 厂商自带的高速链路。在这块板子上它没通,而且是有实测原因的:写反的接线把链路逼进了一些 永远走不完的模式,缺陷叠着缺陷。于是这条链路跑的是我们自己写的协议,块编码还是那套 64B/66B,但成帧是我们自己 的。它刻意做得很薄。四种块类型撑起整条流:空闲、帧起、数据、帧尾;一个自同步扰码器让线路保持平衡;块锁定即 链路建立。没有训练握手,没有信用额度,没有链路层校验或应答。每个方向各自独立,任意一端随时可以加入。

要自己拥有这条链路,原因是物理性的,而且改不掉。每条通道本身就是全双工,所以麻烦不在方向,而在顺序: 在这块载板上,八条通道在铜箔里是反序走线的,Kintex 一侧的收发器通道 0 到 3 接到标号 7 到 4(递减)的通道 网络上,而 RFSoC 一侧是递增的,于是 RFSoC 的第 i 条对上 Kintex 的第 7 减 i 条。厂商的链路按第 N 条对第 N 条 来捆绑,捆绑要靠一致、预期的通道顺序去做去偏斜和锁定;顺序一反,捆绑就永远完不成:每条通道各自能到块锁定, 可整个通道始终到不了通道建立,双工链路就是不通。退回单工又撞上厂商链路在 Kintex 收发器上的另一个限制,到这里 就该收手了。我们自己的链路从不捆绑通道,自带成帧,所以通道反序对它根本无所谓。这也是为什么先前那条写反的记录 代价那么大:这个反序是铜箔里改不掉的事实,不只是一张写错的表。

数据和控制共用这一条流,按每帧的第一拍来分。一个内存帧以命令、长度、地址开头:写操作把负载突发进远端 DDR4, 再回来一拍应答;读操作只有帧头,返回一个应答帧头加数据。一个控制帧以带标记的一拍开头:寄存器读写、链路重初始化、 状态计数器,甚至跨链路给第二块芯片热重启,全程不接 JTAG。计算则完全不需要操作码。Wi-Fi 译码器就串在链路的接收 和发送之间,于是一帧进来就是它的输入,译出的结果直接成帧送回。

可靠性是刻意做到最简。块锁定自行恢复,流上带着反压跨过一个异步跨时钟缓冲,内存写操作等自己的应答。没有校验, 也没有重传,因为在这个距离上,逐字节精确的结果表明它不需要。一条通道稳定跑到约 3.0 千兆每秒、逐字节精确,也是在 这条链路上,我们把配置和一份 8.56 兆字节的启动镜像逐字节送进第二块芯片,之后它就从闪存自启动,全程不接 JTAG。

四千兆字节内存,从一份 75 页 PDF 里抠出来

第二块芯片旁的 4GB DDR4 没有任何机器可读的引脚文件,只有一份 75 页的原理图 PDF,而它的 64 位接口有 119 个引脚,手抄错一根线就是一次校准失败。于是 AI 把它变成一个几何问题:提取每页每个词和它的坐标框,把每个 网络名和同一行里最近的引脚号配成一对,并要求每个网络都配两次、必须配到同一个引脚,否则整份作废。这道零冲突 硬闸解出 117 个网络,零冲突,连藏在复用名字里的地址线也认了出来。裁判是厂商的内存控制器 IP:它一路跑到布局, 字节组和 bank 合法性检查全部通过,全程不靠人眼看图纸。烧进板子,DDR4 第一次上电校准就通过。

从原理图 PDF 到可信引脚表,全程机器完成:带坐标提取、几何配对、117 个网络零冲突硬闸、厂商 IP 当裁判,最后第一次上电即校准
从 75 页 PDF 到一份可信引脚表,全程机器提取、机器验证。117 个网络,零冲突,DDR4 第一次上电即校准。

第二块芯片一身兼三职

链路能跑真实字节、内存也校准之后,第二块芯片承担了三种角色,全部在真实硬件上验证。一次 256KB 的往返在 链路上回来逐字节精确。一个放在第二块芯片上的 Wi-Fi LDPC 译码器,吃进 1296 字节软信息、吐出 164 字节判决, 与基准模型比对零错,中间不复位连跑两次仍零错。跨链路写 4KB 再读回逐字节精确,换个深地址再来一遍仍精确。 从此第二块芯片对第一块就是三样东西:一条逐字节精确的链路、一个算力节点、一块 4GB 远程内存。

0 误差
一个跑在第二块芯片上的 Wi-Fi 译码器,进 1296 字节、出 164 字节,与基准模型逐字节比对

一份记录骗过了每一项检查

要让这条链路双向跑通真实字节,是最难的一环,而它就藏在唯独没人去测的地方。一个方向很快通了,另一个一直 在滑动,永远差一点锁定,没有报错,没有崩溃。于是我们逐层测量,每一层都通过:厂商自带的例程仿真建起了链路; 一次自环仿真逐位精确地传过一帧;一次按真实接线连好的跨芯片仿真回环逐字节精确;对仿真导线上 40 万比特的分析 发现,在唯一正确的偏移上同步头 100% 合法;对好坏两版布线后网表逐引脚的对比,结果完全相同。接收端的扫描显示 眼睛又大又干净,水平张开度 77.8%、垂直 93.6%。信号无可挑剔,问题不在信号。

到此为止的每个读数都是统计出来的数字。于是我们加了一个一次性抓取器,把锁定状态下连续三拍的原始 64 位字 直接读回来。回来的是 0011 循环,一个纯方波,一个自由振荡的时钟。扰码数据本该像随机数,这却什么数据都没承载。 而 66 除以 4 余 2,所以按 66 位切帧,每帧相位走 2 位,同步头永远落在 01 或 10 上,两种都合法。一个时钟一直 在冒充一条健康的链路。

一个周期为 4 的方波如何同时满足同步头锁定、CDR 锁定、眼图和同步头合法率,却不承载任何数据
一个纯时钟图案喂饱了每一项指标:CDR 锁定、干净的眼图、完美的同步头合法率。每个指标都满足了,唯独没有数据。

于是我们把通道接线重新量了一次:只认物理通道名,不认工具序号,每条通道发一个不一样的二进制编码标记, 三轮解出全部八条,结果和我们一直信任的那份记录正好相反。发送端一直往一条没人监听的通道上发正确的数据, 而被监听的那条,连着一条从未配置的通道,自由振荡出那个方波。所有仿真都照同一份记录接线,记录内部自洽, 所以每次仿真都通过。

记录在案的映射是第 i 条对第 i 条,实测的映射却是反的:第 i 条对第 7 减 i 条,于是 0 号发的数据到了没人监听的通道
记录说通道是直连的,实测说它们是反着连的。在反着连的接线下,数据去了没人监听的那条通道。

之前对这八条线已经跑过一次误码率测试,其中七条零误码,那它怎么会漏掉一对接反的线?因为那种测试往每条线上 发同一个伪随机序列:不管谁连着谁,每个接收端都能锁定、都报零误码。它对"谁连着谁"天生是盲的。每条铜线确实都好, 错的是"谁对谁"那张表。修法是换到正确的两条通道上重建,一次就通,逐字节精确。排查途中顺手修掉的三个真实 bug 都留下了,但都不是根因。还留了个尾巴:之前的测试在其中一条线上测出过少量误码,正好就是反向链路一直在用的那条, 于是把这条线单独泡了十分钟。6 万亿比特,零误差,眼图张开度和其他七条一个水平。

留下的三条准则

每一条都写回了框架,成为每次构建都会跑的强制检查。

锁定不等于数据。一个方波能同时满足同步头锁定、CDR 锁定、干净的眼图和完美的同步头合法率。 一条链路只有在解出真实载荷、逐字节对上时才算验收通过。

地图只认物理名字。通道接线用两端的物理名记录,用每条一个的独立标记实测。工具的编号不算 "谁连着谁"的证据。

引脚表只信机器。原理图引脚用几何配对提取,只有每个网络都零冲突解出才放行,再由厂商 IP 验证,而不是靠人读图。

为什么这件事重要

第二块 FPGA 成了第一块经过验证的扩展仓:一条 10 千兆管道、一个算力节点、一块四千兆字节远程内存,每一项都 在真实板子上逐字节验证。让这一切成立的,是自始至终同一份纪律:每一层都对着真实读数验证,相信硬件的真实状态, 而不是描述它的那份文档。那条只写反了一行的记录能存活整整一天,正是因为每一次仿真都老老实实照着它接线,而修法 是去测导线,而不是重读记录。整套系统就是这样,一步一个测量地拼起来的。

有链路或板子调不通?

我们把高速链路、多 FPGA 板卡、射频前端从裸硬件带到一个可测量、逐字节精确的系统,一次验证一层。 告诉我们你在调什么。

设计服务