ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FPGA LVDS高速通信数据测试:PRBS误码率实测与工程实践

FPGA LVDS高速通信数据测试:PRBS误码率实测与工程实践 LVDS 系统前几篇把理论、板卡和逻辑链路都交代完了代码也算给到大家了但有个问题一直悬着这套东西跑起来到底稳不稳误码率是多少长时间运行会不会翻车这篇就是把这个问题当面锣对面鼓地讲清楚。数据测试这关是高速串行通信项目里最刺激也最容易翻车的地方。我经常跟团队里的小朋友说逻辑功能没调通顶多是干活慢一点数据测试没做透那就是埋雷什么时候爆全看运气。这篇内容围绕 Xilinx FPGA 的 LVDS 高速串行通信系统展开重点分享我用 PRBS 伪随机码做链路测试的完整方案、核心 Verilog 逻辑、实测数据和一堆排查经验。搞过 FPGA 高速接口、被误码折磨过的朋友这篇值得你花十分钟细看源码我放在文末直接拿走就能用。1. 数据测试为什么值得单独开一篇1.1 测试在高速链路开发中的真实位置很多初学 FPGA 的朋友对数据测试有个误解觉得功能仿真过了、板上灯亮了这事就算成了。放在低速设计里这么想没问题但在 LVDS 高速串行链路上这想法会害死人。信号一旦跑到几百 Mbps 甚至 Gbps 级别PCB 板材损耗、过孔阻抗不连续、连接器接触电阻、线缆长线反射、电源纹波、地弹噪声这些以前可以忽略的因素全部变成实打实的信号完整性问题。你可以把 LVDS 链路想象成一根水管低速灌水时管子里有点杂质无所谓但水流一大、压力一高杂质就会卡在弯头处轻则水流变小重则直接堵死。功能仿真只能验证逻辑对不对验证不了物理层能不能在真实环境下把这个“水”稳定送过去。所以我做高速项目一定会把数据测试当成一个独立阶段来规划逻辑设计一开始就预留测试接口板卡回来第一天做冒烟测试跑不过就直接打回改版。1.2 数据测试到底要测出什么东西测试不是简单看“通不通”按我的习惯一个完整的 LVDS 数据测试要回答四个问题链路能不能通、误码到底有多少、瓶颈卡在哪一段、系统长期跑靠不靠谱。链路连通性是最基本的上电后收发两端能不能建立起正确的数据通路同步头能不能抓到。但这只是起点真正的重头戏是量化误码率BER。误码率是衡量高速链路可靠性的核心指标一般通信产品的误码率要求做到 10^-12 甚至更低也就是说传输一万亿比特最多只能错一个。接下来是定位瓶颈。同样一套系统短距离走线误码为零一旦接上长线缆就开始出误码那问题大概率在线缆或连接器上。如果短距离都不行就要回头查 PCB 布线和芯片配置。这种分层排查的思路比一上来就乱试要高效得多。最后是长期可靠性。很多链路刚上电时工作正常跑半小时后温度上来就开始出误码。这类问题不经过长跑测试根本发现不了所以我通常会让系统连续跑 24 小时以上任何突发误码都不放过。1.3 测试维度和测试矩阵我习惯在做测试之前先列一个测试矩阵把需要验证的维度都铺开。第一个维度是速率。同一个系统在不同速率下的表现差异巨大。以我常用的 7 系列 FPGA 为例LVDS 在 HP Bank 和 HR Bank 上支持的最高速率完全不同而且不同速度等级芯片的时序裕量也不一样。我的做法是从最低速率开始逐步往上爬每爬一档都做一次完整测试直到找到系统能稳定工作的速率上限。第二个维度是电压和温度。LVDS 驱动器输出摆幅通常可以通过寄存器调整摆幅太大容易辐射超标摆幅太小又导致接收端采样裕量不足。温度的影响更隐蔽芯片内部温度从 25 度升到 85 度驱动器的输出阻抗、压摆率都会变化链路时序裕量被压缩误码率随之上升。有条件的话一定要上温箱做温度循环这比单纯测常温可靠得多。第三个维度是码型。不同数据码型对链路的应力完全不同固定数据测不出真实水平后面详细说。把这些维度组合起来就是一个完整的测试矩阵。测试报告按矩阵逐项填写每个参数配置下的误码结果一目了然。2. 测试方案设计回环、点对点与码型选择2.1 三种测试结构的适用场景LVDS 数据测试按物理连接方式分常见的有三种FPGA 内部回环、板级外部回环、双板点对点互连。三种结构各有各的用途测试目的不同选型逻辑也不同。FPGA 内部回环是最省事的测试方式。在 FPGA 内部直接把发送模块的输出和接收模块的输入短接不经过任何物理引脚。这种方式主要用于验证逻辑功能和时序收敛情况排除物理层干扰后先把逻辑层面的问题清干净。它的局限也很明显完全绕过了真实链路对信号完整性问题一无所知。板级外部回环是第二个层次。把 FPGA 发送引脚输出的差分对在 PCB 外部用短跳线或者线缆短接回接收引脚。数据经过了真实的物理通道包括引脚封装、PCB 走线、连接器链路质量开始被真实检验。具体回环点在板卡设计时就要预留我一般会放一到两组回环测试点方便板卡回来后做验证。双板点对点最接近实际应用场景。两块 FPGA 板卡通过 LVDS 接口互连一头发送一头发收模拟真实产品的工作状态。这个测试能覆盖到两套系统之间的地电位差、共模电压漂移、长距离传输等实际问题是量产前必须做的测试。实际项目里我通常是三阶段测试都做先用内部回环把逻辑调通再做板上回环确认电气链路无问题最后双板对接做长时间误码率验证。建一个表格对比会更直观测试结构覆盖范围优点局限适用阶段FPGA 内部回环逻辑功能搭建快、无物理干扰不覆盖物理层功能调试初期板级外部回环PCB 走线、连接器验证信号完整性链路长度有限板卡验证阶段双板点对点完整链路最贴近真实场景需要两套系统产品化验证阶段2.2 测试码型为什么工程师都在用 PRBS测试码型的选择直接影响测试结果的可信度。用全 0 或全 1 作为测试码型链路永远测不出问题因为这种数据没有任何跳变沿接收端采样时钟稍微漂移也察觉不到。真实业务数据是随机变化的链路能不能扛住随机数据的压力才是关键。因此工程师普遍使用 PRBS伪随机二进制序列作为测试码型。PRBS 由线性反馈移位寄存器LFSR生成序列看起来是随机的但本质上是确定性的周期序列。这意味着接收端可以用同样的生成多项式复现出理想序列再和实际接收到的数据逐比特比对任何一位不一致都能被精确捕捉。不同阶数的 PRBS 对链路的应力不同我用得最多的是 PRBS7、PRBS15 和 PRBS23。PRBS7 的序列长度只有 127 比特短序列翻转密度大主要用来测设备的基本连通性。PRBS15 的序列长度是 32767 比特包含更长的连续相同比特能考察链路的低频特性和直流平衡能力。PRBS23 的序列长度超过 838 万比特最长连 0/1 达到 23 位用来模拟最严苛的真实数据场景。做高速链路压力测试我建议至少跑 PRBS15 以上。只跑 PRBS7 往往会出现一种假象短码型测下来误码为零换成真实业务数据立刻出问题。原因就在于业务数据里不可避免会出现长连续相同比特链路对低频分量的响应能力在这种状态下被真正考验。2.3 测试系统的整体构架一个完整的 LVDS 数据测试系统逻辑上包括四个模块发送端码型发生器、接收端同步与数据恢复、误码比对统计、控制与状态上报。发送端负责产生确定性 PRBS 数据流并以固定帧格式封装帧头用特殊字比如 K 码或者固定同步字标识。接收端上电后先在数据流里搜索帧头完成字对齐和帧对齐锁定后启动本地 PRBS 发生器与接收数据同步运行并逐比特比对。比对结果送入误码计数器超过预定阈值就产生告警信号。控制与状态上报模块负责配置测试参数速率、码型、幅度并把统计结果通过 UART 或 JTAG 上报到上位机。这里有一个关键设计点收发两端的 PRBS 种子必须一致。最稳妥的做法是发送端上电后在固定位置先发一段同步头接收端检测到同步头后复位本地 LFSR从同一个种子开始产生 PRBS 序列。还有一种做法是通过控制通道下发种子参数但工程上我更喜欢前者逻辑简单不依赖额外通道。3. 数据测试核心逻辑实现3.1 发送端基于 LFSR 的 PRBS 生成器PRBS 生成器的核心就是一个 LFSR。以 PRBS7 为例生成多项式是 x^7 x^6 1对应 7 位寄存器反馈抽头在第 7 位和第 6 位。具体 Verilog 实现如下module prbs7_gen ( input wire clk, input wire rst_n, input wire en, output reg [6:0] lfsr, output wire prbs_out ); wire feedback lfsr[6] ^ lfsr[5]; // x^7 x^6 1 always (posedge clk or negedge rst_n) begin if (!rst_n) lfsr 7b1010101; // 种子不能全0 else if (en) lfsr {lfsr[5:0], feedback}; end assign prbs_out lfsr[6]; endmodule这段代码有两个容易踩的坑。第一个是种子不能全 0LFSR 全 0 时会陷入死锁状态永远输出 0。初始化种子只要不是全 0 就行我用 1010101 纯粹是习惯。第二个是抽头位置要对应生成多项式。PRBS7 的标准多项式是 x^7 x^6 1反馈 第 7 级异或第 6 级输出取第 7 级。这个对应关系错了序列就不对了接收端和发送端永远配不上。实际项目里很少直接串行输出单比特 PRBS因为 LVDS 链路通常是以并行数据总线方式工作的。比如我的参考设计里FPGA 内部逻辑工作在 125MHz 时钟域LVDS 物理层通过 OSERDES 实现 1:7 串化最终线上速率是 875Mbps。这种情况下 PRBS 生成器也要改成并行结构一次产生 7 比特数据送入 OSERDES。并行化 PRBS 生成器的实现方式有两种一种是把 LFSR 移位的时钟改为并行时钟每次跳 7 个状态推导出并行反馈逻辑另一种是用 ROM 查表预先存储 PRBS 序列再按并行地址读取。小规模序列我用第一种逻辑简洁且不占存储资源。3.2 接收端位对齐与数据同步接收端的工作比发送端复杂不少。LVDS 接收引脚进来的串行数据先经过 IBUFDS 转成单端信号再送入 ISERDES 解串成并行数据。但这里有个前提ISERDES 的采样时钟和数据之间必须满足建立保持时间要求。对于源同步 LVDS 接口随路时钟由发送端提供数据与时钟的相位关系是确定的但经过 PCB 走线长度的差异、芯片内部延时的差异之后相位关系会发生变化。最常用的解决办法是利用 FPGA 的 IDELAY 原语对输入数据进行精细延时调整或者使用 BUFIO BUFR 对时钟进行相位控制。还有一种做法是利用 ISERDES 的 BITSLIP 功能做位对齐。ISERDES 解串输出的并行数据存在一个“从哪一位开始”的问题如果收发端的比特序不对齐并行数据就会出现移位错乱。BITSLIP 通过在输出数据上加一个滑动窗口来实现位序调整配合训练序列就能找到正确的对齐位置。帧同步比位同步更高一个层次。发送端在帧头插入固定同步字比如 0x7E接收端检测到同步字后锁定帧边界。这里要处理一个误同步的问题数据内容里也可能出现同步字模式造成虚同步。工程上常用的做法是连续检测到 N 个帧头才确认同步一旦失步立即重新同步。我在项目里一般做“两连确认”加“连续误帧失步”的机制既快又稳。比较完整的接收端数据同步流程是这样的先由硬件完成位同步ISERDES 输出稳定的并行数据然后在并行数据流里搜索同步字搜索过程中使用 BITSLIP 尝试不同的位偏移连续两次在预期位置抓到同步字后进入同步状态正常接收期间每帧校验同步字连续出错三次判定失步重新回到搜索状态。// 帧同步状态机示意 localparam IDLE 3d0; localparam SEARCH 3d1; localparam SYNCED 3d2; localparam RESYNC 3d3; reg [2:0] state; reg [1:0] sync_cnt; reg [1:0] error_cnt; always (posedge clk) begin if (!rst_n) begin state IDLE; end else begin case (state) IDLE: begin if (sync_word_detected) state SYNCED; else state SEARCH; end SEARCH: begin if (sync_word_detected) begin sync_cnt sync_cnt 1b1; if (sync_cnt 2d1) state SYNCED; end else begin sync_cnt 2d0; end end SYNCED: begin if (sync_word_error) begin error_cnt error_cnt 1b1; if (error_cnt 2d2) state SEARCH; end else begin error_cnt 2d0; end end endcase end end这类代码是初学者最容易写飘的因为状态转移条件一多就容易漏分支。我的经验是先把状态图画清楚再写代码一个状态对应一个分支宁多勿漏。3.3 误码统计与长时间跑测机制链路同步建立后接收端本地 PRBS 发生器以相同种子开始运行与接收数据逐比特比对任何不一致都记入误码计数。误码统计逻辑要区分两个概念误码数和误码秒。误码数直接反映错误比特总量误码秒则统计出现误码的时间单元对于评估链路是否需要纠错重传很有意义。长时间跑测需要一个核心计数器我习惯做 64 位宽按 125MHz 时钟计算要连续跑四千多年才能溢出完全够用。统计结果通过轮询方式上报上位机每秒读一次误码计数绘图展示误码率随时间的变化曲线。跑测过程中一旦误码计数连续增长超过阈值系统自动拉高 ALARM 信号板卡上的 LED 同步点亮方便实验室现场发现问题。另外一个必须做的是数据有效标志。接收端在比特比对时要屏蔽以下时段链路未同步、同步字本身的误差、同步恢复过程。把这些时段产生的“伪误码”纳入统计会严重干扰结果。我一般用一个 valid 信号只有 valid 拉高期间才允许误码计数器累加所有伪误码在源头上就隔离掉了。4. 实测过程、结果与信号质量分析4.1 实测环境与关键参数配置我这次实测使用的平台是 Xilinx Artix-7 系列 FPGA具体型号 XC7A35TVivado 2020.1 环境系统核心时钟 125MHz。LVDS 通道配置为 7:1 串化模式ISERDES/OSERDES 工作在 DDR 模式线上速率 875Mbps。IOSTANDARD 设置为 LVDS开启差分终端电阻 DIFF_TERM。Xilinx 7 系列里 DIFF_TERM 属性能直接控制是否使能内部 100 欧姆差分终端电阻走线不长、信号完整性良好时建议开启省掉外接电阻。但如果走线较长或者经过连接器、线缆我更推荐在 PCB 上用独立差分电阻做终端阻抗匹配更精准。这次实测分两种情况对比。速率选择上我特意没有直接冲到芯片手册标称的最高速率而是选择 875Mbps 这个相对保守的值。原因很简单先确认系统在这个速率下完全稳定再逐步加压找极限比一开始就顶着上限跑要容易排查问题。多次项目经验告诉我稳定可靠的系统比压着极限性能的系统值钱得多毕竟产品交付后要面对的是全天候无人值守的工况。4.2 不同测试场景下的实测数据第一组测试是板上短距离回环。发送引脚和接收引脚之间的一对差分走线长度大约 3 厘米。测试配置为 PRBS15、875Mbps连续运行 24 小时误码统计结果为零。这个结果在意料之中这么短的链路上信号完整性问题微乎其微但我依然让系统跑满 24 小时目的是验证逻辑本身在长时间运行下不会出现死锁、计数器溢出之类的问题。第二组测试通过 20 厘米 FFC 软排线做外部回环。同样是 PRBS15、875Mbps结果开始出现零星误码。24 小时累计误码比特数大约 10 个左右换算误码率约 10^-13 量级。这个结果单独看不算差但没有达到我预期的零误码。把示波器探头点在接收端测量发现差分信号的眼图张度比短距离回环时小了很多眼高从接近 500mV 掉到 380mV 左右眼宽也从接近 1ns 缩到 800ps 以下。FFC 排线的特征阻抗一致性差是主要原因。第三组测试增加了压力速率提高到 900Mbps仍然是 PRBS15、20 厘米 FFC。误码率明显恶化24 小时累计误码接近一百比特换算 BER 约 10^-12 量级同时发现误码分布不均匀突发特点明显。这种情况下信号裕量已经接近临界任何电源纹波或温度波动都可能引发连续误码。分析原因除了线缆本身高频损耗连接器引脚处阻抗不连续和线间串扰的贡献也不可忽视。最后我在软件配置里把 LVDS 输出摆幅从默认的 350mV 提高到 450mV重新测试误码率有所下降说明链路主要受电压裕量限制。三组测试结果汇总如下测试场景速率码型运行时长误码BER板上短距回环875MbpsPRBS1524h010^-1520cm FFC 回环875MbpsPRBS1524h约10约10^-1320cm FFC 回环900MbpsPRBS1524h约100约10^-12这几组数据说明一个道理同样的逻辑设计物理通道变化之后系统余量完全不同数据测试的价值就在于把这些差异量化出来。没有测试数据做参考你根本不知道该在哪个环节投入改进资源。4.3 眼图测量与采样裕量评估很多人一听到眼图就摇头觉得需要几十万的示波器才能测。实际上针对 LVDS 这种相对低速的差分信号一台中等带宽的示波器就能看到完整眼图。关键是测试点的位置必须尽量靠近接收芯片引脚离得越远测得的结果越差反映不了真实接收裕量。把示波器探头接在接收端差分对上设置余辉模式让大量数据波形叠加显示就能看到清晰的“眼睛”。眼图张开度直接对应接收端采样的可靠程度眼高大于 200mV、眼宽大于 0.5UI 是比较安全的范围。我这里 875Mbps 时 FFC 场景眼高约 380mV、眼宽约 0.8UI虽可用但余量一般900Mbps 时眼明显缩小测试结果也证实了误码率上升。没有示波器也有土办法在代码里通过调整 IDELAY 延时值扫描接收端采样相位记录不同相位下误码率的分布。理论上最佳采样点在眼图正中间这个位置附近误码率最低。实测无误码的相位范围可以换算成眼宽这个“软件眼图”虽然精度不如示波器但足够指导工程判断。我在这套系统上做了一次 IDELAY 扫描从 0 到 31 步进遍历每步跑 10 秒统计误码。结果显示连续约 20 个步进无误码说明采样裕量充足换成 FFC 长线后无误码的步进范围缩到约 12 个。用这个数据直接指导了后续的相位初始化值设定把最佳采样点写到系统配置里上线后误码率立刻降了一个数量级。5. 常见问题排查与工程避坑5.1 误码率异常的排查顺序数据测试中遇到高误码率第一反应不应该是改代码而是按照“物理层 → 接口层 → 逻辑层”的顺序逐步排除。物理层排查先看差分信号是否正常。用示波器测发送端引脚确认有无输出、差分幅度是否达标、共模电压是否在合理范围通常 1.2V 左右。接着测接收端引脚确认信号有没有传到位。信号幅度正常但误码重点查端接电阻和阻抗匹配。信号幅度本身低查 FPGA Bank 电压、DIFF_TERM 开启状态、外部端接电阻焊接。接口层排查看 ISERDES 配置。采样沿是上升沿还是下降沿数据位序是高字节在前还是低字节在前这些参数不匹配也会造成系统性误码。接口层误码有个典型特征错误呈周期性规律而不是随机突发。通过抓取并行数据用逻辑分析仪分析帧内容能快速定位这类问题。逻辑层排查关注同步和比对逻辑。帧同步字有没有被误判收端 PRBS 种子和发端是否一致误码统计窗口是否包含了无效数据。逻辑层问题通过仿真就能复现一般不需要上板反复调。我之前就栽过一次两个模块用了不同字节序的 PRBS 实现实测一直是约 50% 误码率百思不得其解后来对着发送端和接收端的并行波形逐拍比对才发现收端比特序整体反了改一行代码就解决。5.2 布线、连接器与电源的隐性坑PCB 布线是信号完整性的根基。LVDS 差分对要求等长、等宽、间距恒定这些大家都懂但有几个细节容易被忽略。一是组间等长问题一个接口通常有多对差分线组内等长做好了组间长度差过大会导致不同通道的时延差超出对齐范围。二是差分对的参考平面必须完整换层时最好加回流地孔。三是过孔残桩对高速信号影响大能用背钻尽量背钻。连接器是另一个重灾区。LVDS 信号对连接器的一致性要求很高同样是 FFC 排线质量好的和质量差的高频损耗差出一倍。我这次测试里 FFC 场景出现误码率偏高的一个原因就是手头排线是普通 IO 排线不是专门用于差分信号的 FFC。有条件的话差分信号优先选用带有屏蔽层的高频连接器或者直接走 SMA/HDMI 这类成熟的差分接口。线缆是短距离测试里最容易低估的变量建议在实际选型阶段就把连接器和线缆的高频性能纳入考量不要等系统联调时才意识到问题。电源完整性的影响容易被低估。LVDS 驱动器的输出特性直接受供电电压影响IO Bank 电压波动 50mV 以上时输出共模和差分电压都会漂移接收端裕量被压缩。这次在 FFC 长线测试时我特意用示波器监控了 Bank 电压发现在数据翻转密集时电源平面有约 80mV 的纹波和偶发误码的出现时间高度吻合。解决办法是在靠近 Bank 的位置加大容量去耦电容并检查电源层平面分割避免高速切换电流绕远路回流。5.3 容易被忽略的三个次要因素第一个是时钟抖动。发送端锁相环输出的时钟抖动直接叠加到数据流上抖动过大会吃掉接收端的采样裕量。所以 LVDS 的参考时钟源必须干净不要用带大量纹波的 DCDC 输出直接供电给振荡器。我在项目里对 LVDS 参考时钟使用了专门的 LDO 供电效果立竿见影。第二个是芯片温度。FPGA 高速运行时内部温度可能达到 60-80 度LVDS 驱动器和接收器的电气参数会随温度漂移。常温测试误码为零但在散热条件差的机箱里跑一段时间就可能出现偶发误码。所以压力测试一定要做热循环或者至少让系统连续满载跑满 24 小时以上观察不同温度阶段的误码表现。第三个是 PCB 叠层与参考地。LVDS 差分走线正下方的地层如果被其他信号线破坏回流失真会造成严重的共模噪声。在设计阶段就要保证高速差分对下方的地平面完整尽量避免跨分割布线。这些因素单个拿出来影响可能不大但叠加在高速链路上就是压垮骆驼的最后一根稻草。我也经历过被时钟抖动问题折腾一周的窘境当时两套板子单独测试都正常一对接就出误码查了三天才发现是其中一块板子的晶振电源纹波过大导致发送端时钟抖动恶化到百皮秒级。换了一路干净的 LDO 供电后问题彻底消失。后来凡是高速接口的参考时钟我都会在原理图评审时专门标注电源要求。数据测试这部分的经验我最后再分享一点心得。测试逻辑在项目里看似是辅助代码但它承担的是“见证者”的职责是系统能不能交付的关键证据。很多工程师写测试逻辑时比较随意这是个大坑。测试逻辑一旦有问题你的结论就是错误的可能把一个有缺陷的板卡误判为合格也可能把一块完全正常的板卡冤枉成不良品。我的建议是测试逻辑按正式代码的标准来写同步帧、数据有效、统计窗口这些细节一步都不能省。代码在文末需要的直接拿去用有问题评论区交流。
返回列表