资讯动态

多片FPGA菊花链互联设计:拓扑选型、链路形态与工程调试

发布时间:2026/10/9 13:08:01 来源:尧图企业网站定制
1. 菊花链的拓扑本质为什么多片FPGA选了这条单行道1.1 节点连接关系与数据流方向多片FPGA组合成系统最常见的方式有三种星型、网格型、菊花链型。菊花链这个名字本身就带着画面感——就像一串糖葫芦每颗果子只和前后各一颗相邻数据从第一颗一路穿到最后。在FPGA系统里菊花链意味着每片FPGA只需要和它的直接邻居建立物理连接。A连BB连CC连D数据从A出发经过B、C再到D中间节点既要收数据也要发数据承担桥的角色。这里有个容易被新人忽略的点菊花链里的数据流方向不是随便定的。它通常遵循业务流的天然顺序。比如最常见的采集链第一片FPGA接ADC做数据采集第二片做滤波或者格式转换第三片做协议打包上传。数据就是单向往前流的后级不需要回给前级大规模数据顶多发一些控制握手信号。我把这类方向称为顺流而下。如果业务本身要求任意两片FPGA之间都能互发大数据菊花链就不是好选择因为中间节点会被迫承担大量无意义的转发工作链路的有效带宽也会被中间节点挤占。换句话说菊花链适合数据流本身具备流水线属性的场景不适合随意互相访问的场景。1.2 与星型、全网状拓扑的取舍说到多片FPGA互联很多人第一反应是星型拓扑一片作为中心交换节点所有数据都汇聚到这里再由它分发出去。这种方案的优点是路由清晰调试简单任何两节点之间的通信都只经过一跳。但缺点也很明显——中心FPGA的引脚资源和逻辑资源被严重压榨。比如四片FPGA组星型中心那片要同时开出三套完整的数据总线每套至少十几根信号线加上时钟、控制、地回流板级布线的压力非常大。而且中心节点一旦出问题整个系统瘫痪单点故障风险很高。全网状拓扑则是极致互联任意两片都直接相连延迟最低灵活性最高。但代价是连接数量呈平方级增长。4片FPGA就要6条链路8片就要28条链路引脚开销和PCB面积在工程上几乎无法接受。绝大多数项目根本用不起这样的拓扑。菊花链的价值就在这里它把连接数量控制在线性增长。4片只需要3条链路8片只需要7条链路。引脚消耗、布线面积、电源复杂度都大幅下降。代价是端到端延迟变大中间节点需要做转发。工程上很多场景完全能接受几百纳秒的额外延迟换来的却是成倍的PCB设计余量。1.3 什么场景该用什么场景不该用我做过的项目里菊花链真正发挥优势的场景有几类多通道数据采集的逐级汇聚、图像传感器的行像素拼接、需要逐级加密或加扰的通信链路。这些场景有一个共同特征数据像河流一样单向流淌后级只处理前级给的内容极少回灌。不适合菊花链的场景也明确多FPGA之间需要频繁交换控制状态、分布式共享内存、实时互锁逻辑。这类需求对任意通信和一致性要求极高菊花链的串行转发会带来不可控的时序复杂度。我曾在一个雷达信号仿真项目里尝试过用菊花链做多片间的实时参数共享结果调试了两周最后拆掉一半链路改成两两直连才解决。方向错了再努力也是事倍功半。2. 链路形态选型并行LVDS、高速SerDes还是JTAG配置链2.1 先把配置链和数据链分开很多刚接触多片FPGA的工程师会把菊花链简单等同于JTAG菊花链。其实这是两个完全不同的概念。JTAG菊花链解决的是FPGA的配置与调试问题。它利用边界扫描机制把多片FPGA的TDI、TDO首尾相接形成一条扫描链。下载bitstream时主控通过JTAG接口把数据依次移入各片FPGA的配置寄存器。这条链只负责把程序灌进去和调试访问不承担业务数据的搬运。数据菊花链才是系统运行时真正传输业务数据的高速通路。它决定了数据能跑多快、延迟多高、误码率多少。设计时必须把这两条链分开规划JTAG链的逻辑简单只要保证扫描链连接正确、TCK时序合适即可数据链才是设计核心需要从带宽、引脚、时钟、PCB走线几个维度综合权衡。2.2 并行LVDS直连简单可靠的起点并行LVDS是最容易上手、也是很多项目最先考虑的方案。它的思路非常直接数据位宽多少就铺多少对差分线再加上一对源同步时钟。比如16bit数据链路就是16对数据线加1对时钟线再加上valid、nready这类握手信号。带宽等于位宽乘以时钟频率在DDR模式下还能再翻倍。并行LVDS的优势是延迟低、实现简单、调试直观。数据在时钟上升沿或双边沿采样逻辑上就是一个同步FIFO的读写。不需要CDR时钟数据恢复不需要参考时钟对对齐也不涉及复杂的协议状态机。对数据吞吐在几个Gbps以内、板级走线距离不超过20cm的场景它非常够用。但它的代价也摆在明面上引脚消耗大。一片中等规模的FPGA可用IO可能也就四五百个如果数据链路是32bit每级连接就要占掉将近70个引脚两片之间还能接受到了三四片引脚资源就开始告急。另外并行总线的等长约束和串扰控制也考验PCB工程师的水平走线一旦过长或者包地不完整时序就很容易出问题。2.3 高速SerDes串行链路带宽换引脚当单链路带宽需求超过2Gbps或者引脚非常紧张就该上高速串行方案。FPGA自带的SerDes硬核可以把数据串行化跑上几Gbps甚至十几Gbps。一片FPGA通常有几十对GT收发器每对收发器就是一对差分线。相比并行LVDS的几十根线串行链路只需要一对线引脚消耗量直接下降一个数量级。在3片以上的菊花链中这个优势会叠加链路越多省的引脚越多。代价是复杂度大幅上升。串行链路需要参考时钟需要做CDR需要处理8b/10b或者64b/66b编码需要链路训练和对齐还需要协议层处理。链路调试时最让人头疼的就是误码率问题——信号质量、参考时钟抖动、电源噪声任何一个环节不稳误码就悄悄出现业务数据就会发生偶发性错误。串行方案和并行方案的选择本质上是在引脚资源布线面积和调试复杂度协议开销之间做权衡。我个人的经验是节点数小于等于3、单链路带宽不超过1.5Gbps时优先考虑并行LVDS节点数多或者带宽要求高再上SerDes。不要一开始就追求高速方案因为菊花链本身已经有转发逻辑要调叠加协议层绝对是调试噩梦。2.4 三种链路的选型对比对比项并行LVDS高速SerDesJTAG配置链承担任务传输业务数据传输业务数据配置/调试/边界扫描单链路带宽中等1~2Gbps高5Gbps以上极低几十Mbps引脚消耗高低极低4根线共享设计复杂度低高低调试难度较低较高低典型延迟几个时钟周期几十到上百时钟周期不参与业务路径这个表格并不是让大家直接照抄而是给一个思考框架任何链路选型都要先回答这条链路在系统里承担什么角色、需要多大带宽、能容忍多少延迟。答案清晰了方案自然就出来了。3. 同步与帧结构设计让多个FPGA在一条链上讲同一种语言3.1 级联复位与同步脉冲多片FPGA级联后的第一个难关是复位。单片FPGA的复位很好处理一个全局复位引脚拉低若干周期就行。但菊花链里有A、B、C三片如果三片各自复位、各自初始化就会出现A已经开始发数据、B还没准备好接收的尴尬状态。级联复位的核心思路有两条要么由一个主控统一控制所有FPGA的复位引脚要么在链路上传播一个同步脉冲。统一控制复位最简单但要求复位信号到每片FPGA的延迟差足够小否则同步精度就没了。我在某个项目里用过这个方案当时复位信号的PCB走线没有做等长结果不同片的复位释放时间差了约几十纳秒恰好卡在链路握手超时的边缘问题极其隐蔽。更可靠的方案是让复位脉冲沿着数据链路逐级传播。第一片FPGA先完成初始化然后向下游发出一个精心构造的同步脉冲第二片收到后再初始化并继续向下传播。这个方案的逻辑实现不复杂但要注意脉冲宽度太窄下游可能采样不到太宽又会影响同步精度。经验值是把同步脉冲宽度做到单链路时钟周期的4倍以上同时保证每级对脉冲的处理延迟完全一致只有这样才能让整条链建立起确定的相位关系。3.2 帧格式与转发模式链路一旦跑起来就必须有明确的帧格式。没有帧格式的数据流只是一堆比特节点无法判断这段数据是给我的还是给后面那片的。我在工程里常用的帧结构是帧头 目标节点号 载荷长度 载荷数据 校验字。帧头可以用几个固定字节比如0xEB90目标节点号告诉每一级节点这帧数据该由谁消费。中间节点收到一帧后做两件事一是判断目标节点号是否等于自己如果是就提取载荷交给本地逻辑处理如果不是就原样转发二是把目标节点号往后传让后面节点也知道这帧数据去往哪里。这里有一个设计选择逐字节透传还是按帧缓冲转发。透传模式延迟最低每过一个节点只增加几个时钟周期但中间节点没有机会检查帧完整性和做校验。按帧缓冲转发的延迟要大得多每级可能增加几十甚至上百个时钟周期好处是可以在中间节点做校验、重组、甚至改变载荷内容再往下发。我在实践中的做法是如果中间节点纯粹做转发用透传模式配合每帧末尾的CRC来做校验如果中间节点要做业务处理比如数据压缩、协议转换必须上按帧缓冲模式。两种模式对应完全不同的逻辑结构设计前一定要想清楚每个节点在链路里扮演什么角色。3.3 流量控制与背压传递菊花链最怕的情况是上游拼命发数据下游处理不过来FIFO溢出数据丢失。解决思路是背压机制让下游把我快满了这个状态一级一级往上传递。每级节点在发送数据前先看下一级能否接收如果下一级发出了反压信号比如nready有效表示暂不可接收本级就暂停发送同时本级也可能是上游的下级于是本级又向上游传达反压最终让最上游降速或者暂停。这个机制看起来简单实现时有一个需要注意的隐藏问题反压信号沿链路反向传播需要时间如果帧长度很大上游在收到反压前已经又发了不少数据中间节点的FIFO深度必须能覆盖这段额外数据。计算方法是FIFO深度 反压信号传播延迟内的数据量 一帧最大长度。在实际项目中我会把中间节点的FIFO深度按两层估算——理论值的1.5倍再加32个深度冗余宁多勿少。FIFO溢出导致的数据丢失是很难排查的因为表象往往是偶发的校验错误而非稳定的功能失效。// 中间节点数据转发与反压示意简化代码 always (posedge clk) begin if (fifo_empty) begin tx_valid 1b0; end else begin // fifo非空且下游可接收则弹出一拍数据 tx_data fifo_rd_data; tx_valid 1b1; end end // 向上游输出的反压信号本地FIFO将满时置有效 assign nready_up ~almost_full; // 下游反压时本地FIFO继续缓存上游数据 always (posedge clk) begin if (rx_valid nready_down) begin // 正常接收并写入FIFO end else begin // 上游已停止本轮无数据 end end代码只是骨架但已经能说明关键逻辑FIFO是节点的缓冲池valid信号是数据有效标志nready反压信号以反向路径逐级传递。这三者配合好链路才算真正稳定。4. 一个三片FPGA菊花链的真实工程实现4.1 需求背景与节点分工用一个实际做过的项目来说明一个带宽需求较高的数据采集系统需要三片FPGA配合工作。按规划第一片接若干路高速ADC做数据采集和最简单的奇偶校验第二片做数字滤波和格式变换第三片把处理完的数据打包转为对外通信协议上传。这个分工天然适合菊花链数据流向是单向的从采集→处理→上传中间不需要逆向传输大数据每级只和相邻级有物理连接。链路形态我选择了并行LVDS。原因是节点只有3个带宽需求大约在800Mbps上下并行LVDS完全可以覆盖而且调试工具链成熟出了问题更容易定位。每条链路的信号组包括16bit数据线、1对源同步时钟、1根valid信号、1根nready反压信号。源同步时钟工作在300MHz的单边沿模式理论带宽是16bit×300MHz 4.8Gbps实际流速控制在1Gbps以内给信号完整性和逻辑处理留下充足余量。4.2 中间节点既要转发也要消费这个项目里第二片FPGA是中间节点的典型代表它既要消费第一片传来的原始采集数据做滤波处理又要让处理后的数据继续流向第三片。这里有一个非常容易搞错的设计点中间节点的接收逻辑和发送逻辑不能共享同一组FIFO。接收侧FIFO缓存的是上游原始数据滤波模块按自己的节奏从里面取数处理完成后结果写入发送侧FIFO由发送逻辑向下游转发。两侧FIFO互相独立这样才能解耦上游发送节奏和下游接收节奏。如果接收和发送共用一套FIFO流速不匹配时上游快、下游慢处理模块就会被迫等待读取整个系统的流水线被堵死延迟也会变得不可预测。从帧结构上看第二片接收时检查帧头读取目标节点号。如果目标是自己剥离载荷送给滤波模块如果目标不是自己比如某些通道直通数据直接进转发路径。设计这种混合帧格式时我强烈建议把原样转发和处理后再转发分成两条独立的数据通路并在顶层用简单的仲裁合并输出。两条通路混在一个状态机里会让时序分析和调试都变得很痛苦。4.3 具体配置与参数选定这个项目的实际参数如下链路数据宽度16bit源同步时钟300MHzFIFO深度128×16bit反压阈值设为FIFO写入深度超过96时拉高反压。看起来是一个很平淡的参数表但每个值背后都有计算支持。FIFO深度为什么定128因为反压从第三片传到第一片大约需要2个链路时钟周期加上第二片自身的处理延迟约5个时钟周期以及一帧最大长度约64个周期理论需求是256471个数据字冗余之后取128是合理的。反压阈值为什么是96因为阈值太高FIFO容易溢出阈值太低上游会被频繁打断吞吐下降。96的计算思路是FIFO深度128减去最大单帧长度64再减去两个时钟的保护余量得到的64只是为了安全保留96正是一个均衡点。这些参数在实际运行中验证过整条链路连续运行几十小时无一帧报错。5. 调试菊花链最容易踩的坑5.1 单板单链路能通级联以后断流这是我在菊花链项目里遇到频率最高的故障也是最折磨人的一种。现象很诡异单独测A和B之间的链路数据收发正常误码为零单独测B和C之间同样正常。但三片级联跑起来B总是在运行一段时间后停止向上游请求数据整条链的吞吐掉到接近零。排查过程花了大半天时间。先用FPGA工具链里集成的逻辑分析仪IP打上在线观测点观察B片接收侧的valid信号和反压信号。发现B的接收valid信号一直为高数据源源不断进来但它向C发送数据时频繁被反压。继续往C内部看发现C片的FIFO经常处于将近满的状态。问题是数据量并不大为什么C会频繁接近满最终定位到问题在C的发送逻辑——C向外部设备发送数据时采用了一种批量发送策略每次都集聚大量数据才触发一次发送导致发送节奏不均匀内部FIFO周期性逼近溢出。解决办法也简单把C的发送策略改成有数据就发送攒够一个最小包立即触发而不是等批量。调整后整条链的流量立刻平稳。这个坑的教训是菊花链的稳定性取决于最下游节点的消费节奏下游不稳定上游所有努力都会被反压信号抵消。调链路时如果只盯单一链路永远发现不了问题。5.2 误码、眼图和跨时钟域难题菊花链中误码是最难缠的问题。它不像断流那样有鲜明的故障表现而是在高负载运行一段时间后偶发丢帧或校验失败复现概率还不稳定。排查误码要分层进行。第一步用PRBS伪随机序列灌进去在接收端统计误码率确认是物理层还是逻辑层问题。如果误码率在10的负12次方量级且稳定多半是信号完整性问题如果误码偶发但复现位置固定多半是逻辑跨时钟域问题。信号完整性方面最常见的坑是LVDS走线的包地不完整。有一次我将链路的时钟和数据线从过孔区域穿过过孔旁边没有加缝合地孔结果在高温实测时误码率突然恶化。补上缝合地孔后误码率恢复为0。做菊花链PCB时每条链路的数据线、时钟线周围必须保证完整的地平面任何一点铜皮开槽都可能成为信号质量的隐患。跨时钟域问题则更隐蔽。如果相邻两片FPGA的参考时钟来自不同晶振那么A发给B的数据流时钟与B内部逻辑时钟就存在频率偏差。此时直接用同步FIFO读写必然偶发丢数据。正确做法是使用异步FIFO用格雷码保证空满标志的跨时钟域安全性。很多工程师能想到用异步FIFO但常常忽略格雷码空满判断的一个细节读时钟域的空信号和写时钟域的满信号必须各自在自己时钟域内生成不能跨域直接断言。5.3 调试工具与错误特征对照拿积累的经验做个简单对照表出现这些现象时可以快速缩小范围故障特征最可能原因建议排查手段链路完全不通复位未释放/极性接反查复位时序与差分极性偶发校验错误跨时钟域采样检查FIFO类型与格雷码高负载才丢帧下游FIFO溢出观察反压信号与FIFO水位低温/高温误码率升高信号完整性问题查走线包地、端接电阻、过孔区级联后吞吐骤降下游消费节奏不均统计各节点valid占空比6. 菊花链的性能边界与升级路径6.1 带宽和延迟的天花板菊花链的性能上限是一眼能算出来的。端到端延迟 每一级的转发延迟之和。每个中间节点至少贡献一个FIFO读写延迟加上数据对齐和协议处理通常每级在5~10个时钟周期之间。假设5个节点、每级8个周期、时钟200MHz总延迟就是5×8×(1/200MHz) 200ns。这个延迟在大多数采集和通信场景里完全可接受但对于需要严格实时闭环的控制系统可能已经超出预算。带宽上限则取决于单条链路的物理带宽和中间节点的处理能力。每条链路能够承载的最大吞吐由链路位宽和时钟决定但中间节点如果既要转发又要做业务处理它的逻辑瓶颈会直接成为整条链的瓶颈。所以设计时要先估算每个节点转发数据 本地处理的总时间开销如果处理耗时接近转发耗时就要考虑降速或拆分节点。还有个容易被忽略的边界电源。多片FPGA级联后所有芯片同时高速翻转电源瞬态响应如果跟不上会产生同步开关噪声直接影响高速链路的信号质量。菊花链项目布板时每片FPGA的核心电源至少要预留充足的去耦电容不能指望单一集中供电打天下。6.2 当菊花链撑不住时怎么办当节点数超过8个或者任意节点间通信变得频繁时菊花链的延迟和转发负担就会逼近临界点。这时候不必推翻重来可以分两步走。第一步是改造链路形态把中间节点的透传模式改为带旁路通道的处理模式或者把部分低速控制信息从数据链路中剥离单独建立一条专用管理链路减少数据链路被控制帧打断的概率。这个做法在工程里见效最快改动量也最小。第二步是改变拓扑如果仍然不够就把整条链拆成两段两个头节点之间用高速串行链路互联形成一种两段式菊花链结构。这种混合拓扑保留了菊花链引脚少的优势又把最长的端到端路径缩短了一半。我在一个8片级联的项目里就做过类似处理原本一条链从第1片穿到第8片端到端延迟逼近500ns已经影响业务。后来拆成两条4片链中间用一对高速串行线做桥接延迟降到了280ns而改动只涉及头尾两个节点其余6片逻辑完全没动。这个经验说明菊花链设计一定要预留升级空间——物理层布线时留出额外的GT差分对和配置引脚逻辑层设计时保持节点接口标准化后面改拓扑才不至于伤筋动骨。做完这个改造我对菊花链的理解又深了一层它不是所有互联问题的唯一解但在绝大多数中低节点数、强流水特性的场景里它是最省资源、最容易调试、也最容易维护的方案。关键是在设计之初就想清楚每个节点在链路上的职责边界把同步、流控、帧格式这些底层机制做扎实后续所有业务逻辑才有稳固的立足点。如果你正准备做多片FPGA级联建议从上面这些链路参数和帧结构开始搭骨架再逐步填充业务细节会少走不少弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑