ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

4片AD9208多通道同步采集:JESD204B确定性延迟设计与调试

4片AD9208多通道同步采集:JESD204B确定性延迟设计与调试 做多通道高速采集的朋友应该都有体会单片AD9208跑通JESD204B接口其实并不难Xilinx的IP核配好、GT收发器一连数据流很快就出来了。但把4片AD9208往板上一放要求8个通道严格同时采样重启之后第一次采样的时刻也必须固定这时候真正头疼的问题才开始浮现。我之前就为这事折腾了两周最后发现瓶颈几乎全在时钟域LMK04828的SYSREF怎么给、设备时钟怎么分配、FPGA侧的JESD204B配置怎么配合每一步都咬着JESD204B规范里的“确定性延迟”。这篇文章把我最终跑通的完整方案、计算过程和踩坑经历整理出来重点覆盖LMK04828的时钟树设计、AD9208的JESD204B参数配置、FPGA侧4个IP核的同步逻辑以及调试中定位问题的思路。适合正在做多通道数据采集、相控阵接收前端、高速示波器类项目的硬件和FPGA工程师参考。1. 为什么多片AD9208同步难在确定性延迟1.1 从单链路跑通到8通道对齐问题出在哪单链路的情况下JESD204B的链路只要能建立数据一直往外吐看起来一切正常。但多片同步的要求完全不同不仅要“同时开始转换”还要保证从ADC采样到FPGA收到数据的整个时延是固定且可重复的。换句话说每次上电复位之后第一个采样点到达FPGA的时刻必须完全相同。如果做不到就算四片ADC的采样时钟来自同一个源重启后每片数据还是会差出几个采样周期甚至差出几个多帧周期。你会在ILA里看到四路数据的样本序号对不齐或者同样都在输出但互相之间的相位关系每次上电都在变。这就是JESD204B规范里说的确定性延迟问题。实际项目中多片同步的难点可以拆成三个层面第一每片ADC的采样时钟必须同源并且相位关系确定第二JESD204B链路必须处于Subclass 1模式下通过SYSREF对齐本地多帧时钟LMFC第三FPGA内部每个JESD204B核的链路层必须能感知并保持这种对齐关系不能各自为政。1.2 JESD204B Subclass 1和SYSREF的作用JESD204B定义了三种Subclass其中Subclass 1是专为多器件同步设计的。它的核心思想是利用SYSREF信号对所有发送器ADC和接收器FPGA的本地多帧时钟LMFC进行对表使每个器件内部的LMFC边沿在同一个时间点对齐进而保证确定性延迟。SYSREF本质上是一个窄脉冲或低频时钟它的上升沿必须落座在LMFC的有效窗口内。器件在SYSREF的上升沿采样LMFC然后据此调整本地的帧/多帧计数器让所有器件的LMFC都从同一个计数点开始工作。之后JESD204B链路中的ILASInitial Lane Alignment Sequence再完成lane之间的对齐最终实现整个链路的确定性传输。这里有一个容易被忽视的点SYSREF和LMFC之间的时序关系非常苛刻。AD9208的数据手册会给出SYSREF相对LMFC的建立时间、保持时间窗口如果你在PCB上让不同ADC的SYSREF走线长度差太多或者SYSREF在LMK04828里的延时设置不对就会出现“链路偶尔能同步但多上电几次就会失步”的诡异现象。1.3 本项目的整体时钟树与参数概览本文以4片AD9208、每片双通道工作、共8通道、采样率1.25GSPS为例。LMK04828负责给4片AD9208提供设备时钟和SYSREF同时给FPGA提供GT参考时钟和SYSREF。整体JESD204B链路参数如下表后续的计算都基于这套配置。参数数值说明ADC型号AD9208 × 4每片双通道采样率 f_s1.25 GSPS每通道M2每片2个转换器L8每片8条laneF4每帧每lane 4字节K32每多帧32帧N / N14 / 16数据位宽14编码位宽16线速率6.25 Gbps每lane物理线速率LMFC4.8828125 MHz本地多帧时钟这套配置的核心是让LMK04828产生的SYSREF频率等于LMFC也就是约4.88MHz。所有器件4片ADC FPGA的LMFC参考都从同一个SYSREF边沿开始计数这样多片同步就在底层具备了可行性。2. LMK04828时钟树设计从参考源到SYSREF的完整链路2.1 输出通道分配谁给时钟谁给同步LMK04828作为集成了双锁相环的时钟芯片在JESD204B系统里的角色是“时间基准分配器”。它不仅要产生干净的设备时钟还要产生与设备时钟相位关系确定的SYSREF。合理规划它的12路输出是系统设计的第一步。以本文的配置为例输出分配可以这样规划LMK04828输出频率去向用途DCLKout01.25 GHzAD9208_0设备时钟采样时钟DCLKout11.25 GHzAD9208_1设备时钟DCLKout21.25 GHzAD9208_2设备时钟DCLKout31.25 GHzAD9208_3设备时钟SDCLKout04.88 MHzAD9208_0SYSREFSDCLKout14.88 MHzAD9208_1SYSREFSDCLKout24.88 MHzAD9208_2SYSREFSDCLKout34.88 MHzAD9208_3SYSREFDCLKout8156.25 MHzFPGA MGTREFCLKGT参考时钟SDCLKout44.88 MHzFPGASYSREF需要特别注意的是设备时钟和SYSREF是一一配对的。LMK04828内部可以精确控制DCLKout和SDCLKout之间的相位关系这是普通时钟芯片做不到的。1.25GHz设备时钟用于AD9208采样SYSREF用于触发所有AD9208的LMFC对齐。156.25MHz参考时钟刚好是6.25Gbps线速率除以40FPGA高速收发器内部PLL可以很方便地从这个参考时钟获得线速率时钟。2.2 用TICS Pro生成寄存器表的配置顺序LMK04828的寄存器数量不少手工去写非常容易出错。工程上正确做法是用TI官方的TICS Pro软件把时钟树需求填进去让它自动生成寄存器表和配置文件。这套配置流程里有几个关键步骤的顺序不能乱。第一步在TICS Pro里选择LMK04828芯片型号建议选B版本相比早期版本在很多指标上有优化。第二步配置PLL1的参考输入。这里以100MHz TCXO作为参考源PLL1负责对参考时钟进行净化和倍频输出给PLL2作为参考。第三步配置PLL2。LMK04828内置VCO通过合理设置倍频和分频系数让VCO工作在最优频点再分频得到1.25GHz的设备时钟。第四步配置SYSREF。SYSREF可以选择连续模式或脉冲模式多片同步场景下建议使用连续的SYSREF或者由外部SYNC引脚触发一次性脉冲。配置完成后TICS Pro会生成一个完整的寄存器表。实际项目中我习惯将这个寄存器表固化成数组放在FPGA的只读存储中上电后由FPGA通过SPI接口写入LMK04828同时用逻辑分析仪或回读方式校验写入结果。不要在Linux启动或应用程序运行后再动态配置时钟芯片那样会引入不可控的上电时序问题。2.3 SYSREF延时补偿与PCB走线约束LMK04828的寄存器里有一项非常重要的配置SYSREF的数字延时和模拟延时。这个延时的作用是微调SYSREF边沿相对设备时钟的位置从而补偿PCB走线带来的时间差。工程上我建议先在PCB布局阶段就尽量保证以下几点所有AD9208的SYSREF走线等长SYSREF差分对内等长SYSREF走线远离设备时钟和其他高速数字信号必要时加屏蔽地孔。FR4板材上信号传播速度大约6ps/mm如果两片ADC的SYSREF走线长度差10mm时间差就有60ps左右。这个数值在低频系统里可以忽略但在JESD204B Subclass 1的时序预算里已经足以造成偶发失步。即便如此PCB上的残差仍然存在。所以LMK04828上的SYSREF延时补偿是最后一道调节手段。具体调节方法先用示波器双通道观察一片ADC设备时钟的上升沿和SYSREF上升沿的相位关系再对比另一片ADC的相同信号通过修改LMK04828对应SDCLKout的延时寄存器把两片ADC的SYSREF边沿尽量对齐。这个过程往往需要反复迭代几次但一旦调好接下来很长时间都不用再动。3. AD9208侧配置JESD204B参数与SYSREF时序预算3.1 线速率、帧频和LMFC的计算在配置AD9208之前最好先自己把线速率、帧频和LMFC算一遍。这套计算不仅决定了JESD204B参数寄存器填什么也决定了FPGA侧GT参考时钟怎么选。线速率的计算公式是线速率 M × N × f_s / L × 10 / 8代入本文参数M2N16f_s1.25GHzL8。先算有效数据率2×16×1.25G/85Gbps。因为JESD204B链路采用8b/10b编码物理线速率还要乘以10/8得到6.25Gbps。这个速率对Xilinx 7系列GTH和UltraScale系列GTY都是很轻松的范围眼图裕量充足。接下来算帧频。每条lane每帧传F4字节每条lane的有效数据率是5Gbps也就是625MB/s。用625MB/s除以4字节得到帧频156.25MHz。然后K32LMFC就等于156.25MHz除以32得到4.8828125MHz。这个LMFC频率就是SYSREF应该提供的频率也是ADC内部本地多帧时钟的基准。这套参数之间是互相咬合的任何一个改动都会连锁影响。实际项目中我通常先定采样率和片数再根据FPGA的GT资源选择合适的L和F最后反推线速率和LMFC确保每个数值都在器件规格范围内。3.2 SPI配置的关键设置项AD9208的SPI寄存器是按功能模块组织的JESD204B相关参数主要分布在链路配置寄存器区域。配置时重点检查以下几类设置。第一类是链路基本参数。L8F4K32M2N16Subclass选1。这几项必须和FPGA侧JESD204B IP核完全一致任何一项不匹配ILAS阶段就会卡住。第二类是SYSREF模式。启用SYSREF检测并设置SYSREF边沿类型通常是上升沿有效。第三类是测试模式。调试阶段强烈建议先启用JESD204B测试图形模式让ADC输出递增斜坡或者固定图案这样可以快速判断链路同步是否成功而不用先处理真实采样数据的正确性。配置顺序上我建议先做一次软复位然后按地址从低到高写入所有配置写完后再配置JESD204B链路复位并重新初始化。不要在ADC转换过程中随意改写JESD204B相关寄存器否则链路状态机会进入不可预期状态。如果回读寄存器发现某个参数没写进去优先检查SPI时序和片选信号的电平配合AD9208的SPI对时序要求比较严格尤其是最后的保持时间。3.3 SYSREF建立保持窗口分析AD9208数据手册里会给SYSREF相对LMFC的建立时间和保持时间要求。这里有一个工程上最容易踩的坑SYSREF并不是只要有边沿就能被正确采样它必须落在LMFC的有效窗口内。在我的项目里我是这样分析时序预算的。LMK04828输出的设备时钟1.25GHz周期800ps。SYSREF频率4.88MHz周期约204.8ns。SYSREF信号的边沿经过PCB走线到达AD9208AD9208内部用LMFC采样SYSREF。如果SYSREF的边沿刚好落在LMFC窗口边界附近温度变化、电压波动都会导致采样结果不稳定体现为偶发的同步失败。解决思路有两层。第一层是走线等长保证4片ADC收到的SYSREF边沿时间差尽量小。第二层是利用LMK04828的SYSREF延时调整把SYSREF边沿放到窗口正中间。具体怎么判断是否在正中间可以反复上下电复位看每次同步是否都能稳定建立。如果连续几十次复位都能成功说明SYSREF位置余量足够如果偶尔失败就要微调延时每次调一个档位再测试。4. FPGA侧JESD204B IP核、SYNC合并与链路验证4.1 4个IP核实例怎么配在Xilinx Vivado环境中JESD204B IP核是一个实例对应一条完整链路。4片AD9208需要例化4个JESD204B IP核实例每个实例对应一片ADC的8条lane。IP核配置界面里的核心参数需要和ADC侧完全对应。物理层选择GT收发器线速率填6.25Gbps参考时钟选156.25MHz。链路层参数L8、F4、K32、N16Subclass选1。这里有个容易忽略的地方IP核内部的编码方式要选8b/10b数据位宽要和F、L匹配。如果你在IP核配置界面里看到的数据位宽是自动计算出来的那就对了。参考时钟的连接也要注意。LMK04828输出的156.25MHz差分时钟需要接到FPGA的高速收发器参考时钟引脚比如GT Bank的REFCLK引脚。在约束文件里要显式指定这个引脚位置。如果参考时钟接错Bank或者接到普通IO上GT完全无法工作。4.2 同步请求的合并逻辑与端口连接附代码JESD204B协议里接收器FPGA通过SYNC信号通知发送器ADC进入ILAS同步流程。SYNC是低有效信号。当FPGA准备好接收数据时保持SYNC为高当FPGA需要重新同步时拉低SYNC。问题在于4个JESD204B IP核实例各自输出自己的同步请求信号但4片ADC的SYNC输入必须同时收到相同的请求。如果只把其中一片ADC的SYNC拉低其他ADC不会进入ILAS整个系统就会卡住。所以需要做一个同步请求合并逻辑。Xilinx JESD204B IP核的rx_sync输出是高有效同步请求。我的合并逻辑非常简单wire rx_sync_0, rx_sync_1, rx_sync_2, rx_sync_3; // 任何一个IP核请求同步都触发所有ADC的SYNC wire sync_request rx_sync_0 | rx_sync_1 | rx_sync_2 | rx_sync_3; // JESD204B的SYNC为低有效 wire sync_n ~sync_request; assign adc0_syncb sync_n; assign adc1_syncb sync_n; assign adc2_syncb sync_n; assign adc3_syncb sync_n;这段逻辑的意义在于只要有一片ADC的链路状态异常FPGA就会同时要求所有ADC重新进入ILAS保证四片ADC始终处于相同的同步状态。实际调试中我曾经因为只连了一片ADC的SYNC信号导致另外三片链路完全正常却不输出数据查了很久才定位到问题。SYNC分配看似简单但优先级在所有接线里算最高的。4.3 复位顺序与上电流程多片同步系统对上电顺序极其敏感这在文档里往往写得不明显但在实际项目中是绝对的经验值。我的经验是采用如下的上电复位流程。第一步先给LMK04828供电由FPGA写入寄存器配置等待LMK04828的LOCK引脚变高。这个等待时间一般需要几毫秒到几十毫秒取决于寄存器配置和外部参考的稳定性。第二步确认LMK04828输出稳定后再释放AD9208的硬件复位引脚让ADC开始初始化。第三步FPGA侧释放JESD204B IP核的复位GT收发器开始锁定参考时钟同时向ADC发出SYNC请求。第四步等待ILAS完成检查链路状态寄存器中的同步状态位。这里最关键的是第一步和第三步之间的等待。如果FPGA在LMK04828还没有锁定的情况下就释放JESD204B复位GT参考时钟可能处于异常频率之后即使时钟稳定了链路也可能进入错误状态。可以在FPGA逻辑里做一个简单的状态机等LMK04828的LOCK信号拉高再延时若干毫秒最后才释放JESD204B复位。5. 实际调试中的三个坑与完整排查链路5.1 坑一LMK04828始终不锁定现象上电后LMK04828的LOCK引脚一直是低电平设备时钟输出和SYSREF输出都没有波形。查了电源和参考输入表面看起来都正常。排查链路是这样的。第一步用示波器看OSCin引脚的参考时钟波形频率和幅度是否符合规格。我遇到的问题就是TCXO的输出幅度不够LMK04828对参考输入幅度有最低要求幅度不够时PLL1根本锁不住。第二步回读LMK04828的寄存器确认FPGA通过SPI写入的值真的写进去了。SPI时序问题经常导致寄存器写入一半芯片工作状态完全错乱。第三步逐级检查PLL1和PLL2的锁定状态寄存器看是这两级中的哪一级没有锁定。最终发现原因在SPI通信的时序上。我原来的SPI控制器在时钟低电平期间切换数据但LMK04828要求数据在时钟上升沿稳定导致部分寄存器写入了随机值。修正SPI相位之后LMK04828正常锁定。这个坑的经验是碰到时钟芯片不工作先回读寄存器别急着怀疑芯片本身损坏。5.2 坑二SYSREF对齐不稳定偶发失步现象系统刚上电时一切正常数据也能采到但运行一段时间甚至只是上下电几十次就会偶发出现四片ADC数据错位。看链路状态寄存器有时候ILAS一直不完成有时候虽然显示完成但数据排列不正确。排查的第一步是判断问题出在时钟域还是数据域。我先关了真实数据让AD9208输出JESD204B测试图形比如递增斜坡。然后上电复位几十次用ILA抓取四路数据发现错位时各路数据的起始编号不一致说明是SYSREF对齐出了问题。第二步用示波器看LMK04828输出的4路SYSREF边沿发现其中一路比另外三路晚了约100ps。原因是PCB走线长度没有完全等长虽然布局时已经做了等长约束但绕线的实际长度还是差了约1.7cm。第三步通过修改LMK04828里对应这一路SDCLKout的延时寄存器把这路SYSREF的边沿提前补回走线造成的差值。反复调整后连续上下电上百次再也没有出现失步。这个坑的教训是PCB等长设计只能保证大部分对齐最终微调必须靠LMK04828的延时功能这也是器件设计时预留这个功能的用意所在。5.3 坑三GT参考时钟对不上CDR锁不住现象JESD204B IP核的GT收发器一直无法锁定Vivado中看到的链路状态停在CDR复位阶段rx_sync持续拉高ILAS始终无法完成。排查时先怀疑链路参数配置反复比对ADC和IP核的参数确认完全一致后问题依旧。然后用IBERT测试工程单独验证GT收发器发现GT能正常收发随机数据说明高速收发器本身没问题。最后检查参考时钟频率发现LMK04828输出的156.25MHz参考时钟误配成了150MHz。LMK04828配置工具里有一个分频比填错导致FPGA GT的参考时钟偏了。GT的CDR对参考时钟频率非常敏感偏离其工作范围就无法锁定。修正LMK04828的寄存器配置后GT立即锁定JESD204B链路正常建立。这个坑提醒我每次改完LMK04828配置都必须在FPGA侧用频率计或Vivado里的时钟监测功能确认参考时钟的实际频率不能只看软件里的配置值。5.4 多片对齐的最终验证方法系统调通之后如何证明4片AD9208的数据确实对齐我的最终验证方法分三步。第一步让ADC输出JESD204B递增斜坡测试图形。四片ADC的斜坡起始值应该相同且每一路数据的递增规律一致。用ILA同时抓取四个IP核的rx_tdata检查同一时刻的数据是否所有通道都是同一个数值。如果通道间数值差了一个固定的偏移量说明链路都工作了但存在帧/多帧级别的错位。第二步验证确定性延迟。反复上下电复位数十次每次复位后检查四路数据的起始对齐点是否完全一致。只要有一次不一致就说明SYSREF或者LMFC对齐还有问题需要继续微调。第三步切回真实采样数据。给所有ADC输入端加上同一个正弦信号用FPGA内部逻辑把8通道数据交叉显示确认正弦波相位在通道间完全相同。这一步是最终验收标准也是客户能直观看到的效果。调试中还有一个实用技巧在JESD204B IP核的用户逻辑里加一个简单的one-shot标志寄存器。当LMFC边沿到来时记录当前采集的第一个样本序号并写入状态寄存器。这样即便不实时用ILA抓波形也能通过读寄存器快速判断链路是否在复位后保持了对齐。写在最后经验这个东西写在博客里几行就带过了实际调的时候每一步都可能卡你好几天。我在这个项目里最有体感的一条是SYSREF时序余量不能被“看起来能同步”骗过去。偶尔同步成功不代表设计稳定尤其多片系统一定要做反复上下电的老化测试。另一个建议是所有配置参数无论是LMK04828还是AD9208都尽量做成FPGA可回读、可在线修改的形式方便调试时在寄存器级别做微调。如果你正在做类似的多片AD9208同步系统不妨从本文的参数表起步先把单板单通道跑通再逐步扩展到4片。等四片对齐那一刻看到数据完美同步之前的折腾也算值了。
RELATED READING

延伸阅读

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