1. 为什么JESD204会成为高速数据采集的必经之路
搞FPGA开发到一定阶段,你迟早会撞上JESD204这个协议。我第一次接触它是在一个高速ADC采集项目里,当时用的还是LVDS并行接口,16对差分线拉得密密麻麻,PCB走线等长绕得我头皮发麻。后来ADC采样率往上提,并行接口的时序余量越来越小,眼图闭合得让人绝望,才被迫转向JESD204B。这个协议的核心价值就一句话:用高速串行链路替代大量并行数据线,把PCB布局从走线地狱里解放出来。
JESD204最初是JEDEC在2006年发布的,最初版本叫JESD204,后来演进到204A、204B,现在最新是204C。204B是目前工业界用得最广的版本,支持最高12.5Gbps的lane速率,关键特性是引入了子类(Subclass)概念。Subclass 0没有确定性延迟要求,Subclass 1用SYSREF信号实现确定性延迟,Subclass 2用SYNC信号实现。做多通道同步采集的时候,Subclass 1几乎是必选项,因为你需要保证每个通道的采样数据在时间上严格对齐。
为什么说它是高速数据采集的必经之路?你去看现在主流的ADC和DAC芯片,ADI的AD9208、AD9680,TI的ADC12DJ3200、DAC38J84,几乎全部标配JESD204B接口。这些芯片的采样率动辄1GSPS以上,用并行接口根本传不出来。JESD204B的链路层把数据打包成帧(Frame),多个帧组成多帧(Multiframe),通过8b/10b编码在SerDes上传输。接收端要做时钟数据恢复、字节对齐、帧对齐、多帧对齐,最后才能还原出原始采样数据。整个过程涉及链路初始化、代码组同步、初始通道对齐、用户数据加载几个阶段,每个阶段都有严格的时序要求。
对于FPGA开发者来说,JESD204B的难点不在于协议本身有多复杂,而在于调试。链路建立不起来的时候,你面对的是几个状态寄存器的值,根本不知道问题出在物理层、链路层还是时钟上。我踩过最深的坑是SYSREF的时序,当时用Subclass 1模式,SYSREF和器件时钟的相位关系没处理好,链路偶尔能建立但数据错位,查了整整一周才发现是SYSREF的建立保持时间不满足要求。所以这篇文章我会把JESD204B的IP核配置、嵌入式初始化流程、以及实际调试中遇到的坑都掰开揉碎讲清楚。
2. JESD204B协议核心机制拆解
2.1 链路层的数据打包逻辑
JESD204B的链路层做的事情,本质上就是把ADC的采样数据按照一定的规则重新排列,然后交给物理层的SerDes发送出去。这个规则涉及几个关键参数:每帧的字节数F、每帧的转换器数M、每个转换器的采样精度N、每个样本的传输位数N'、每多帧的帧数K。这些参数不是随便设的,它们之间要满足一定的约束关系。
举个例子,假设你用一个双通道ADC,每个通道14位精度,采样率1GSPS,用4条lane传输。那么M=2,N=14,N'通常取16(因为要按字节对齐),F=2(每帧2个字节,对应一个样本的16位),K通常取32。每条lane的线速率就是:采样率 × M × N' × (10/8) / L,其中L是lane数。代入数值:1G × 2 × 16 × 1.25 / 4 = 10Gbps。这个计算很关键,因为线速率决定了你选的FPGA收发器能不能支持,也决定了PCB板材和连接器的选型。
8b/10b编码是JESD204B的物理层编码方式,每8位数据编码成10位传输,带来25%的开销,但保证了直流平衡和足够的跳变沿用于时钟恢复。204C版本引入了64b/66b编码,开销降到3%左右,但对时钟恢复的要求更高。目前204B还是主流,所以8b/10b是必须理解的。
2.2 同步状态机的四个阶段
JESD204B链路的建立过程是一个严格的状态机,分为代码组同步、初始通道对齐、用户数据加载三个阶段,加上最开始的链路初始化,一共四个阶段。
代码组同步阶段,接收端发送SYNC请求,发送端收到后开始发送K28.5字符(逗号字符)。接收端在每条lane上搜索K28.5,连续收到至少4个后,认为该lane的字节边界已对齐,拉高SYNC信号。这个阶段的关键是CDR(时钟数据恢复)要锁定,如果CDR没锁,收到的就是乱码,永远找不到K28.5。
初始通道对齐阶段,所有lane的SYNC都拉高后,发送端开始发送ILA序列。ILA序列包含多帧对齐信息,接收端用这些信息把多条lane的数据对齐到同一个多帧边界。这个阶段最怕的是lane间偏斜(skew)太大,超过一个多帧的缓冲深度就对齐失败了。
用户数据加载阶段,ILA完成后,发送端开始发送实际的ADC采样数据。接收端根据配置的帧参数解析数据,输出给后续处理模块。这个阶段如果数据错位,通常是帧参数配错了,或者SYSREF的时序有问题。
2.3 确定性延迟与SYSREF的关系
Subclass 1的确定性延迟是靠SYSREF信号实现的。SYSREF是一个周期性的脉冲信号,它的上升沿定义了多帧的起始边界。发送端和接收端都用同一个SYSREF来对齐各自的本地多帧计数器(LMFC)。这样,从ADC采样到FPGA收到数据,整个链路的延迟是固定的,可以精确计算出来。
SYSREF的频率必须是多帧频率的整数倍,而且要和器件时钟保持确定的相位关系。实际调试中,SYSREF的走线要等长,端接要正确,否则建立保持时间不满足,LMFC对齐就会出错。我一般会用示波器同时抓SYSREF和器件时钟,确认两者的相位关系在数据手册要求的窗口内。
3. JESD204B IP核配置实战
3.1 IP核选型与关键参数设置
Xilinx的JESD204 IP核是目前FPGA开发中最常用的,Vivado里直接可以例化。IP核的配置界面参数很多,但核心就那么几个:L(lane数)、M(转换器数)、F(每帧字节数)、K(每多帧帧数)、N(采样精度)、N'(传输位数)、S(每帧每转换器的样本数)、CS(控制位)、CF(控制帧位)。
配置的时候有个原则:先确定ADC的型号和它的JESD204B配置,然后让FPGA的IP核去匹配ADC。ADC的数据手册里会给出推荐的参数组合,直接抄过来就行。比如AD9680,双通道14位,推荐配置是M=2,L=4,F=2,K=32,N=14,N'=16,S=1。
IP核的时钟架构也要注意。JESD204 IP核需要几个时钟:收发器的参考时钟、核时钟(core clock)、AXI总线时钟。核时钟的频率是线速率除以40(8b/10b编码后是10位,但IP核内部按40位处理)。比如线速率10Gbps,核时钟就是250MHz。这个时钟必须由MMCM或PLL从参考时钟生成,抖动要控制好,否则收发器的误码率会很高。
3.2 收发器的物理层配置
JESD204B的物理层用的是FPGA的高速收发器,Xilinx 7系列叫GTP/GTX/GTH/GTH,UltraScale叫GTH/GTY。配置收发器的时候,线速率、参考时钟频率、编码方式要和JESD204 IP核的配置一致。参考时钟的抖动要求很严,一般要求RMS抖动小于1ps,否则CDR锁不定。
收发器的均衡器设置也很关键。短距离背板连接可以用DFE(判决反馈均衡),长距离或者电缆连接可能需要CTLE(连续时间线性均衡)。我一般先用默认设置,如果误码率高再调整。眼图扫描功能可以帮你直观地看到信号质量,Vivado的IBERT工具就是干这个的。
3.3 时钟方案与SYSREF生成
时钟方案是JESD204B设计中最容易出问题的地方。整个系统需要器件时钟(Device Clock)、SYSREF、参考时钟。器件时钟给ADC和FPGA的JESD204核用,SYSREF给两者的LMFC对齐用,参考时钟给收发器用。
通常用一个时钟芯片(比如LMK04828)来生成这些时钟。LMK04828可以输出多路时钟,每路的频率和相位都可以独立配置。配置的时候要注意:SYSREF和器件时钟的相位关系要满足ADC和FPGA的要求,一般要求SYSREF在器件时钟的上升沿附近建立保持。具体窗口看数据手册,不同芯片要求不一样。
SYSREF的使能方式有两种:连续模式和脉冲模式。连续模式下SYSREF一直输出,脉冲模式下只在需要的时候发几个脉冲。Subclass 1通常用脉冲模式,在链路初始化之前发一次,之后就不再发了。这样可以减少SYSREF对系统的干扰。
4. MicroBlaze嵌入式初始化流程
4.1 为什么需要嵌入式初始化
JESD204B链路建立之后,还需要配置ADC的内部寄存器,比如设置采样率、增益、测试模式等。这些配置通常通过SPI接口完成。你可以用FPGA的逻辑直接写SPI状态机,也可以用MicroBlaze软核跑C代码来配置。用MicroBlaze的好处是灵活,改配置不用重新综合FPGA,而且可以跑复杂的初始化序列。
MicroBlaze是Xilinx的32位软核处理器,在Vivado里可以像IP核一样例化。配合AXI总线,可以挂载SPI、I2C、UART等外设。初始化流程一般是:MicroBlaze启动后,先配置时钟芯片,然后配置ADC,接着启动JESD204链路,最后检查链路状态。
4.2 MicroBlaze系统的搭建
在Vivado里搭建MicroBlaze系统,需要例化MicroBlaze核、AXI互联、AXI GPIO、AXI SPI、AXI UART等IP。MicroBlaze的配置选项很多,但常用的就几个:处理器频率、缓存大小、调试接口。处理器频率一般设100MHz到200MHz,缓存用默认的就行。
AXI SPI IP核用来和ADC通信。配置的时候要注意SPI的时钟极性、相位、数据位宽要和ADC匹配。ADC的SPI通常支持4线模式,片选、时钟、数据输入、数据输出。SPI的时钟频率不能超过ADC手册规定的最大值,一般10MHz到50MHz。
AXI UART用来打印调试信息。MicroBlaze的C代码里可以用printf输出链路状态、寄存器值等,方便调试。UART的波特率一般设115200,和电脑的串口助手匹配。
4.3 初始化代码的编写要点
MicroBlaze的C代码主要做三件事:配置时钟芯片、配置ADC、启动并检查JESD204链路。配置时钟芯片的代码要根据LMK04828的寄存器手册来写,每个寄存器的值都要仔细核对。配置ADC的代码要根据ADC的寄存器手册来写,通常有一个推荐的初始化序列。
启动JESD204链路的代码,主要是写JESD204 IP核的寄存器,使能链路,然后轮询状态寄存器直到链路建立。如果链路建立失败,要读错误寄存器,判断是哪个阶段出了问题。常见的错误有:CDR没锁、代码组同步失败、ILA失败、SYSREF错误等。
代码里要加超时机制,不能死等。如果链路在预定时间内没建立,要打印错误信息并尝试重新初始化。我一般会加一个重试计数器,重试3次还不成功就报错。
5. 调试实战与常见问题排查
5.1 链路建立失败的排查思路
链路建立失败是最常见的问题,排查的时候要按阶段来。先看CDR有没有锁,如果CDR没锁,检查参考时钟频率和抖动、收发器配置、PCB走线。CDR锁了之后看代码组同步,如果SYNC拉不高,检查K28.5字符有没有发出来、接收端有没有收到。代码组同步过了看ILA,如果ILA失败,检查lane间偏斜、多帧长度配置。ILA过了看用户数据,如果数据错位,检查帧参数、SYSREF时序。
我遇到过一次CDR锁不定的情况,查了半天发现是参考时钟的电源噪声太大,换了一个LDO就好了。还有一次是代码组同步失败,原因是收发器的极性接反了,在IP核里把极性翻转一下就好了。
5.2 SYSREF时序问题的解决方法
SYSREF时序问题很隐蔽,因为链路可能偶尔能建立,但数据不稳定。排查的时候用示波器抓SYSREF和器件时钟,看建立保持时间。如果不满足,调整时钟芯片的相位配置,或者调整PCB走线长度。SYSREF的走线要远离高速信号,避免串扰。
还有一种情况是SYSREF的频率不对。SYSREF必须是多帧频率的整数倍,如果频率偏了,LMFC对齐就会周期性出错。用频率计测一下SYSREF的频率,确认和计算值一致。
5.3 数据错位的几种典型表现
数据错位表现为接收到的数据看起来有规律但不对,比如通道交换了、样本顺序乱了、高位和低位反了。通道交换通常是lane映射配错了,在IP核里调整lane的顺序就行。样本顺序乱了可能是帧参数配错了,检查F和S的值。高位低位反了可能是N'和N的配置问题,检查传输位数的设置。
还有一种数据错位是间歇性的,偶尔错几个样本。这种通常是时序余量不够,可能是SYSREF的抖动太大,或者收发器的均衡器没调好。用IBERT扫描眼图,看眼高眼宽是否足够。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| CDR无法锁定 | 参考时钟抖动大、频率不对 | 用示波器测参考时钟 | 更换低抖动时钟源,检查频率 |
| SYNC拉不高 | K28.5未发送、极性反 | 检查发送端配置、收发器极性 | 使能K28.5发送,翻转极性 |
| ILA失败 | lane间偏斜大、多帧长度错 | 测lane间偏斜,检查K值 | 调整走线等长,修正K值 |
| 数据间歇性错位 | SYSREF时序不满足 | 抓SYSREF和器件时钟相位 | 调整时钟芯片相位配置 |
| 链路偶尔断连 | 电源噪声、温度漂移 | 监测电源和温度 | 优化电源滤波,加散热 |
6. 几个容易被忽略的实操细节
6.1 IP核复位顺序有讲究
JESD204 IP核的复位不是拉一下就行,要按顺序来。先复位收发器,再复位核时钟域,最后复位AXI接口。如果顺序错了,IP核可能起不来。我一般会在MicroBlaze代码里写一个复位序列,按顺序操作。
6.2 时钟芯片的配置要留余量
时钟芯片的配置不要卡在极限值上,比如SYSREF的相位,不要设在窗口的边缘,要设在窗口中间。这样温度变化或者电源波动的时候,还有余量。我一般会把相位设在窗口的中间偏一点的位置,实测下来最稳。
6.3 链路状态要持续监控
链路建立之后不是就没事了,要持续监控状态寄存器。如果链路断了,要及时发现并重新初始化。我一般会在MicroBlaze里起一个定时器,每隔一段时间读一次链路状态,如果发现异常就触发重新初始化。
6.4 测试模式先跑通再接真实数据
调试的时候先用ADC的内部测试模式,比如斜坡信号、正弦波,这样数据是已知的,容易判断对错。测试模式跑通了再接真实信号,可以排除很多变量。我见过有人直接上真实信号,数据不对根本不知道是链路问题还是信号问题。
6.5 电源和地的处理不能省
JESD204B的收发器对电源噪声很敏感,电源滤波要做好。收发器的电源通常需要多级滤波,铁氧体磁珠加电容。地平面要完整,不要被信号线割裂。我踩过一次坑,收发器的电源和数字电源共用了一个LDO,结果误码率一直下不来,分开供电就好了。
7. 从项目实战中积累的经验
做JESD204B项目,最深的体会是:协议本身不难,难的是调试。链路建立不起来的时候,你面对的是几个寄存器的值,需要根据现象反推问题出在哪。我的经验是,先把物理层调通,用IBERT确认眼图没问题,再调链路层。链路层调通了再调数据层。一层一层来,不要跳。
另外,MicroBlaze的初始化代码要写得健壮。不要假设链路一次就能建立,要加重试机制。不要假设ADC的配置一次就写对,要读回来验证。不要假设时钟芯片的输出一次就正确,要测量确认。这些看起来是小事,但实际项目中能省很多调试时间。
还有一点,文档要记好。每次调试遇到的问题和解决方法都记下来,下次遇到类似问题可以快速定位。JESD204B的调试经验很宝贵,因为很多问题不是看手册能看出来的,都是踩坑踩出来的。
最后分享一个小技巧:如果链路建立不稳定,可以试着降低线速率。线速率降下来,时序余量就大了,如果降速后链路稳定了,说明是信号完整性问题,去查PCB和均衡器。如果降速后还是不稳定,说明是配置问题,去查参数。这个方法能快速区分是硬件问题还是软件问题。