搞高速数据采集和射频收发这些年,JESD204B几乎是躲不开的话题。ADC、DAC、收发机这类正经的高速转换器,接口早就从LVDS并行总线切到JESD204B了。我见过不少团队板子画得很漂亮,却在建链同步这一关卡了几个星期:要么SYNC~信号死活拉不起来,要么SYSREF时序余量不够,链路时好时坏,甚至整批板子只有几块能稳定工作。这篇我结合自己做过的几块板子,把JESD204B的同步机制从代码组同步CGS、初始通道对齐ILAS,到SYSREF和LMFC的相位关系完整梳理一遍,重点讲FPGA侧怎么抓信号、怎么定位问题。适合正在调JESD204B接口的FPGA工程师,也适合刚入门、对SYSREF一脸懵的新手——这篇文章就是按“从基础到实战”的顺序写的。
1. 为什么JESD204B的同步机制总让人头疼
1.1 从并行总线到串行链路,同步方式彻底变了
以前用并行接口接ADC很简单:一条转换时钟,几十根并行数据线,再加上DCO和数据有效信号,用FPGA的IO逻辑按沿采样就行。数据线之间只要做等长处理,绝大多数情况下不会出什么大问题。到了JESD204B时代,接口变成了几条高速serdes lane,物理上不再有“数据时钟”这个概念。时钟信息被嵌入到高速串行比特流里,数据必须由接收端先从比特流中恢复出时钟,再完成字节对齐、多lane对齐、多芯片对齐。
这一下就把同步问题从板级搬到了逻辑和协议层。原来是PCB布线保证时序,现在要靠8B/10B编码、弹性缓冲、SYSREF这类机制来保证。很多从并行接口转过来的工程师,一上来就按老思路查眼图和信号完整性,结果CGS(代码组同步)都过不去,就是因为没有理解JESD204B是分层同步的结构。
1.2 三种“同步”别混为一谈
JESD204B里说的“同步”,其实包含三个层级的意思,很多人混淆了,导致排查问题没有方向。
第一层是字节/字符同步,对应CGS阶段。串行数据流里接收端要靠K28.5字符把每个10-bit码组切分对齐,这是最底层的同步。
第二层是多通道对齐,对应ILAS阶段。多路lane之间传输延迟不一样,必须通过初始通道对齐序列让各lane在同一时刻输出对齐后的数据,保证字序正确。
第三层是多芯片/多板同步,对应SYSREF和LMFC的相位对齐。多片ADC或DAC之间要保证采样时刻一致、数据的确定性时延一致,这时候靠SYSREF来校准各器件内部的本地多帧时钟。
这三个层级是递进关系:CGS不过,ILAS肯定没戏;ILAS不过,数据全是乱的;SYSREF没做对,单板可能正常,但多板联调就随机出问题。调试时必须按这个层次逐级确认,别一上来就盯着用户数据看。
2. 三步建链:CGS、ILAS、数据阶段的原理与观测
2.1 CGS:K28.5让接收端找到字节边界
链路一建立,发送端会持续发送K28.5字符,也就是8B/10B编码中的逗号序列。接收端在未同步情况下不断扫描进来的bit流,寻找K28.5对应的特定bit模式,一旦找到,就确认了字节边界。连续检测到规定数量的K28.5后,接收端会把SYNC~信号拉高,表示CGS完成。
在FPGA侧,这一阶段的判断点很直观。Xilinx JESD204B IP里,rx_sync_n信号如果一直为低,说明CGS还没完成。我调试时习惯用ILA抓SYNC~和rx_sync_n,同时抓lane的rxdata。如果SYNC~一直拉不起来,多半是以下情况:
- 参考时钟频率不对,导致lane rate和发送端不一致;
- 收发两端的8B/10B极性设置反了,差分极性接反;
- 发送端根本没进入CGS状态机,例如SPI配置没有生效。
有一个容易被忽略的点:CGS阶段接收端需要“连续”检测到若干K28.5才认为同步。如果线路上偶尔有误码,SYNC~会拉高了又掉下来,这种状态通常意味着信号完整性有问题,优先查眼图、查CDR失锁计数。
2.2 ILAS:多通道对齐与参数回传
CGS完成后,发送端会发出ILAS序列,通常连续4个多帧。ILAS的第一个多帧以R字符(K28.0)开头,随后是Q字符(K28.4)和一组配置参数,这些参数包括L、M、F、N、N'、S、K等关键配置。接收端解析这些参数后,就能确认两侧配置是否一致。
多通道对齐的核心机制是弹性缓冲器。每一路lane的接收端都会把解串后的数据写入各自的弹性缓冲,再用LMFC边界同步读出,这样即使不同lane到达FPGA的延迟差在半帧以内,也能把数据对齐到同一个时间点输出。ILAS阶段的作用就是把每一路弹性缓冲的写入位置校准到相同尺度上。
实际操作中,我一般会在FPGA里把lane的rxdata打出来,在ILA中触发R字符,然后逐字节检查后续参数是否和寄存器配置一致。这里有个经验:ILAS解析出乱码,九成是收发两端参数不一致,最常见的是F值不匹配。比如FPGA IP里配了F=2,AD/DA芯片里配的是F=1,两端看对方发来的数据全是错位。这种问题靠看眼图是看不出任何异常的,因为物理层是完全通的,必须看协议层。
2.3 正常工作阶段:数据必须贴着LMFC边界跑
ILAS完成后进入正常数据传输阶段。用户数据在传输层被打包成帧,每个帧和每个多帧都有严格的时间边界,这个边界由LMFC(本地多帧时钟)决定。LMFC周期计算公式如下:
LMFC周期 = (K × F × 10) / lane_rate
举个例子,某ADC配置为F=2、K=32、lane_rate=10Gbps,那么LMFC周期 = (32 × 2 × 10) / 10Gbps = 64ns。这意味着每64ns,所有lane都会对齐到一个多帧边界。
FPGA侧的用户逻辑必须严格按照LMFC边界来采样数据。如果发现数据偶尔出现一个字的错位,大概率不是用户逻辑时序问题,而是弹性缓冲的读指针没有和LMFC对齐。这时候回头看SYSREF是否有效复位了LMFC计数器,比在业务逻辑里加寄存器要有用得多。
3. SYSREF信号调试:绝大多数同步问题的根源
3.1 SYSREF到底在“对齐”什么
JESD204B定义了三个子类,Subclass 0不支持确定性时延,Subclass 1使用SYSREF信号实现确定性时延,Subclass 2用SYNC~信号实现。绝大多数高速转换器选择Subclass 1,也就是依赖SYSREF。
SYSREF的核心作用是复位各器件的LMFC计数器。每个ADC/DAC和FPGA都有自己的device clock,device clock分频后得到LMFC。即使所有器件共用同一个device clock源,由于内部分频器上电相位不确定,每个器件的LMFC也可能存在相位差。SYSREF就像一个“广播复位信号”,让所有器件在同一个上升沿把LMFC计数器清零,从此LMFC边界完全对齐。
SYSREF不是普通的数据信号,它必须满足一系列要求:
- 与device clock同源,频率等于LMFC频率或LMFC的整数分频;
- 脉宽要达芯片手册要求,很多芯片要求至少3ns;
- 相对器件时钟要有充足的建立保持时间。
我见过一个典型案例:SYSREF脉冲由外部信号发生器产生,脉宽只有2ns,芯片手册明确要求至少3ns,结果常温下还能工作,温度一高就开始偶发失步。这种问题靠示波器看SYSREF波形很难发现,必须把脉宽调大、留足裕量。
3.2 FPGA侧接收SYSREF的正确姿势
SYSREF信号通常是差分形式进入FPGA,多数情况下直接用IBUFDS原语接收,然后接到JESD204B IP的sysref输入。
这里有几个坑必须提。
第一,不要把SYSREF当作普通数据信号送到普通逻辑里打拍采样。SYSREF的建立保持时间要求很严格,普通逻辑路径延迟不可控,很容易导致亚稳态。正确做法是让SYSREF走全局时钟资源,例如用BUFG或BUFGCE处理,保证到内部寄存器时钟引脚的偏斜可控。
第二,如果JESD204B IP内部需要用自己的时钟域去捕获SYSREF,要特别注意捕获寄存器的时序。有的FPGA中SYSREF和device clock是不同bank进来的,如果不做约束,工具不一定能把路径优化好。我习惯在XDC中把SYSREF相关的时钟路径做显式约束,确保综合布局布线后建立保持时间有足够余量。
第三,SYSREF可以是单次脉冲,也可以是周期性信号。用周期性SYSREF时,频率不能太高,通常等于LMFC频率或分频后的频率。如果SYSREF频率过高,LMFC计数器还没稳定就又被复位,链路会持续重建,表面看起来就是“链路永远建不起来”。这一点在配置时钟芯片时容易忽略。
下面是在Vivado里常用的一种调试标记写法,方便把SYSREF和LMFC计数器引到ILA里观察:
(* mark_debug = "true" *) wire sysref_int; (* mark_debug = "true" *) reg [11:0] lmfc_counter; (* mark_debug = "true" *) reg rx_sync_n_ff;综合后打开综合设置里的“Set ILA”或者用Synthesis的Debug规划器插入ILA,把这三个信号都加进去。注意在布局布线后要重新检查SYSREF路径的时序报告。
3.3 用ILA实测SYSREF与LMFC的相位关系
调试SYSREF最重要的一步,是确认SYSREF上升沿到来后,LMFC计数器是否按预期清零。理想情况下,SYSREF上升沿到LMFC计数器清零之间的延迟应该固定,且小于一个device clock周期。
我的操作方法是:在ILA里同时抓SYSREF、LMFC计数器、rx_sync_n,触发条件设为SYSREF上升沿。然后观察SYSREF到LMFC计数器复位之间的拍数。如果这个拍数不稳定,说明SYSREF的建立保持时间余量不足;如果LMFC计数器根本没有复位,说明SYSREF没有进到IP内部,或者被综合工具优化掉了。
曾经有一块板子,SYSREF信号用示波器量明明有波形,但ILA里怎么都触发不到。最后发现,SYSREF引脚接在了普通IO bank,而且没有进任何全局时钟缓冲,被综合工具当成普通数据信号做了逻辑延迟,等到逻辑层再采样时已经面目全非。换成IBUFDS加BUFG的结构之后问题立刻消失。这类问题在原理图设计阶段就要避免:SYSREF的FPGA引脚必须选在支持全局时钟输入的引脚上,而不是随便挑个IO。
4. 多芯片/多板同步实战要点
4.1 板级SYSREF分配网络怎么设计
SYSREF虽然是协议层的同步信号,但板级设计决定了它能否可靠工作。JESD204B多芯片同步对SYSREF分配网络的要求,本质上和时钟分配网络差不多。
首先要保证SYSREF与所有device clock同源。常见的做法是用支持JESD204B的时钟芯片,例如LMK04828、HMC7044等,同时产生device clock和SYSREF。这些芯片能做到device clock和SYSREF之间的相位关系精确可控,而且多个输出之间的skew可以做到皮秒级。如果只是随便用一个时钟源分频产生SYSREF,不同板卡之间的时序一致性完全没有保障。
其次,SYSREF要扇出到每一片ADC/DAC和FPGA,走线要尽量等长,且SYSREF线要有完整的地平面参考。多片转换器之间的SYSREF延迟差,决定了多芯片采样的同步精度。具体要求以芯片手册为准,通常需要控制在几十皮秒以内。这里有一个容易被忽视的点:SYSREF的串接电阻、滤波电容都会影响上升沿和偏斜,调试时不能只盯等长。
再到FPGA内部,SYSREF的路径延迟也要考虑。不同芯片、不同批次、不同温度下,SYSREF到内部寄存器的路径延迟会有差异。这就是为什么有的板子在实验室没问题,产线上一大批只回来几块好的。量产项目建议在老化测试阶段专门跑SYSREF时序测试,把建立保持时间余量压到最小。
4.2 寄存器配置和参数核算,必须两头一致
JESD204B参数一致是建链的前提,FPGA侧的IP配置和转换器侧的寄存器配置必须完全匹配。除了L、M、F、S、N、N'这些基础参数,还要注意K值。K值决定了多帧长度,也直接影响了LMFC周期。
举个实际例子:某ADC的配置是L=4、M=1、F=2、N=N'=16、K=32,lane_rate为10Gbps。LMFC周期 = (32 × 2 × 10) / 10Gbps = 64ns。FPGA侧的JESD204B IP也要配置成完全相同的参数,同时SYSREF频率要设置为64ns的周期(如果使用单次触发SYSREF,则不需要周期匹配,但要满足触发时序)。
我见过一次排查了很久的问题:FPGA侧IP配了K=32,ADC侧寄存器却是K=16,两边都能各自完成CGS,但ILAS阶段一直报错。最后把ILAS抓出来的配置参数和寄存器配置逐字节对比,才发现K值不一致。以后这类问题我都是先抓ILAS数据,直接看参数实际传的是什么,比反复翻寄存器手册快得多。
建议在工程里把JESD204B参数做成一个统一的配置文件,既用于FPGA IP例化,也用于转换器初始化,还要导出一份给硬件同事核对。人肉核对参数这件事,一次两次还行,项目多了一定会出错。
4.3 排查同步失败的通用顺序
JESD204B同步失败的排查,我一直遵循从物理层到协议层、从单板到多板的顺序。
第一步,确认物理层。查参考时钟、复位信号、GT/GTH的复位状态和CDR失锁计数。必要时候用IBERT跑一下高速lane误码率,确认serdes通道本身没问题。
第二步,确认CGS。观察SYNC~信号是否稳定拉高,正常上电后应该很快完成CGS。如果SYNC~反复抖动,优先怀疑参考时钟质量和差分极性。
第三步,确认ILAS。抓ILAS内容,检查参数是否和配置一致,以及多通道是否对齐。
第四步,确认SYSREF。用ILA抓SYSREF和LMFC计数器的关系,确认每次SYSREF都能复位LMFC。
第五步,确认用户数据正确性。跑ramp码型测试或PRBS伪随机序列测试,确认数据通路的位序、字序全部正确。
这个顺序看着简单,但能覆盖绝大多数问题。我经常看到工程师一上来就抓用户数据,发现数据乱套了就开始怀疑信号完整性,结果绕了一大圈,最后发现是SYSREF没接好。先理清同步阶段,再去看数据,能省下一大半时间。
5. 常见问题速查与调试心得
5.1 一张表搞定高频问题
下面这张表是这几年调试JESD204B接口时遇到最高频的问题汇总,按现象、原因和排查手段整理。
| 现象 | 可能原因 | 排查手段 |
|---|---|---|
| SYNC~一直为低 | 无参考时钟、lane rate不匹配、差分极性反 | 查看GT状态、参考时钟输入、IBERT眼图 |
| SYNC~拉高后又掉下来 | 偶发误码、时钟抖动大、CDR失锁 | 统计误码率,检查电源纹波和参考时钟 |
| CGS正常但ILAS解析失败 | 收发参数不一致、F值或K值配错 | ILA抓ILAS逐字节核对参数 |
| ILAS后数据错位 | 弹性缓冲读指针未对齐、LMFC复位异常 | 检查SYSREF和LMFC计数器关系 |
| 单板正常但多板失步 | SYSREF到达各板时刻差异大、分配网络不均衡 | 示波器测各板SYSREF偏斜,优化扇出网络 |
| SYSREF有波形但IP采不到 | 引脚没走时钟资源、建立保持时间不足 | 换成IBUFDS+BUFG,检查XDC时序报告 |
| 温度变化后偶发失步 | SYSREF脉宽或建立保持裕量不足 | 加脉宽、调SYSREF延迟、做高低温循环测试 |
这张表建议打印出来贴在工位上,遇到问题先对号入座。
5.2 我亲手踩过的几个坑
第一个坑,SYSREF脉宽不够。某项目用外部信号源产生SYSREF,脉宽只有2ns,看起来波形挺好,但总是偶尔失步。查手册发现芯片要求SYSREF脉宽至少3ns,调整到10ns后问题彻底消失。这个还提醒我,调试时要先看数据手册的SYSREF电气规格,而不是想当然觉得“只要上升沿干净就行”。
第二个坑,把SYSREF当普通数据信号接。有一次原理图上SYSREF接到了普通IO,没有走全局时钟网络,结果内部逻辑采样到的SYSREF不稳定,导致链路建了很久才能成功。后来改成IBUFDS加BUFG的结构,同时约束了时钟路径,问题马上解决。有些FPGA JESD204B IP的sysref输入本身就要求接在特定引脚上,画原理图前一定要看引脚约束文档。
第三个坑,K值两边不一致。前面提到过,FPGA侧配K=32,ADC寄存器配K=16,ILAS反复报错。当时看波形、看眼图、看配置界面都正常,最后实在没办法把ILAS里传的参数一个一个字节抠出来,才发现K不对。从那以后,我每次都要求软件同事把寄存器回读出来,而不是只信配置脚本。
第四个坑,多板联调时不同板卡SYSREF存在固定偏斜。这个在实验室单板测试中完全正常,但一上系统,不同板卡的数据相位差了几百ps。排查后发现是时钟芯片的输出相位配置没有统一。时钟芯片支持SYSREF相位微调,把各板相位调到和主时钟参考一致后,问题解决。这个属于“看着像硬件问题,其实是配置没同步”的典型。
5.3 调试流程,建议固化到项目里
JESD204B调试很依赖流程化。我现在的习惯是,新板子回来后不急着跑业务,先跑一遍完整的建链测试。
测试步骤固定为:上电后先读GT状态,确认物理层;然后查CGS状态;再抓ILAS内容,确认参数;接着检查SYSREF和LMFC对齐;最后跑ramp码型测试,以像素级数据确认没有字序错位。
同时把状态寄存器和错误计数器全部通过调试口上报,这样即使FPGA侧出问题,也能远程拿到现场数据,不用每次都拆机焊线。多板项目还要固定做高低温循环测试,很多偶发失步问题在常温下根本测不出来,温度一变化就现原形。
最后说一个我个人的习惯:每次拿到新板子,我先不急着跑业务逻辑,先把JESD204B的建链状态机单独拉出来做一次完整的时序测试,确保SYSREF、SYNC~、LMFC三者关系在常温下余量足够,再碰上层应用。很多看起来玄学的数据异常,最后基本都能回溯到同步环节。希望这篇能把大家在JESD204B同步上浪费的时间省下来,剩下的时间留给真正有意思的信号处理。