做高速多通道采集,最让人头疼的往往不是ADC本身,而是让4片AD9208在同一时刻采样、同一套时钟体系下工作。LMK04828负责给整个系统发“心跳”——既是4片ADC的采样时钟,又是JESD204B链路必需的SYSREF参考信号;FPGA则负责在SYSREF的边沿上把每条链路的本地多帧时钟LMFC对齐。这套组合是目前射频直采、雷达、多通道仪器里很典型的方案,但真正上手的时候,寄存器配置、时序对齐、上电顺序任何一个环节出问题,轻则链路起不来,重则4片之间相位差几十皮秒还没法查。这篇文章就把我从时钟树规划到FPGA初始化完整调通的思路和坑都捋一遍,给准备用LMK04828 + 4片AD9208做多通道同步采集的朋友做个参考。
1. 多片AD9208同步的本质与整体方案
1.1 这些芯片分别在系统里扮演什么角色
先交代一下系统背景。板卡上有4片AD9208,每片是双通道14bit ADC,目标采样率2457.6MHz(245.76MHz基准的10倍),要求8个模拟通道严格同步采集。每个AD9208输出8对高速串行lane,数据通过JESD204B协议进入FPGA做后续处理。
LMK04828在这套系统里不是配角。它承担两件核心工作:
- 给4片AD9208提供2457.6MHz采样时钟,以及给FPGA提供GT参考时钟
- 产生SYSREF信号,让所有AD9208和FPGA的JESD204B本地多帧时钟在同一个时间基准上对齐
把这两件事做好,4片ADC才能保证在同一个时刻对模拟输入进行采样,并且所有数字数据在FPGA内部恢复出的采样序列是严格对齐的。这里的“同一时刻”不是粗略意义上的同一毫秒,而是要求各路采样时钟的相位差控制在几十皮秒级别,SYSREF与采样时钟的时序关系满足器件手册的建立保持窗口。
FPGA侧用的是Xilinx UltraScale+系列,4片AD9208对应4个JESD204B IP核,每个IP核处理一片ADC的8条lane。IP核配置、上电复位、SYSREF捕获、LMFC对齐,这些流程都必须和LMK04828的时钟输出严格配合,否则数据进到FPGA以后是乱的,甚至完全起不来。
1.2 JESD204B同步到底在同步什么
很多刚接触JESD204B的人会把“同步”简单理解成“AD9208采样时钟同频同相”,实际上这只是基础。JESD204B子类1要求的是:所有发送端(AD9208)和接收端(FPGA IP核)的本地多帧时钟LMFC相位对齐。
这里要理解几个关键概念:
- device clock:JESD204B链路的工作时钟,AD9208内部会根据采样时钟分频产生,FPGA侧对应GT的参考时钟
- SYSREF:子类1专用的同步参考信号,它必须相对于device clock满足确定的建立保持时间
- LMFC:本地多帧时钟,JESD204B协议里所有数据映射、弹性缓冲都以LMFC为基准
- ILAS:初始通道对齐序列,链路建立后各个lane通过这个序列完成字节对齐和多帧对齐
SYSREF的作用相当于一个“起跑枪声”。所有ADC和FPGA在收到SYSREF边沿后,将内部LMFC清零并重新开始计数。只要大家收到的是同一个SYSREF信号、device clock又是同源时钟,那么所有LMFC自然对齐。这个机制就是JESD204B子类1多芯片同步的核心思路。
4片AD9208需要同步,本质上就是要保证8个ADC通道的采样点对应同一个绝对时间点,同时数字域里所有lane的帧边界和多帧边界完全一致。如果LMFC没对齐,即便每条lane数据本身正确,4片ADC之间的数据帧也有固定的相位偏移,后续处理根本没法做。
1.3 为什么用LMK04828而不是普通时钟芯片
普通时钟芯片也能输出不同频率的时钟,但顶不住JESD204B的同步需求。LMK04828本身带着双级PLL和专门的SYSREF产生逻辑,这是一般时钟发生器不具备的差异化能力。
LMK04828的双PLL架构很有讲究。PLL1负责将外部低相噪参考(常用10MHz或100MHz)进行净化,输出一个干净的参考给PLL2;PLL2工作在较高VCO频率上,通过可编程分频产生各路输出。这个架构的好处是,外部参考的相噪和杂散不会直接传递到输出时钟上,VCO的高频抖动被环路滤波器抑制得很低。
SYSREF产生方面,LMK04828专门支持连续模式和脉冲模式,还能通过SYNC输入引脚统一触发各路SYSREF输出。实际项目中我习惯用脉冲模式:由FPGA或外部触发产生一次SYNC请求,LMK04828在所有相关输出上同时产生SYSREF脉冲,所有下游器件在同一个边沿完成LMFC对齐。这比让SYSREF一直跑连续模式更容易控制,也减少了持续干扰。
2. LMK04828的时钟树设计与寄存器配置
2.1 时钟频率规划与计算
在动寄存器之前,先把整个时钟树频率算清楚。这一步偷懒的话,后面调试大概率返工。
本方案的核心频率参数:
| 信号 | 频率 | 用途 |
|---|---|---|
| ADC采样时钟 | 2457.6MHz | 4片AD9208的CLK输入 |
| JESD204B lane速率 | 12.288Gbps | 每片AD9208对应的8条lane |
| GT参考时钟 | 307.2MHz | FPGA的GT refclk,12.288Gbps/40 |
| SYSREF | 2.4MHz | AD9208和FPGA的LMFC对齐信号 |
| LMFC | 48MHz | 本地多帧时钟,由链路参数决定 |
核心计算过程如下。AD9208为双通道14bit,JESD204B链路每片8条lane,N'=16(14bit数据加上控制位填充到16bit):
lane速率 = (M × N' × fS × 10) / (8 × L) = (2 × 16 × 2457.6MHz × 10) / (8 × 8) = 12.288Gbps
这里乘10是因为JESD204B物理层用了8b/10b编码,实际线速率比有效载荷高25%。
配置参数选择F=1、K=32、S=2,校验一下F的计算:
F = (M × S × N') / (8 × L) = (2 × 2 × 16) / (8 × 8) = 1
然后算LMFC周期:
LMFC周期 = (K × F × 8) / lane速率 = (32 × 1 × 8) / 12.288Gbps = 20.833ns
LMFC对应频率48MHz,这个频率必须由采样时钟分频得到。2457.6MHz / 48MHz = 51.2,不是整数?注意这个“分频”不是简单的整数分频,因为LMFC由lane速率链路参数决定,涉及8b/10b开销,实际是2457.6MHz / 48MHz = 51.2,但检查发现这个没直接对应。这里要反过来看,SYSREF只要满足“SYSREF周期是LMFC周期的整数倍”即可。设计SYSREF = 2.4MHz,周期416.67ns,与LMFC周期20.833ns相比正好20倍,满足整数倍关系。这个整数倍关系是JESD204B子类1能够可靠对齐的前提,如果SYSREF周期和LMFC周期不是整数倍,对齐会在不同帧之间漂移。
SYSREF 2.4MHz由LMK04828的VCO 2457.6MHz进行1024分频得到,整数分频,干净利落。选这个组合的另一个好处是,AD9208采样时钟本身也是2457.6MHz的整数倍关系,SYSREF的上升沿始终落在采样时钟的固定相位点上,不会出现边沿随机漂移导致建立保持时间不满足的情况。
2.2 SYSREF产生方式选择
LMK04828的SYSREF有连续模式和脉冲模式。连续模式是SYSREF持续输出,每来一个上升沿都触发一次LMFC对齐;脉冲模式则是在SYNC触发下输出一个或几个脉冲,触发一次对齐一次。
我的建议是优先用脉冲模式,并且SYSREF的脉冲个数选择1个。理由很简单:连续模式下SYSREF一直翻转,除了对齐作用外,还会在电源和PCB上引入额外噪声,对高速采样链路不友好。而且如果SYSREF触发得太频繁,某些ADC器件内部对齐逻辑反复复位,数据路径容易出毛刺。
脉冲模式下需要关注的是脉冲宽度。SYSREF上升沿是有效的对齐边沿,脉冲宽度至少要保证下游所有器件都能稳定采样到。LMK04828的SYSREF输出可以配置成LVDS或LVCMOS,LVDS差分脉冲的边沿质量更好,我建议在ADC和FPGA的SYSREF输入都走LVDS,并保证走线阻抗100欧姆差分。
LMK04828还支持SYSREF的相位动态调整。通过配置每个CLKout的数字延迟,可以在小范围内粗调SYSREF的相位,配合FPGA内部的IDELAY细调,实现对时序窗口的完整覆盖。这个功能在后面调4片ADC相位一致性时很实用。
2.3 寄存器配置流程与关键项
LMK04828的寄存器配置可以用TI官方工具TICS Pro来生成寄存器和评估时序,但实际工程里还是要把关键寄存器项搞清楚,否则出了问题定位很被动。
按照TI手册,配置流程大致是:
- 配置PLL1:外部参考10MHz,分频和鉴相频率设置为10MHz,环路带宽选100Hz左右,主要用于净化参考信号
- 配置PLL2:VCO目标频率2457.6MHz,根据参考频率设置R分频和N分频,确保VCO落在芯片可用范围内
- 配置输出分频:CLKout0-3分频1,输出2457.6MHz;CLKout4-7走SYSREF路径,分频1024,输出2.4MHz
- 配置输出格式:AD9208采样时钟用LVDS,SYSREF用LVDS,FPGA参考时钟用LVDS或LVPECL
- 配置SYSREF模式:脉冲模式,1个脉冲
- 配置SYNC输入极性,使能相关输出
寄存器写入顺序上,要注意一个常见坑:LMK04828的输出使能寄存器必须在时钟分频器配置结束后再写,否则输出在配置过程中被拉到不确定状态,可能导致下游ADC内部器件状态错乱。稳妥做法是先把所有不需要输出的通道置为disable,全部配置完成且PLL2锁定后,最后一次使能SYSREF相关输出和device clock输出。
PLL锁定状态的判断也不能省。通过SPI回读PLL1_LOCKED和PLL2_LOCKED寄存器位,两个都置1后,再确认SYSREF输出状态寄存器为有效,才让FPGA开始对ADC发送同步请求。如果跳过这一步,后面的对齐一定是全乱的。
3. 4片AD9208的JESD204B链路参数与同步电路实现
3.1 链路参数配置与校验
AD9208的JESD204B链路配置不是随便填的,每个参数都要和FPGA侧IP核匹配,否则数据分析永远对不上。
4片AD9208中每一片的链路参数:
| 参数 | 数值 | 说明 |
|---|---|---|
| L | 8 | 每片ADC到FPGA的lane数 |
| M | 2 | 每个AD9208的转换器数量 |
| N | 14 | ADC分辨率 |
| N' | 16 | JESD204B有效位宽 |
| S | 2 | 每帧中每个转换器的采样数 |
| F | 1 | 每帧字节数 |
| K | 32 | 每个多帧的帧数 |
| CS | 0 | 控制位个数 |
之所以每片ADC用8条lane,是带宽决定的。lane速率12.288Gbps,AD9208内部串行器在这个速率上工作稳定,FPGA侧GT也能可靠接收。如果强行用4条lane,lane速率要翻倍到24.576Gbps,目前主流的FPGA GT也顶不住,PCB链路更难做。
L、M、F、K之间存在约束关系,配置完一定要再算一遍。F = (M × S × N') / (8 × L),代入数值确实是1。K=32是最常用的多帧长度,保证ILAS序列在链路建立时有足够的对齐信息。
3.2 SYSREF与采样时钟的同步关系
SYSREF不能想什么时候来就什么时候来。LMK04828产生的SYSREF必须与AD9208的采样时钟保持确定的相位关系,因为AD9208内部并不是直接拿SYSREF上升沿对齐,而是在每个device clock上升沿对SYSREF采样,只有SYSREF在device clock的建立保持窗口内稳定,ADC才能把SYSREF边沿映射到正确的device clock周期上。
解决办法是靠LMK04828的架构天然保证:SYSREF和device clock都从同一个VCO分频而来,SYSREF分频器与CLKout分频器共用VCO边沿,所以SYSREF天然与device clock是边沿对齐的。只要PCB布线时SYSREF与device clock保持等长约束,器件输入端的相位关系就能维持住。
FPGA侧同理。JESD204B IP核会拿GT参考时钟采样SYSREF,同样要求SYSREF的边沿落在GT参考时钟的建立保持窗口内。LMK04828有一路CLKout专门给FPGA输出SYSREF,这一路的相位延迟可以单独调整,如果FPGA报告SYSREF采样失败,优先调这一路的CLKout延迟。
3.3 布线、延时与相位对齐的工程细节
4片ADC的同步,最终拼的是PCB上各个路径的延迟一致性。LMK04828虽然能产生同相的SYSREF和device clock,但从芯片引脚到每个ADC引脚之间的PCB走线长度不可能完全相同,必须把所有相关走线做成等长。
实际工程中我用过两种方案:
- 星形扇出:LMK04828每路输出单独走线到一片ADC,利用芯片的14路输出,4路device clock + 4路SYSREF分别直连4片ADC,每组走线做等长,SYSREF和对应ADC的时钟走线还要一起做长度补偿
- 扇出缓冲:LMK04828只输出一对device clock和一对SYSREF,通过缓冲芯片(比如HMC7044或专门的时钟扇出芯片)分成4路给4片ADC
我这次用的是LMK04828直接扇出。好处是少一级缓冲,少引入一次抖动;缺点是对PCB布局布线要求高,SYSREF四路都要做严格等长,误差控制在±10mil以内。
每一路SYSREF走线还要比对应ADC的采样时钟走线做额外处理。具体的长度关系依赖LMK04828输出端的相位关系,需要用示波器实测后,把粗调数字延迟配上。LMK04828每个SYSREF输出有个Delay寄存器,单位是VCO周期(约407ps),可以拿这个做皮秒级粗调,然后在FPGA侧用GT的RX_CDR和IDELAY做细调。
另外注意AD9208的SYSREF输入终端。AD9208的SYSREF输入是内部自带偏置的,外部要按数据手册要求接合适的端接电阻,不接的话边沿反射会让SYSREF采样窗口变差。有些板子图省事只接差分走线不接端接,结果FPGA侧误码率一直降不下去。
4. FPGA侧JESD204B IP配置与上电握手流程(附关键代码)
4.1 IP核参数与参考时钟选型
FPGA侧我用的是Xilinx JESD204B IP核(对应版本为jesd204_v7_2),每个IP核绑定一片AD9208。IP核配置界面里要填的参数和ADC侧完全对应:
- Line Rate:12.288Gbps
- Reference Clock:307.2MHz
- L:8,M:2,F:1,K:32
- N':16,N:14,CS:0,S:2
- Subclass:1
- SYSREF Configuration:支持SYSREF的Always或脉冲模式
GT参考时钟这里要重点说。12.288Gbps线速率下,GT参考时钟取307.2MHz(除以40)比较常见,也可以用245.76MHz(除以50),具体看所用GT的PLL分频比是否支持。选307.2MHz的好处是QPLL的倍频比正好是整数,配置简单,抖动指标也好。
IP核生成后,工程里还需要例化收发器PHY(jesd204_phy或GT wrapper)。PHY负责GT的复位、CDR锁定、极性调整和字节对齐,IP核负责上层协议。这两个模块的复位顺序有严格先后,必须先PHY后IP核。
4.2 AXI4-Lite初始化与复位时序
FPGA侧的上电流程,我建议严格按照下面步骤来。复位顺序错了,链路就可能卡在某个状态出不来。
第一步,LMK04828配置完成且锁定后,先释放FPGA侧所有GT的复位信号。GT需要几十毫秒完成PLL锁定和CDR校准,这个时间不能省。
第二步,通过AXI4-Lite接口对JESD204B IP核做软复位,复位寄存器位置1再清零。这一步是让IP核恢复到已知初始状态。
第三步,配置IP核寄存器,使能SYSREF接收和相关lane。关键的寄存器偏移有:
// 以Xilinx JESD204B IP为例,寄存器偏移根据IP版本可能略有调整 // 1. 软复位 jesd_write(0x0000, 0x0A); // 写入复位值 usleep(1000); jesd_write(0x0000, 0x00); // 释放复位 // 2. 使能SYSREF jesd_write(0x0070, 0x03); // SYSREF使能,并允许SYSREF触发LMFC对齐 // 3. 配置接收链路 jesd_write(0x0510, 0xFF); // 使能所有lane jesd_write(0x0514, 0x01); // 使能链路 // 4. 读取状态寄存器,确认PHY已锁定 while ((jesd_read(0x0A00) & 0x01) == 0) { usleep(1000); }这里要特别提醒,写完使能寄存器后,不要立刻去读链路状态。GT CDR锁定和字节对齐需要时间,通常要给上几十毫秒。如果一上来就狂轮询状态寄存器,误判的概率很高。
第四步,释放IP核的复位信号,让IP核开始接收ADC发送的初始通道对齐序列ILAS。IP核内部会先完成代码组同步(CGS),也就是连续收到4个K28.5字符后进行lane对齐,然后进入ILAS阶段。
第五步,等待IP核的状态寄存器报告链路处于DATA状态,同时检查各lane的对齐错误标志位。如果ILAS阶段有错误,IP核会拉低sync信号要求ADC重新同步,这时候要回查错的是哪条lane。
4.3 CGS、ILAS、DATA三个阶段的验证方法
JESD204B通信建立要经历CGS、ILAS、DATA三个阶段,FPGA侧调试时每个阶段都要能判断是否通过。
CGS阶段是物理层握手。FPGA发送sync信号(低电平有效)给ADC,ADC收到后持续发送K28.5字符,FPGA的GT在接收端通过comma检测对齐字节边界。如果GT的RX byte alignment没有正确配置,CGS阶段就会卡死。调试时可以通过GT的rxbyteisaligned状态信号确认。
ILAS阶段是协议层对齐。ADC在收到sync解除后,会按照K/F参数发送多帧数据,FPGA从多帧里提取各lane的通道映射和参数校验信息。Xilinx IP核会把ILAS里收到的参数和配置参数比对,不一致时报告错误。
DATA阶段就是正常数据流了。判断4片ADC是否真正同步,有一个很直接的测试方法:给所有模拟通道输入同一个已知信号,采集到的数字数据做互相关,如果LMFC完全对齐,任意两个通道的采样点时间差应该为零。如果对齐偏差,互相关的峰会出现若干个采样周期的偏移。
4.4 多IP核同步的实现方式
4片AD9208对应4个JESD204B IP核,难点在于让四个IP核的LMFC对齐,而不是各对齐各的。
Xilinx的JESD204B IP核本身支持通过同一个SYSREF信号进行多核同步。硬件上,4个IP核的SYSREF输入都接到LMK04828的同一路SYSREF输出(或者扇出的SYSREF信号),每个IP核内部都利用SYSREF对齐自己的LMFC。因为SYSREF是同一个信号的分支,理论上有路径延迟差,但只要PCB等长做好,对齐精度是有保证的。
镜像SYSREF的处理方式上,有人选择把FPGA的SYSREF和ADC的SYSREF完全独立开来,各自用LMK04828的一路输出。好处是FPGA侧SYSREF的相位不会影响ADC侧,方便单独调节。我在方案里就是FPGA用了一路独立的SYSREF输出,有问题单独调,互不干扰。
还有一个实用技巧:4个IP核的复位信号可以用同一个逻辑控制,保证同时开始接收ILAS。如果复位有先后,即便SYSREF对齐了,ILAS的接收起点也会错开,最后的LMFC相位反而不一致。这个细节如果忽略,同步偏差会非常隐蔽。
5. 常见问题排查与工程心得
5.1 起不来:最常见的三个坑
链路起不来,大部分时候不是原理问题,而是配置漏项。
第一个坑是SYSREF极性搞反。AD9208和FPGA的SYSREF采样极性有可能不同,如果LMK04828输出极化方向和ADC期望相反,SYSREF边沿永远落在采样窗口外,链路一直不进入同步状态。排查时用示波器直接看SYSREF边沿,然后跟ADC内部寄存器回读的SYSREF检测状态对比。
第二个坑是GT参考时钟频率没选对。JESD204B IP核的参考时钟如果和线速率不匹配,GT的QPLL根本锁不定。平时可以回读GT的TX/RX resetdone信号,如果一直不拉高,问题八成在参考时钟或者QPLL配置。
第三个坑是上电时序问题。LMK04828如果和FPGA、ADC共用一个电源域,上电瞬间时钟输出还没稳定,ADC如果已经上电并开始尝试采样,内部状态可能进入死锁。我的做法是用FPGA的GPIO控制LMK04828的SYNC引脚,时钟全部稳定后再释放SYNC,统一触发SYSREF。
5.2 同步后偶发丢码怎么定位
偶发丢码比完全起不来还难查。丢码表现为数据流里偶尔出现一个错误的采样点,误码率不高,但系统不达标。
定位顺序按照“物理层 -> 链路层 -> 数据层”来:
- 物理层:用GT的眼图扫描,或者看IBERT误码率测试,确认所有lane的信号完整性。12.288Gbps速率下,PCB过孔、连接器、AC耦合电容都有影响
- 链路层:回读JESD204B IP核的链路错误寄存器,看是不是有CRC错误或者字节对齐错误
- 数据层:做直流输入测试,输入端接固定电压,采集数据看是否出现跳变
我在实际项目里遇到过一种情况,丢码只在SYSREF边沿附近出现。分析后发现是SYSREF信号通过电源层耦合到了ADC的模拟供电上,导致ADC内部采样保持电路在SYSREF边沿瞬间产生了微小的采样误差。解决方法是把SYSREF走线从数字电源区域拉开,ADC的模拟电源和数字电源之间加强隔离。这种问题靠逻辑分析仪是查不出来的,必须从电源和PCB隔离入手。
5.3 4片之间相位不一致的调整手法
4片ADC都工作,ILAS也通过了,但互相关显示通道间有固定时偏,这种问题通常是SYSREF到达每个ADC的时间不一样。
先用示波器测量4片ADC的SYSREF引脚,看上升沿时间差。如果时间差在几百皮秒以上,就要查PCB等长是不是没做到位,或者有没有过孔插入到SYSREF走线里造成额外延迟。
如果时间差很小但在几十皮秒量级,就属于正常偏差,靠调整LMK04828的每路CLKout数字延迟来补偿。LMK04828的数字延迟步进是VCO周期,约407ps,看起来粗,但对SYSREF这种低频信号来说,407ps对应相位偏移很小,配合FPGA侧的IDELAY细调足够覆盖。
调整的最终目标是:4片ADC在同一时刻完成LMFC对齐,FPGA内部4个IP核的LMFC相位也一致。判断标准我前面提过,就是多通道输入同一频率信号做互相关,所有通道的峰值位置应该重合。
5.4 一些值得留住的调试技巧
最后分享几个调试层面很实用的小技巧。
技巧一,调试初期先不要追求2457.6MHz满速跑。可以把采样时钟降到低一些(比如245.76MHz),把链路完整跑通,确认JESD204B配置无误后,再把频率升回来。这样把“协议问题”和“信号完整性问题”分开排查,能省一半时间。
技巧二,用FPGA的IBERT硬核单独测GT链路。IBERT不依赖JESD204B协议,能直接把GT通道的误码率测出来,如果IBERT都不过,后面协议层再怎么调都白搭。
技巧三,SYSREF频率不是越高越好,也不是越低越好。低了,每次上电对齐的响应时间变长;高了,可能超过ADC的SYSREF最大输入频率。用2.4MHz这种低频SYSREF,配合单脉冲模式,是最稳妥的选择。
技巧四,保存一份配置好的TICS Pro工程文件。LMK04828寄存器配置有几十上百个,手工写SPI代码非常容易出错,把TICS Pro导出的寄存器表作为唯一的配置来源,代码直接按表生成,能避免低级错误。Intel FPGA侧也有类似的参考设计,应用笔记XAPP523里对JESD204B PHY和SYSREF的处理思路值得一读,两者在协议层的很多经验是相通的。
带4片AD9208做同步采集,这个过程本质上是把一个复杂的“时刻对齐”问题拆成时钟域的稳定问题、协议域的配置问题和工程域的PCB延迟问题。每个环节单独看都不难,难的是它们会互相影响。如果只记住一条经验,那就是先把SYSREF时序吃透、把GT物理层测干净,再去碰上层协议配置,这样才能在数据出现乱序的时候,一眼定位到是时钟树的锅还是配置的锅。