ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

跨代FPGA高速互连:单向黑盒LVDS链路设计与时序实践

跨代FPGA高速互连:单向黑盒LVDS链路设计与时序实践 1. 项目背景跨代FPGA互连为什么绕不开LVDS做过几年板级设计的人大概都有类似经历手头一个运行了好多年的老平台可能是Spartan-6、Cyclone III那个年代的东西某天突然要接一块新板子而新板子上是一颗Artix-7、Cyclone 10甚至更新的器件。两边工艺差了好几代供电、IO标准、时钟资源都不一样偏偏业务上还要求它们之间把一批数据稳稳地传过去。跨代FPGA高速互连这个题目说的就是这种场景。而单向黑盒LVDS链路是这类场景里我最常选的一种落地形态——一端只负责发另一端只负责收接收方完全把发送方当成一个黑盒不关心对面是哪个厂商、哪一代工艺只认接口上约定的电平和时序。这套方案能解决的核心问题很具体当两侧器件差异大、又不想引入复杂的握手协议时用低压差分信号LVDS做物理层用单方向的数据流做逻辑层把耦合面压到最小。它适合三类人参考一是手上真有跨代平台要对接的硬件工程师二是需要设计板间、板内高速数据链路的FPGA开发者三是想搞清楚LVDS链路到底怎么算时序余量、怎么预估风险的技术负责人。本文不堆概念重点讲我在实际项目里怎么选型、怎么推参数、怎么排坑。2. 架构选型为什么是单向、为什么是黑盒、为什么是LVDS2.1 单向链路是一种主动的架构收敛很多人一上来就想做双向觉得双向通用、扩展性好。我个人的经验是只要业务场景允许能单向就单向。原因很实在双向意味着两个方向都要做时钟域处理、都要做流控、都要处理对方掉线的情况验证工作量差不多翻倍。而单向链路里发送端永远只管把数据推出去接收端永远只管按节拍采双方的职责边界清清楚楚。代价当然也有——发送端不知道接收端忙不忙可能出现溢出。解决办法通常有两个要么在数据流里嵌一个简单的帧头帧尾接收端丢帧了也不回头找要么预留一条低速的反向线做背压back-pressure。后者严格说已经不纯单向但它速率低、时序松对主体链路没有任何影响属于工程上的折中。我在几个项目里都用的第二种反向线就走一根普通LVCMOS速率几百kbps纯粹用来告诉对面先歇会儿。单向还有个隐性好处调试方向明确。链路不通的时候你只需要顺着发送端往接收端一路查过去不用在两个方向上反复跳。这在跨代器件这种本来变量就多的场景里能把排查复杂度砍掉一大块。2.2 黑盒思维带来的是解耦不是偷懒黑盒这个词容易被误解成我不管对面。实际恰恰相反黑盒意味着接口契约必须先定死。发送端和接收端要约定的东西包括数据位宽、帧结构、随路时钟还是嵌入时钟、上电后的对齐序列、无效数据的填充方式。这些定完之后两侧可以独立开发、独立验证甚至用两块不同厂商的开发板分别跑通最后再合起来联调。我特别看重的一点是黑盒接口让跨代这件事变得可控。老器件那边可能连基本的SelectIO原语都和新的不一样但你只要保证它在接口上吐出来的电平、时序符合约定新一代器件完全不需要知道对面是Spartan还是Cyclone。反过来也一样。这种解耦在器件停产、备件替换的时候价值巨大你换掉一侧另一侧几乎不用动。当然黑盒也有风险契约如果定得不严谨比如没约定好上电顺序、没约定好空载时的电平状态联调阶段就会各种诡异现象。所以我的做法是把接口契约写成一份简短文档双方各留一份写清楚每个信号的默认状态、有效电平、时序窗口。这不是形式主义是省时间。2.3 LVDS是物理层里性价比最高的那档物理层可选项其实不多LVCMOS、LVDS、还有带CDR的收发器GT/GTP/GTX那一类。三种我都用过简单说说取舍。LVCMOS最简单单端、走线多、速率上不去。做并行数据总线的时候比如8位数据加1位时钟9根线速率一到一两百兆就开始有信号完整性问题串扰、地弹、边沿变缓。板间走线长一点就更明显。所以LVCMOS我只在低速、短距离、器件资源极度受限时用。带CDR的收发器性能最强一个通道就能跑到几个Gbps自带时钟恢复、均衡。但它有前提器件得支持而且收发器资源通常稀缺。更关键的是跨代场景里老器件那侧往往压根没有高速收发器你总不能为了对接把老平台全换掉。所以收发器方案一般只在新新对接时优先考虑。LVDS夹在中间正好是那个甜点。它的电气本质是电流驱动差分驱动器输出约3.5mA恒定电流流过接收端100Ω终端电阻产生约350mV的差分摆幅。差分结构天生抗共模干扰边沿也快单对线跑到几百Mbps没压力。更妙的是绝大多数FPGA的普通IO都能配置成LVDS不需要专用收发器跨代兼容性极好。举个具体对比方便你代入理解方案单通道典型速率抗干扰跨代兼容性资源占用我的使用场景LVCMOS几十~200Mbps弱好极低短距低速控制线LVDS200Mbps~1Gbps强好低跨代数据主干高速收发器1Gbps~数十Gbps很强差老器件常无高专用资源新新对接、超高速选LVDS还有一个现实原因线缆和连接器成熟。一对差分线就是两根线一个连接器上塞几对甚至十几对很轻松成本比高速连接器低一个量级装配工人也熟悉。3. 链路参数推演速率、位宽与时钟到底怎么定3.1 从业务需求反推链路速率参数不是拍脑袋定的从数据量倒推最靠谱。假设业务上每秒要传200MB的有效数据也就是1.6Gbps。如果你用LVDS做串行化传输一个时钟周期送8位数据8:1串行化即DDR下每对线每周期8bit那么链路时钟至少需要1.6Gbps ÷ 8 200MHz。这个200MHz不是随便能达成的得回去看接收端FPGA的ISERDES能不能在这个速率下稳定工作。我一般的做法是先查两端器件的SelectIO手册找到各自LVDS接收能稳定工作的最高速率取两者中较低的那个作为上限然后再留20%到30%的裕量。比如老器件手册标600Mbps新器件标1.25Gbps那实际链路速率我大概会定在450Mbps到480Mbps这个区间而不是硬撑到600。这条20%~30%的裕量不是保守是给温度漂移、电压波动、线缆批次差异留的空间。我吃过一次亏早期项目顶着手册上限跑常温下误码率测试很好一到机箱里温度上到60度就开始零星误码最后只能降速率或者改时钟方案。前期的裕量比后期的返工便宜太多。3.2 时序余量的手算过程时序预算这件事说的是从发送端把数据推出IO到接收端IO把数据采进来整个路径上的时间开销。核心公式很简单数据到达接收端的时间 建立时间余量 ≤ 采样时钟边沿到来时间 采样时钟边沿到来时间 保持时间余量 ≥ 数据到达接收端的时间 数据保持时长具体到LVDS源同步链路路径延迟包含这几块发送端IO输出延迟Tco、PCB走线延迟大约6ps/mm到7ps/mm视板材而定、连接器延迟、接收端输入延迟、接收端内部可编程延迟IDELAY能补偿的范围。我举个数发送端Tco约1.5nsPCB走线假设100mm单端延迟按6.5ps/mm算是0.65ns两条线如果等长做得差2mm就是13ps的偏斜先忽略。连接器约0.1ns。接收端输入到ISERDES约1ns含内部布线。那么数据到达时间大概1.50.650.113.25ns。时钟如果也是源同步走的路径类似但它作为采样基准。关键在接收端很多FPGA的ISERDES都带IDELAY可以按tap微调采样点每个tap约几十ps。所以设计的时候我会先算出一个大致的相位差再用IDELAY把它对到数据眼图的中心。这就是为什么LVDS接收端一定要留IDELAY能力否则时序一旦因为板材批次或温度漂移就跑偏你只能干瞪眼。下面是我在项目里常用的一张时序预算简表可以直接照着填项目典型值备注发送端Tco1.0~2.0ns查器件手册PCB走线100mm0.65ns6.5ps/mm连接器与焊点0.1~0.3ns视连接器接收端输入延迟0.5~1.5ns查IBIS或手册眼图张开度要求≥0.3UI经验值IDELAY补偿范围±0.3~1.0ns视器件tap数3.3 时钟方案源同步比系统同步更值得选跨代链路里时钟怎么传是个容易吵起来的问题。系统同步是两个器件各用各自的时钟靠时钟同源来保证采样正确问题是两个器件的时钟树延迟不一样跨代器件差异更大相位关系很难保证。源同步是发送端把时钟和数据一起发出去接收端用随路时钟去采时钟和数据经历了相同的路径共模的延迟被抵消掉了。跨代场景我几乎无脑选源同步。原因就是前面说的两个器件差异太大系统同步的时钟相位对齐很难做尤其老器件的全局时钟树和新器件不是一个设计思路。源同步虽然多占一对差分线专门走时钟但换来的是相位关系的确定性和抗环境变化的鲁棒性值。不过源同步也有讲究。数据和时钟是并行走的PCB上必须严格等长否则偏斜会直接吃掉眼图。我一般要求同一组LVDS对内的数据和时钟等长误差控制在±1mm以内跨对之间可以放宽到±3mm。这个约束在设计初期就要跟PCB工程师讲清楚等线都布完了再改代价很大。4. 逻辑落地收发两侧的实现要点4.1 发送端串行化与输出发送端要做的事情是把并行数据串成LVDS能承载的位流。Xilinx和Intel都有各自的串行化原语Xilinx侧是OSERDESIntel侧是SERDES。以OSERDES为例可以配置成DDR模式下4:1或8:1把低位宽的并行数据在时钟驱动下串出去。我给个简化的思路伪代码形式帮你理清逻辑// 发送端并行数据 - 串行 // 假设 8:1 串行化DDR 输出 always (posedge clk_fast) begin data_shift {data_shift[6:0], data_in_bit}; end // OSERDES 原语负责把 8bit 按 DDR 时序输出到差分对实际用的时候不要自己手写移位器去拼LVDS输出那样时序很难收敛。正确姿势是调用厂商原语让工具去处理IO上的时序关系。原语的配置参数要重点关注这几点数据位宽决定了串行化比例、是否DDR、输出标准是否设成LVDS、以及是否使能内部终端。发送端还有个容易忽略的细节上电初始状态。链路刚上电的时候数据是乱的接收端如果直接采会收到垃圾。我的习惯是在发送端加一段固定模式的对齐序列比如0xAA55或者PRBS持续几微秒到几十微秒等接收端锁定之后再切换到真实数据。这个小设计能让联调时的现象干净很多。4.2 接收端对齐、过采样与字边界接收端的活儿比发送端复杂。它要从随路时钟里把数据正确采下来还要知道字节边界在哪。这里我常用两种手段配合。第一是IDELAY。接收到的数据和时钟相位不确定用IDELAY逐tap扫找到眼图最开的那个采样点。很多工程做法是上电后跑一段自动扫描delay calibration把最佳tap值存下来。这个过程我做过的项目里基本都做成自动的因为手动调一次换块板子就失效。第二是字对齐。串行进来的位流你只知道哪一位是哪一位但不知道一个字节从哪开始。通常发送端会发一个独特的对齐字接收端用一个状态机去搜索这个模式找到之后就把后续数据按位宽切分成字节。这个搜索逻辑要写得足够鲁棒允许有一定的位错误不能因为一次误码就丢掉对齐状态。接收端还有个资源问题如果链路速率较高单个ISERDES可能到不了就要用多个ISERDES做过采样或者DDR双沿来分担。过采样就是用更高的采样时钟去采数据比如数据200Mbps你用400MHz去采采两次取中间那次。代价是内部逻辑时钟变高功耗和时序压力都上去了。所以我一般优先用源同步DDR的方式把采样时钟压到和数据同频甚至更低。4.3 约束文件怎么写才不翻车逻辑能跑起来不算完约束写对才算完。LVDS链路的约束核心是两条时钟约束和IO延迟约束。时钟约束要告诉工具随路时钟是干什么用的。假设时钟100MHz# Xilinx XDC 示例 create_clock -name rx_clk -period 10.000 [get_ports rx_clk_p]IO延迟约束是重点也是很多人漏掉的地方。你要告诉工具发送端数据相对时钟的偏移以及板级走线的延迟# 发送端输出延迟含 PCB 走线 set_output_delay -clock tx_clk -max 1.2 [get_ports data_out*] set_output_delay -clock tx_clk -min 0.3 [get_ports data_out*] # 接收端输入延迟 set_input_delay -clock rx_clk -max 1.5 [get_ports data_in*] set_input_delay -clock rx_clk -min 0.6 [get_ports data_in*]这些数值不是随便填的要结合第3节算出来的时序预算。填得不准工具要么收敛不了要么收敛了但实际板子跑不通。我见过不少项目时序报告一片绿上板就是误码八成是IO约束和实际板级延迟对不上。提示跨代器件两侧的时序模型差异大建议分别建立两套约束用真实的板级延迟数据可以从PCB工具导出去填不要用默认值或拍脑袋值。5. 硬件落地PCB与连接器的关键细节5.1 差分走线与阻抗控制LVDS的电气设计核心是100Ω差分阻抗。这个阻抗主要由PCB叠层和线宽线距决定做板之前一定要让PCB厂给一份阻抗计算单确认差分阻抗落在100Ω±10%以内。我见过有的板子因为叠层改了没重算实测差分阻抗跑到120Ω眼图明显变差误码率上去了。差分对内两根线要严格等长误差控制在几mil以内。等长不只是长度相等还要走线方式对称尽量并排走不要一根绕来绕去另一根笔直。绕等长的时候用蛇形线但蛇形段的间距不要太小否则会引入额外的耦合。对内间隔一般保持3倍线宽以上对间间隔更宽减少串扰。参考平面很重要。差分线要有一整块完整的地平面做参考中间不要被电源分割区切断。如果一条差分对跨过了参考平面的缝隙回流路径被迫绕远阻抗突变信号质量急剧下降。这个坑我在一个多层板项目里踩过原因是电源层分割的时候没考虑差分线的位置后来重新铺了一层地才解决。5.2 终端匹配与共模处理LVDS接收端需要100Ω终端电阻位置越靠近接收器越好。有些FPGA内部集成了可选的差分终端用内部终端能省掉外部电阻但要注意内部终端的精度和一致性通常不如外部电阻。速率不高的时候用内部终端很方便速率上去了我倾向用外部精密电阻。共模电压也要关注。LVDS标准共模约1.2V接收器能接受的共模范围大概在0.2V到2.2V之间。如果收发两端地电位差太大共模就会漂出这个范围接收器就采不准了。跨代链路如果两端供电不共地或者线缆较长建议加共模扼流圈或者用带隔离的方案。我在一个长线缆项目里加过共模电感效果立竿见影误码率从偶发降到基本没有。还有一点是失效保护。链路断开的时候接收端输入是悬空的如果没有偏置输出会振荡。加一对弱上拉下拉电阻把差分输入偏到一个确定状态就能避免这个问题。这个细节很多参考设计里不写但实际产品上很有用。5.3 线缆与连接器选型板间连接优先选带屏蔽的差分连接器配对使用的差分对尽量在连接器里也挨着保证阻抗连续。普通排针排母只要间距够、能配到差分对低速也能用但速率一高就不行因为阻抗不可控、串扰大。线缆如果比较长超过半米要选特性阻抗100Ω的差分线缆别拿普通杜邦线凑合。我见过用杜邦线跑几百Mbps跑了两周没问题的也见过同样线材在另一块板上一跑就挂的本质是没控制阻抗和长度靠运气。产品上不能靠运气。6. 风险预估跨代链路最容易翻车的地方6.1 电平和供电兼容风险跨代最大的风险就是电平标准不兼容。老器件可能只支持LVDS_25需要2.5V VCCO新器件支持LVDS但供电可以是1.8V。如果你的bank供电设错IO要么不工作要么长期工作在超规格状态下早衰。这个必须在选型阶段就查清楚把两端的VCCO、VREF、IO标准列成一张对照表逐个确认。我列一个典型的检查清单检查项老器件侧新器件侧是否一致IO标准LVDS_25LVDS需确认Bank供电VCCO2.5V1.8V/2.5V关键终端电阻外部100Ω内部可配需统一输入共模范围0.2~2.2V0.3~2.0V取交集最大速率600Mbps1.25Gbps取较低值这张表填完基本能看出链路能不能成。如果某一行不通过别硬上要么换bank、要么加电平转换、要么降速率早发现早处理。6.2 误码、抖动与温漂链路跑起来之后最常见的问题是误码。误码来源大致分三类信号完整性差、时序余量不足、外部干扰。排查顺序我一般是从物理层查起先看眼图再看时序最后看逻辑。抖动是另一个隐形杀手。发送端时钟的抖动、电源纹波引起的抖动、温度变化引起的延迟漂移都会吃掉时序余量。我做产品的时候会做温度循环测试从低温到高温跑一遍误码率如果误码率随温度明显上升说明时序余量本来就不够得回去压缩或者改用更稳的时钟方案。有个经验数字常温下测得的眼图张开度我一般要求至少达到0.4个UI这样温度漂移和电压波动吃掉一部分之后还有余量。如果常温下就只有0.25UI那基本可以预判高温会出问题。6.3 常见问题速查表下面这张表是我这些年攒下来的遇到问题可以直接对号入座现象可能原因排查动作完全无数据时钟没过来/供电错示波器测随路时钟、查VCCO数据错位字对齐失败检查对齐序列、状态机偶发误码时序余量不足扫IDELAY找最佳采样点误码随温度上升温漂吃掉余量重新算时序、降速率某块板好某块板坏阻抗/等长波动复测差分阻抗、查等长上电偶发挂死初始状态未定义加对齐序列、加失效保护长时间运行后误码电源纹波/散热测电源纹波、查温升7. 调试实战里的几个碎经验最后分享几个我在实际调试里总结的、文档里不太会写的东西。第一先跑通再优化别一上来就堆复杂度。我最早做跨代链路的时候想一步到位把8b/10b编码、CRC校验、自动重传全加上结果调了两周连基本数据都没通。后来退回到最简单的固定模式单对线先用示波器确认眼图和时钟都没问题再一层层往上加逻辑。这个从最小可运行系统开始的思路帮我省了无数次返工。第二示波器是你的眼睛别省这个步骤。逻辑上分析不出来的问题八成在物理层。我习惯在项目初期就把差分探头挂上去测眼图、测共模、测抖动。有时一个眼图就能告诉你问题出在哪比查一下午代码快得多。第三文档里的典型值和你的板子往往不一样。器件手册给的Tco是典型值你的板子实际是多少得测。我现在的习惯是首批板子做出来后用示波器实测一次关键路径延迟把这组实测值回填到约束里第二次改板就会准很多。第四跨代对接项目越早把两端放到一张桌子上联调越好。我见过太多项目两侧各自开发各自验证都好好的合起来就是不通因为大家的接口契约理解不一致。哪怕只是拿两块开发板加一根飞线也比各自闭门造车强。这套单向黑盒LVDS链路的方案我在三四个不同代际的平台之间用过改动量最小的一次接收端逻辑几乎没动只是把IDELAY的初始扫描范围调了一下就通了。它不炫技但稳、便宜、可维护在跨代互连这个具体场景里我觉得很难找到比它更合适的组合。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进