FPGA开发里,JESD204协议是很多人从入门到进阶绕不开的一座山。它的对立面是那种点个IP、连两根线就能跑起来的外设——JESD204B背后牵着一整套IP核配置、高速收发器、时钟树和嵌入式初始化流程。这篇文章是“从近似0基础开始FPGA开发”系列的第14篇,我会以近似0基础的视角,把JESD204B的协议框架、IP核配置和嵌入式初始化串成一条完整链路讲透。你如果是正在调高速ADC/DAC、觉得IP核状态怎么也跑不对、或者被SYSREF和确定性延迟搞到头大的工程师,这篇文章应该能帮你省下不少瞎试的时间。内容不会只讲概念,我会把配置思路、初始化步骤、排查手段一整套给出来,能直接拿去参考。
1. JESD204协议的整体设计与思路拆解
1.1 从并行总线到高速串行:JESD204为什么存在
先说一个很多人没意识到的背景问题:为什么现在高速ADC/DAC都要用JESD204,而不是更简单的并行LVDS或者CMOS接口?
我拿一个12位的ADC举个例子。如果采样率是1GSPS,并行LVDS接口的数据位宽至少是12根,算上时钟和同步信号,PCB上要走的线超过20根。这还不是最麻烦的,麻烦在于等长约束——每根数据线相对时钟的skew必须控制在皮秒级,布线难度和板层成本直接起飞。到了更高采样率,比如4GSPS以上,并行接口在物理上已经走不通了,因为单根线的数据率已经碰上了芯片引脚和PCB板材的双重天花板。
JESD204的出现就是把“宽度换深度”。数据不再十几根线并行传,而是先做串行化,从一对或者几对高速差分线上跑出去。同样的12位1GSPS ADC,用JESD204B一条lane就能搞定,链路速率大概在5Gbps左右。PCB上只需要一对差分线,等长问题从“一堆线”变成“一对线加一个参考时钟”,工程难度降了一个量级。
从应用场景上看,现在但凡是采样率高于500MSPS的ADC/DAC,比如无线通信基站里的RF收发芯片、相控阵雷达的波束成形链路、高速示波器的前端采集,清一色都是JESD204B或者更新的JESD204C接口。所以对于做FPGA的工程师来说,不管你是用Xilinx、Intel还是Microchip的片子,迟早要跟JESD204打交道。这也是我在“从近似0基础开始”系列里专门拿出一篇讲它的原因——它不是一个“可选”的知识点,而是高速采集领域的“必选项”。
1.2 JESD204B的链路模型与参数体系
JESD204这个标准经历了几个版本:初版JESD204差不多是2006年的东西,只能支持单lane,最高速率3.125Gbps;JESD204A加入了多lane同步;到了2011年发布的JESD204B,才是现在用得最广的版本,速率上限提高到12.5Gbps,并且正式引入了确定性延迟的概念。后面还有JESD204C,速率进一步提高到了32Gbps级别,编码方式也加了64B/66B可选。不过绝大多数项目目前用的还是JESD204B,所以我后面的内容主要围绕B版本展开。
要理解JESD204B的链路模型,必须先把几个参数记牢。这些参数就是配置IP核时候让你填的那串字母,很多人一开始搞不清楚它们的含义,我在这里用大白话梳理一遍:
| 参数 | 全称含义 | 通俗解释 |
|---|---|---|
| M | Converters | 链路上转换器的个数,也就是有多少个AD或DA |
| L | Lanes | 物理通道数,一对差分线就是一个lane |
| N | Converter resolution | 转换器的分辨率,比如12位、16位 |
| N' | Total bits per sample | 实际传一个采样点占用的位数,通常因为打包要对齐到4或8的倍数,N'≥N |
| S | Samples per frame | 每一帧里包含几个采样点 |
| F | Octets per frame | 帧长度,以字节为单位 |
| K | Frames per multiframe | 多少帧组成一个多帧,K是个关键值,跟同步机制有关 |
| CS | Control bits per sample | 每个采样点额外带的控制位 |
| CF | Control bits per frame | 每帧的控制字数量 |
这堆参数之间不是随便填的,它们要满足一个基本关系:
链路总数据率 = M × S × N' × fc(采样率)。物理上,总数据率要分摊到L条lane上,再加8b/10b编码的20%开销,就得到了实际线路速率。
线路速率 = (M × S × N' × f_sample) / L × 10 / 8
这个公式是用来算lane速率的。打个比方,一个16位、2GSPS的双通道ADC(M=2),N'通常取16,S根据帧配置取1或者2,如果F=4且K=32,两条lane传输(L=2),那么线速率大概是 (2×2×16×2GHz)/2 ×1.25 = 8Gbps。这个数字就直接决定了你用哪个速度等级的收发器,也决定PCB板材要求。
配置的时候还有另外一个约束,就是帧时钟和多帧时钟的关系。帧时钟等于采样时钟除以每帧采样点数S和每帧字节数F的综合结果,更直观的理解是:一个多帧是链路同步的最小时间单位,多帧时钟周期 = 采样时钟周期 × S × F × K。(这里我简化了一下,实际中是以LMFC也就是本地多帧时钟为核心的,后面会讲。)
Xilinx的JESD204B IP核配置界面里,你填的就是上面这张表。但这里我要提醒一句:这些参数并不是你单独能决定的,而是由你的ADC/DAC芯片手册给的推荐值来决定。比如AD9172、AD9680、ADS54J60这些芯片的数据手册里都会给出标准的LMFK组合,FPGA侧只是去匹配它。千万不要自己拍脑袋改K值,改了之后链路同步机制可能就不工作了。
1.3 三种Subclass和确定性延迟
JESD204B把工作模式分成subclass 0、subclass 1、subclass 2三档,这个分类直接影响你整个系统的同步设计和嵌入式初始化流程。
- Subclass 0:不保证确定性延迟,适合对延迟不敏感的场合,比如一些单纯的采集记录系统。它不需要SYSREF,直接用系统时钟和K码完成同步。
- Subclass 1:通过SYSREF信号实现确定性延迟,是目前高速数据采集和射频系统的主流选择。Xilinx的IP核里你基本都会选这一档。
- Subclass 2:通过SYNC~信号来对齐,应用相对少见,主要用于一些没有SYSREF的器件。
为什么确定性延迟这么重要?简单说,在一个多通道采集系统里,如果每个通道的ADC数据到达FPGA的时间不一致,那后续做波束成形、做通道校准就全乱了。JESD204B的subclass 1模式就是保证:每次上电或者每次重新同步之后,数据从采样到出现在FPGA接口的延迟是完全固定的。为了实现这一点,整个链路必须严格对齐到本地多帧时钟LMFC的相位上。
SYSREF信号是subclass 1的基准。它必须与device clock保持确定的相位关系,FPGA侧收到SYSREF之后,会把内部的LMFC计数器对齐到某个固定边沿。然后发射端和接收端都基于这个对齐后的多帧时钟来发送和解析数据,这样整个确定性就建立起来了。这套机制听起来简单,实际做的时候坑特别多,我在后面章节会展开讲SYSREF的时序约束怎么处理。
2. 核心细节解析与IP核实操要点
2.1 JESD204B IP核的选型与整体配置
FPGA侧拿到JESD204B接口后,一般有三种做法。第一种是用厂商原生的IP核,比如Xilinx从7系列到UltraScale+都有的JESD204B IP核,它在Vivado里直接搜JESD204就能看到。第二种是直接用高速收发器的原始GT,自己从头写协议栈,这个工作量非常大,不推荐,除非你的场景特殊到IP核无法满足。第三种是用ADC/DAC芯片厂商提供的IP核,比如ADI的JESD204 RX/TX模块,配合它的参考设计使用。
用Xilinx的JESD204B IP核时,有几个配置页面是你必须搞清楚的。第一个是Line Rate和Reference Clock的设置,这直接关联到GT收发器的QPLL/CPLL配置。Line Rate填多少,IP核会反推出参考时钟频率,但实际工程里参考时钟是由板上的时钟芯片给的,所以你必须确认板级时钟频率和IP核计算出来的一致。第二个是Lane数量和每个lane对应的GT位置,这在引脚规划的时候就要定好,不要指望到时随便改。第三个是针对subclass 1的SYSREF配置,IP核会要求你选择SYSREF是内部生成还是外部输入。
有一点新手很容易忽略:JESD204B IP核本身不是一个“独立完整”的方案,它必须配合收发器IP核(比如Xilinx的GT Wizard或者GTH/GTY Transceiver Wizard)一起用。在Vivado里,JESD204B IP核会自动例化对应的transceiver wrapper,但你仍然要确认收发器的参考时钟、环路模式、termination这些设置对不对。我见过不少人只配了JESD204B的LMFK参数,结果忘了收发器那边还有一堆GT设置,然后百思不得其解,卡在状态机上。
2.2 时钟系统与SYSREF的设计细节
JESD204B的时钟系统是整个链路里最容易出问题、也是最容易被轻视的部分。很多实验室里调不通,最后用示波器一量,发现SYSREF根本没有和device clock对齐,或者LMFC的相位是抖动的。
先捋清楚时钟家族。整个系统至少涉及这几个时钟:器件时钟device clock(也叫转换器参考时钟,负责产生ADC/DAC的采样时钟和FPGA侧的线速率参考时钟)、位时钟(GT串行时钟)、帧时钟、LMFC。它们之间的倍数关系由LMFK决定。以常见的L=4、F=1、K=32配置来说,每个多帧包含32个帧,帧长度为1个字节,那么LMFC周期就是32个字节对应的长度。
SYSREF的设计要求,用JESD204B标准里的原话就是“SYSREF must be asserted with a setup/hold relationship to the device clock”。翻译成工程语言:SYSREF的上升沿必须和device clock的某个沿保持稳定的建立保持时间,并且这种关系一旦确定就不能变。这不是一个随意的建议,而是确定性延迟的前提。如果SYSREF是板上某个时钟芯片用分频得到的,那你就得保证分频产生的SYSREF和发给ADC的device clock是同步关系,也就是必须由同一个时钟源产生。
在FPGA内部处理SYSREF时,另一个常见坑是SYSREF在进入JESD204B IP核之前经过了不必要的缓冲或逻辑。Xilinx官方推荐约束是SYSREF要通过IBUFDS直接进入GT的参考时钟引脚,并且要在物理约束上让SYSREF的路径延迟尽量短。如果你在SYSREF路径上加了寄存器打拍、加了普通逻辑,即使是看似无害的一个同步器,也可能会破坏IP核内部的SYSREF采样窗口,导致误判。
2.3 IP核接口与数据通路设计
JESD204B IP核起来了之后,你面对的是一堆AXI4-Stream接口或者FPGA侧并行接口。Xilinx IP核的接收方向会输出一个可配置位宽(比如64位或者128位)的数据总线,同时伴随tvalid、tready、tlast、tuser等信号。这里的tuser信号不是随便用的,它里面带有lane的对齐标记和帧边界信息。
在设计数据通路的时候,我建议的顺序是:先把IP核的输出原封不动接到一个环形FIFO或异步FIFO里,做好跨时钟域处理,然后再做数据拼接和格式转换。因为JESD204B IP核的并行数据时钟通常是LMFC的倍数关系,而你的后级处理(比如FFT、抽取滤波)可能是完全另一个时钟域,直接拿IP核的时钟去处理后级逻辑,会在时序收敛上给自己添堵。
这里顺便说一句,很多人喜欢问“JESD204B IP核的数据到底怎么按通道拆开”。答案其实藏在帧和lane的映射关系里:第n个lane在第m帧里传的是哪个转换器的哪个采样字节,由标准里的映射矩阵决定,Xilinx IP核对这个映射关系是固定的。你要做的就是根据M、L、S参数反推。一个16位双通道ADC用2个lane传的时候,数据在每个lane上是交替出现的,而不是“前两个字节是通道A、后两个字节是通道B”。这个理解错了,后面解析出来的数据就是乱的。我的经验是先在FPGA侧给数据打上来源标记,然后直接用型号匹配的参考设计里的deserializer模块来拆数据,不要自己重新发明一遍。
3. 嵌入式初始化实操:从寄存器到链路建立
3.1 嵌入式初始化整体流程设计
JESD204B的链路建立不是一上电就自动好的,它依赖一个严格的握手过程。在FPGA工程里,这个握手过程通常由一个嵌入式处理器来驱动——这也是标题里“嵌入式初始化”的含义。你可以用ZYNQ的硬核ARM,也可以用MicroBlaze软核,甚至可以用一段简单的状态机来做,但用处理器跑的好处是灵活、好调试。
整个初始化流程可以拆成下面几步:
- 系统上电,先完成FPGA配置,释放复位。
- 配置时钟芯片,启动device clock和FPGA侧参考时钟。
- 配置ADC/DAC芯片的JESD204B相关寄存器,设置LMFK、子类、lane极性等。
- 将JESD204B IP核从复位状态释放,执行IP核内部的软复位和初始化。
- 等device clock和SYSREF稳定之后,发送SYSREF脉冲(或者使能周期SYSREF),让链路进入确定性延迟对齐。
- 读取IP核状态寄存器,确认CGS(code group synchronization,码组同步)已经锁定。
- 确认ILAS(initial lane alignment sequence,初始lane对齐序列)阶段完成,各个lane的同步头对齐。
- 进入数据阶段,检查数据是否有效,通过自检模式或者校验码确认链路无误。
这里面的每一步都有讲究。比如第4步里,IP核软复位的时序是有要求的,不能直接往axi寄存器里写“复位=0”就完事,很多时候必须等待Vivado IP核状态机跑到ready状态后才能继续往下走。不做这一步,后面的CGS和ILAS永远不可能成功。
如果你用的是ZYNQ,第2步到第8步通常可以写成一个基于AXI-Lite的设备驱动函数。一个典型的函数调用序列会是:jesd204_init_pll() -> jesd204_reset_ip() -> adc_set_lmfk() -> sysref_align() -> jesd204_check_status()。每一步之间加适当的delay,我在项目里一般用10ms量级的等待,而不是1ms,因为时钟芯片的锁定时间往往比寄存器手册写的要长。
3.2 ZYNQ/软核下的寄存器操作实现
讲讲具体的代码实现逻辑,以Xilinx JESD204B IP核挂在AXI-Lite总线上为例。
你需要在地址映射表里找到以下核心寄存器:IP配置寄存器(写入软复位、使能)、状态寄存器(读出当前状态机的值)、中断使能寄存器等。初始化代码的伪代码结构大概是这样(我这里只说逻辑,具体寄存器偏移以你生成的IP版本为准):
- 写0x00000001到配置寄存器,触发IP核软复位。
- 等待至少8个帧时钟周期,再写0x00000000,解除复位。
- 轮询状态寄存器,直到对应bit显示“TX/RX init done”。
- 如果subclass 1,确保SYSREF已经由外部芯片产生并送入,同时写IP核对齐寄存器使能一次SYSREF对齐。
- 再轮询状态寄存器中的“CGS done”和“ILAS done”标志位(通常在IP核状态机输出的中断向量里有反映)。
用ARM来写的时候,最忌讳的是用delay空转代替对状态标志的轮询。空转虽然简单,但调试的时候你根本不知道卡在哪个环节。我现在的习惯是,每走一步就把当前状态寄存器值记录到一个环形缓冲里,然后通过串口打成日志。这样哪一步没过,一眼就能看到是PLL没锁定还是ILAS没完成。
另外一个细节:当你用的是ZYNQ的AXI-Lite接口时,要注意JESD204B IP核的AXI数据位宽和ARM的读写宽度匹配,不然可能在32位访问时产生意想不到的地址错位。这个看起来是小问题,但实际调试中经常让人困惑。
3.3 数据链路建立后的验证与数据校验
初始化成功不代表万事大吉。一个很常见的现象是链路状态寄存器全绿,但波形出来全是乱的——这就是数据映射关系搞错了,或者字节顺序不对。所以链路建立之后,第一件事是做数据校验,而不是直接接到算法模块里跑。
我通常用三种方法来验证。
第一种是IP核自带的测试模式。Xilinx JESD204B IP核在数据阶段可以注入伪随机序列或者固定图案,接收侧也有对应的检查逻辑。如果你可以配置ADC/DAC输出测试波形(比如AD9680有自带斜坡测试发生器),那就让ADC发斜坡信号,FPGA侧抓数据看是否单调递增,这种方法很快就能暴露字节序和通道错位的问题。
第二种是ILA(Integrated Logic Analyzer)在线抓取。把JESD204B IP核输出接口的tdata、tvalid、tuser信号挂到ILA上,触发条件设为tvalid上升沿,抓一拍数据看tuser值是否符合预期。然后手动把tuser里带的lane编号和数据内容一起对比,就能确认lane映射关系。
第三种是写一个简单的校验器,在FPGA逻辑里实时统计CRC或者对固定帧头做匹配。这个需要你预先知道JESD204B帧结构里的对齐字节位置,适合调试长期稳定性。我一般会让系统跑一整晚,如果校验器不报错,链路就算稳定了。
请注意一个容易忽略的点:JESD204B的数据校验一定要在确定时钟稳定之后再做,不要在板子刚上电几分钟内就下结论说链路不稳。高速链路上电压和温度的变化需要一定时间才能稳定下来,我遇到过一次上电十分钟内偶尔误码、十分钟后完全正常的案例,最后定位是参考时钟芯片的PLL锁定时间比预期长,导致系统实际进入数据阶段的时候时钟还没完全干净。
4. 常见问题与排查技巧实录
4.1 链路起不来的典型症状与根因
我把这几年调试JESD204B遇到的典型问题整理成了下面这张速查表,每一类都是实打实踩过的:
| 症状 | 可能根因 | 排查建议 |
|---|---|---|
| 状态机一直停留在CGS,SYNC~信号不拉高 | 发射端没有输出K28.5字符、线路速率不匹配 | 先确认ADC/DAC侧是否被正确配置为连续发送CGS序列;再用IBERT测试收发器物理链路 |
| CGS过了但ILAS一直不结束 | SYSREF对齐失败、多帧时钟相位不对 | 抓SYSREF和LMFC波形,确认边沿对齐关系;重新触发一次SYSREF |
| ILAS完成但数据完全乱掉 | lane映射不匹配、字节顺序反了 | 让ADC发斜坡数据,逐lane抓波形,对照标准的映射矩阵反推 |
| 偶发误码、隔一段时间掉链 | 电源纹波过大、参考时钟抖动超标 | 用高带宽示波器看电源纹波,检查PLL的抖动指标是否满足链路要求 |
| SYSREF出现但IP核不识别 | SYSREF路径引入延迟或电平不匹配 | 去掉中间逻辑,让SYSREF直接进专用引脚;检查电平标准 |
| 多片ADC无法同步 | 各片SYSREF未同时到达、LMFC未对齐 | 用示波器测多片器件的SYSREF相位差,必要时做板上等长补偿 |
有一个案例我记得很清楚。当时是四片ADC同步采集,症状是每片上电时间不同,后上电的ADC数据偶尔会出现整帧错位。排查时发现,我按ADC手册要求在初始化时只发了一个单脉冲SYSREF,但其中一片ADC因为PLL锁定比较晚,单脉冲落在它PLL还没稳定的窗口里,直接没有被识别到。后面改成在固定时间窗口内连发四个SYSREF脉冲,并确保脉冲边沿对齐到LMFC上升沿之前的固定相位,问题就解决了。这类问题不会在IP核手册里写,因为你用的器件组合是排他的。
4.2 从IP核状态寄存器到波形示波器的排查路径
排查JESD204B问题最忌讳没有章法地乱试。我的顺序固定是:先用IP核状态定位到大的阶段,再用寄存器配置对比定位参数问题,然后用示波器和ILA定位物理层和时序问题。
具体做法是这样的。把IP核透出的状态总线拉出来看,Xilinx的JESD204B IP核通常有tx_rail_align、rx_cgs_done、rx_ilas_done这样的状态信号。第一步先看CGS有没有完成,CGS没有完成,问题大概率在物理层或者发射端配置;CGS完成了ILAS没完成,问题大概率在SYSREF对齐;ILAS都过了数据还是乱的,问题大概率在映射和字节序。
第二步是核对所有寄存器的值。JESD204B这玩意儿,两端参数任何一个对不上,链路都建不起来。我的做法是把两端(ADC/DAC侧和FPGA侧)的LMFKS值打印出来,逐一比对。经常有人填错了S,或者把某片器件的N和N'搞反了,这种问题光靠观察波形是看不出来的。
第三步才是动用示波器。如果CGS都过不去,先用示波器看FPGA侧的RX lane有没有波形翻转。高速差分信号用普通示波器探头测会有损耗,最好用差分探头加上合适的带宽。没有差分探头的话,至少测一测参考时钟和SYSREF,确保低速但关键的信号是好的。
我再啰嗦一句:JESD204B的调试,本质上是“协议状态机”和“物理信号质量”两层问题的交叉。协议层跑通了,物理层未必干净;物理层信号漂亮,协议层参数错了照样建链失败。你排查问题的时候脑子要始终同时装着这两条线,不要只盯着一边。
4.3 文档不会写的避坑经验:电源、PCB和参考设计
有些经验和教训,靠读IP手册是学不到的,因为它们本质上是系统层面的东西。
PCB设计层面,JESD204B的lane对之间的差分阻抗控制、lane对与lane对之间的串扰隔离,这些直接影响误码率。我见过一块板子,RX lane旁边有一段走线本来该包地的没有包,结果距离拉长、串扰变大,链路速率一超过6Gbps就出错。后面重新改版包地处理,问题消失。
电源方面,JESD204B链路出偶发误码,很多时候是模拟电源和数字电源的噪声串扰导致的。特别是ADC数字核心电源和FPGA收发器电源如果共用一片LDO,动态负载变化会通过电源网络耦合到高速收发器。我的经验是高速收发器电源必须保证足够的去耦电容,至少要在靠近供电引脚放置0.1uF和1uF的组合电容。
参考设计是另一个容易被低估的资源。Xilinx官方和各大ADC厂商的评估板参考设计,其实已经把寄存器配置、初始化流程、时序约束都跑通了一遍。我强烈建议你刚开始做JESD204B项目的时候,不要从零写初始化,而是先下载对应型号的参考设计,把初始化代码原封不动跑一遍,确认板级和IP都正常了,再根据自己的需求去改。我见过太多人上来就自己写初始化,结果参数没配对,折腾了两周还不知道问题在哪。
最后一种避坑经验是关于SYSREF的PCB布线。SYSREF和device clock一样,要作为高速信号对待,需要做阻抗控制。很多工程师觉得SYSREF是低速信号就随便走,等到链路建不起来才想起来测SYSREF相位,这时候往往已经晚了。我的规矩是:SYSREF必须和device clock走同一层,且两者之间的skew做到一个SYSREF上升时间以内,最好直接用等长组约束。
5. 嵌入式初始化与项目工程的落地建议
5.1 初始化代码的模块化设计思路
上面讲了具体的寄存器操作,这里我再补充一下嵌入式初始化的工程组织建议。JESD204B的初始化不是一个函数就能写好的,它需要在整个项目中有一块清晰的结构。
我习惯的做法是建一个jesd204_bringup的驱动目录,里面按功能拆成几个源文件:时钟芯片驱动(负责上电时序、配置和锁定检测)、ADC/DAC驱动(负责LMFK和测试模式的寄存器配置)、JESD204链路状态机(负责FPGA IP核的复位、状态轮询和对齐触发)、顶层初始化脚本(把上面这些串成有序的序列)。这样做的最大好处是,换板子或者换芯片型号的时候,你只需要替换对应的驱动文件,而不需要重写整个初始化系统。
把逻辑整理成下面这个流程清单,我每次做新项目都会直接套用:
- 确认时钟芯片锁定、输出频率正确——这一步做不好,后面全白搭。
- 确认FPGA侧参考时钟存在,并可通过IBERT测试物理链路。
- 配置ADC/DAC的JESD204相关寄存器,让发射端进入CGS发送状态。
- 配置FPGA侧JESD204B IP核,取消复位并观察状态。
- 触发SYSREF对齐,进入ILAS阶段。
- 轮询所有lane的ILAS done状态。
- 切换到正常数据模式,启动数据校验。
这个顺序看似稀松平常,但每一步都卡着一个“必须前一步成功”的依赖关系。顺序乱了,比如还没确认时钟就发SYSREF,那链路无论如何也起不来。把顺序固化成代码和文档,团队里任何人接手都能少走弯路。
5.2 多板互联和多片同步的工程考量
如果你做的是多通道同步采集系统,那JESD204B的初始化还有一个额外的层次:多片ADC之间的同步。这意味着不仅每一片ADC到FPGA的链路要建立,还要保证所有ADC的采样时刻对齐,所有数据经过链路到达FPGA的时刻也一致。
这种情况下,SYSREF的设计就变得更重要了。多片ADC的SYSREF应该由同一个时钟芯片同步分发。我在项目里给SYSREF做过多路fanout,发现fanout芯片本身的additive jitter会很敏感地影响LMFC对齐稳定性,所以最后选择了专门的时钟buffer,并保证所有SYSREF输出到各ADC的走线长度一致,skew控制在一个窄范围内。这跟当年做DDR4 IP核设置时对待dqs dqs_n等长的心态是一样的,不能觉得它是低速信号就放松。
如果嵌入式处理器是ZYNQ,多片同步初始化时还要注意SYSREF触发和每个ADC初始化完成状态之间的协调。一片ADC可能因为温度或者上电时序差异比另一片晚锁定100ms,如果你的初始化脚本在固定时间后强制发送SYSREF,那后锁定的那一片就会错过SYSREF。解决办法是初始化脚本轮询所有ADC的PLL锁定状态,全部ready之后再统一发SYSREF,而不是按固定延时发送。这个细节我吃过亏,所以放出来提醒大家。
5.3 从JESD204B到未来版本的过渡
现在JESD204C也开始在一些新器件上出现了。它跟B版最大的区别是速率更高、引入了64B/66B编码(也可以继续用8b/10b),而且在多lane对齐、前向纠错这些方面都有增强。对FPGA工程师来说,好消息是底层的收发器、时钟系统、嵌入式初始化思路是相通的。
你如果掌握好JESD204B这套初始化方法,将来切到JESD204C时,核心的知识点——比如参数匹配、SYSREF对齐、状态机轮询、多lane映射——都不会白学。唯一要重新熟悉的是新IP核的寄存器定义和FEC相关配置。
我不建议现在花大精力去深抠JESD204C的理论,因为实际的项目板子和芯片还不一定支持。我更建议把JESD204B吃透,特别是把“确定性延迟”这个核心机制理解透。理解了为什么SYSREF必须对齐,为什么LMFC是骨干时钟,不管标准怎么升级,你上手都会很快。
6. 写在最后:我的几个实操习惯
按惯例在最后分享几条我个人的经验,跟道理无关,纯粹是习惯。
第一,每次调试JESD204B,我都会先在工程里放好两个调试组件:一个ILA,带深存储,挂在IP核的AXI4-Stream输出上;另一个是VIO,用来在运行时手动触发SYSREF和复位。这两个东西在最开始可能只占一点点资源,但真的能救命,尤其是你没有串口、纯靠JTAG调试的时候。
第二,无论寄存器手册写得多么清楚,我在第一次上板之前都会先用IBERT把高速lane的物理层扫一遍。IBERT能告诉你每个lane的误码率、眼图宽度,如果IBERT都过不了,那就不要花时间去查JESD204B协议层的问题了,省下来的时间比什么都值。
第三,JESD204B的初始化日志要记录完整。我一直会在嵌入式代码里加一个log函数,每执行一步初始化就输出一次时间戳和状态寄存器的值。前端跑起来后,如果链路忽然掉了,有完整日志比拍脑袋猜要靠谱得多。
JESD204B的坑看起来多,但只要你按“时钟先行、状态机紧跟、数据校验最后”的思路走,再加上一套好用的调试手段,它并没有传说中那么可怕。希望这篇文章能让你少走点弯路,把更多时间花在业务算法上,而不是耗在和协议斗争上。