JESD204B链路建立:8B/10B对齐与SYSREF确定性延迟
简介:面向高速ADC/DAC与Serdes接口开发的JESD204B协议规范文档,适合FPGA/DSP工程师、硬件设计人员及通信、医疗成像相关专业学生查阅。它针对传统LVDS、CMOS并行接口在带宽、延迟和引脚数量上的瓶颈,系统阐述基于SERDES的串行链路架构、主从设备通信、链路层多路复用与同步定时等核心内容。压缩包内为1个PDF文件,大小约1.84MB,保留JEDEC固态技术协会标准原文的章节结构与术语体系,从协议概述、关键特性到架构实现逐层展开,便于按条目检索。文档覆盖最高12.5Gbps速率、8b/10b编码、可选前向纠错、链路初始化与配置等关键点,并延伸至无线通信、医疗成像、雷达遥感等应用场景,可用于接口方案选型、链路调试排错、协议学习对照以及FPGA/DSP与转换器联调。已有3388人学习,适合作为高速转换器接口设计与验证的常备参考资料。
1. 大多数人在 JESD204B 协议上栽跟头,都不是 12.5 Gbps 那个数字
一提到 JESD204B 协议,大家习惯性把注意力全放在 12.5 Gbps 上:插损够不够、眼图张不张开、均衡档位怎么调。但在高速信号传输的现场,链路起不来这件事十次有八次不在幅度,而在相位。
示波器上眼图漂亮、误码仪也能跑过,SYNC~ 却一直拉低,接收侧连一个 /K/ 字符都认不到;或者认到了,又在多帧对齐阶段反复重来。SERDES 接口开发的难处从来不是把比特送出去,而是让两端对“第几个比特属于第几帧”这件事达成绝对一致。
JESD204B 的底层逻辑是先对齐、后传数:链路建立阶段跑的全是控制字符,一个用户数据都不传。把对齐机制吃透,比反复调眼图有用得多。
2. 三段式握手:8B/10B 字符、SYNC~ 与 ILA 到底在对什么
数据转换器和逻辑器件之间只连了几对差分线,却要传送几十路采样值,靠的是时间上的严格划分。链路从上电到跑通,要依次穿过代码组同步、初始通道对齐、配置参数交换三道关口,每一关检查的东西都不一样。这一章拆开这三关,看清每一关靠什么信号、判什么条件、失败时会发生什么。
2.1 第一比特为什么必须是控制字符:8B/10B 与逗号
8B/10B 这件事在 JESD204B 里不是可选项,它是链路能被建立起来的前提。编码把 8 位字节映射成 10 位码组,解决的是一组物理层问题:串行链路上长时间没有电平跳变,接收侧无从恢复时钟;数据里连续出现相同电平,交流耦合的电容会漂移。10 位码组在构造时限制了最长连 0 或连 1 不超过 5 位,跳变密度有保证,接收端只要一个能跑的锁相环,就能从数据流里把时钟抽出来。
更关键的是另一组东西:12 个控制字符。它们在编码表里与 256 个数据码组互斥,是协议层能“看见”的标记。JESD204B 在链路上跑了五个,各自的用途非常明确:
| 字符 | 编码名 | 8 位表示 | 在链路中的用途 |
|---|---|---|---|
| /K/ | K28.5 | 0xBC | 代码组同步,接收侧找字符边界 |
| /R/ | K28.0 | 0x1C | 初始通道对齐,把多条 lane 拉回同一相位 |
| /A/ | K28.3 | 0x7C | 多帧对齐,维持多帧周期 |
| /Q/ | K28.4 | 0x9C | 携带配置参数的起始标记 |
| /F/ | K28.7 | 0xFC | 帧对齐 |
/K/ 的特殊性在于它的位模式:RD 为负时是 0011111010,RD 为正时是 1100000101。这两个模式在其余所有码组里都不会出现,所以接收器可以拿一个 10 位窗口在比特流里一位一位地滑动,直到窗口内容命中这两个模式之一——字符边界就找到了。这个动作叫逗号对齐,是整条链路唯一一次“盲扫”,往后所有对齐都建立在这个字符栅格上。
注意:8B/10B 有 25% 的编码开销,链路预算里的线速率必须按有效数据率乘 1.25 来算。很多人第一次算线速率时忘了这一步,结果配出来的接收侧参数和发送侧对不上,卡在配置阶段。
因为同一个字符在 RD 为正和 RD 为负时对应两组不同的 10 位码组,接收器必须在解码时同步维护当前的 RD 值。RD 出错会导致解码表查错,一个字节变成另一个字节,但链路看起来还“通着”。这类问题最难查,因为 SYNC~ 不报警,数据也没有全错,只是偶发几位飘掉。
2.2 从 CGS 到 ILA 再到配置:一次链路建立到底会发生什么
链路建立的过程可以由一个状态机来描述,理解这个状态机,调试时就能判断当前卡在哪一步,而不是盯着“链路不通”干着急。
接收侧的 SYNC~ 是低电平有效的请求信号。上电后接收侧拉低 SYNC~,意思是“我还没同步,请给我送同步字符”。发送侧看到 SYNC~ 有效,就在链路上持续发送 /K/ 序列。接收侧在比特流里扫逗号、定字符边界,连续收到 4 个 /K/ 就认为代码组同步完成,释放 SYNC~。
释放之后进入初始通道对齐阶段。发送侧开始输出 /R/ 与 /A/,接收侧利用 /R/ 把每条 lane 的字符流各自做通道级对齐,再利用 /A/ 锁定多帧边界,确认每条 lane 落进同一个多帧序号。这一步决定了整条链路是“一条链路”还是“几条各跑各的线”。
对齐完成后进入配置阶段。发送侧发 /Q/ 起始标记,接着送出一串配置字节,包含 DID、L、F、K、M、CS、N、S、SUBCLASSV、CHKSUM 等字段。接收侧把这些参数读进本地寄存器,与自身预期的配置逐项比对,校验和通过才允许进入数据阶段。任何一项不一致,整条链路重新回到同步状态。
用一个简化的状态机骨架来刻画这个过程,比读文字描述更容易看出每个分支依赖什么条件:
# 接收侧同步状态机的骨架,只保留链路建立阶段的关键分支 # 控制字符按 8 位表示:/K/=0xBC /R/=0x1C /A/=0x7C /Q/=0x9C K_CODE = 0xBC R_CODE = 0x1C A_CODE = 0x7C Q_CODE = 0x9C def rx_link_fsm(char_stream, local_cfg): state = "CGS" # 代码组同步 comma_hits = 0 # 连续命中的逗号字符计数 cfg_bytes = [] # 从配置阶段收上来的参数 for ch in char_stream: if state == "CGS": if ch.is_control and ch.code == K_CODE: comma_hits += 1 if comma_hits >= 4: # 连续 4 个 /K/ 判定同步 state = "ILA" # 硬件上这一步就是把 SYNC~ 拉高 else: comma_hits = 0 # 任何一个非 /K/ 字符都会清零 elif state == "ILA": if ch.is_control and ch.code == R_CODE: align_lane(ch) # 用 /R/ 做通道级对齐 elif ch.is_control and ch.code == A_CODE: state = "CFG" # /A/ 确认多帧相位,进入配置 elif state == "CFG": if ch.is_control and ch.code == Q_CODE: cfg_bytes.clear() # /Q/ 之后开始收集参数 else: cfg_bytes.append(ch.value) if len(cfg_bytes) >= 14: # 参数区长度按配置字节数截断 if check_sum(cfg_bytes) and match_local(cfg_bytes, local_cfg): state = "DATA" else: state = "CGS" # 校验不过,回到起点重来 return state这段代码里有两个容易忽略的细节。第一个是comma_hits = 0的清零位置:标准的判据是连续命中,中间插进任何一个非 /K/ 字符都要重新计数,实际硬件里这个计数器还会被一个独立的定时器兜底,防止在噪声里无限等待。第二个是配置阶段失败后直接回到 CGS,而不是停在配置阶段重试——因为一旦参数不匹配,说明两端对链路的理解根本不同,重试没有意义,只能全链路复位让发送侧重新开始。
local_cfg是接收侧期望的参数集合,它必须和发送侧的配置完全一致。实践里最常见的失败原因是 F 和 K 这两个字段对不上:发送侧按 F=1 算帧长,接收侧按 F=2 收数据,校验和能过,逐项比对一定挂。所以调试时不要只看“配置阶段过没过”,要把收到的 14 个字节打印出来,和本地期望值逐字对照。
配置阶段通过之后,链路进入数据阶段,但 /A/ 并没有消失。每个多帧的固定位置仍然插入一个 /A/,接收侧持续用它监视多帧相位。一旦某个多帧周期里没在预期位置看到 /A/,说明相位漂了,链路重新同步。这就是为什么 JESD204B 链路在稳定运行中仍然有极小的概率自发重同步——它不是坏了,是相位监视机制在正常工作。
2.3 一条 lane 错位,整条链路重来
多通道的价值在于带宽,代价是对齐的刚性。所有 lane 上的数据必须落在同一个多帧边界上,接收侧才能把它们拼回一个有序的样本流。这个要求意味着:任何一条 lane 的相位偏差超过容限,整条链路都要重来。
偏差从哪来?最直接的是走线长度。假设线速率 5 Gbps,一个 10 位字符在差分对上占用 2 ns,PCB 上的信号传播速度大概 6.7 ps/mm,一个字符周期大约对应 30 cm 的走线差异。听上去很宽松,但实际板子上几条 lane 绕来绕去,两三厘米的差异很常见,再叠加连接器、过孔、封装内的差异,凑出一个字符的偏斜并不难。
偏斜本身不致命,致命的是它越过了对齐机制的调节能力。JESD204B 在接收侧为每条 lane 配了独立的弹性缓冲,可以吸收一定范围的到达时间差。但这个缓冲的深度和多帧周期挂钩,它能把偏斜“吸收”进一个多帧周期里,却不能把一条 lane 挪到上一个多帧。所以设计上有一条硬约束:所有 lane 的到达偏斜,必须小于一个多帧周期,工程上通常要求控制在一个字符周期以内,留足余量。
提示:布线阶段就把 lane 间的等长约束写进规则,别等打板回来再想办法。多帧周期可以调大来放宽这个约束,代价是延迟变大、缓冲变深,这一点在第 3 章讲 LMFC 时会展开。
除了板级偏斜,发送侧的通道相位也有影响。有些转换器内部各 lane 的串行化器存在固定相位差,需要靠寄存器里的通道相位调节来补偿。这类问题在眼图上完全看不出来,只能通过接收侧的 lane 对齐计数和弹性缓冲水位去判断。
3. 确定性延迟:SYSREF 凭什么把“不确定”变成“可算出来”
采样系统里有个比带宽更苛刻的需求:多片转换器之间的相对相位必须可复现。相控阵、多通道采集、测试仪器,失去的不只是精度,是系统能不能成立。JESD204B 相对 JESD204A 最重要的改动,就是提供了一套让链路延迟可编程、可复现的机制,这套机制的核心是 SYSREF 信号和子类(Subclass)的概念。
3.1 Subclass 0/1/2 的分水岭:延迟到底要不要可复现
协议定义了三个子类,它们不是兼容等级,而是三种不同的系统设计哲学。
Subclass 0 不要求确定性延迟。链路上没有 SYSREF,接收侧靠自己的本地时钟自由运行,数据什么时候从缓冲里出来取决于上电时刻的相位,两次上电的延迟完全不同。它适合单设备、对绝对延迟无所谓的场合,实现最简单,硬件成本最低。
Subclass 1 是工程里最常用的。系统里有一路 SYSREF 信号,它和器件时钟同源、低偏斜地分发到每一颗转换器和逻辑器件。SYSREF 的作用是给所有设备的本地多帧计数器一个共同的复位沿,让它们的相位关系固定下来。只要 SYSREF 的时序满足建立保持要求,每次上电复位后所有设备的 LMFC 相位就完全一致,链路延迟因此可复现、可计算。
Subclass 2 用 SYNC~ 本身来复位本地计数器,省掉 SYSREF 这根线。它能做到单条链路内的确定性延迟,但因为 SYNC~ 是各链路各自拉低的,无法保证多条链路之间相位一致,所以不支持多设备同步。
三者的差别可以用一张表说清楚:
| 子类 | 确定性延迟 | 多设备同步 | 依赖信号 | 典型场景 |
|---|---|---|---|---|
| Subclass 0 | 不支持 | 不支持 | 仅器件时钟 | 单通道、延迟不敏感 |
| Subclass 1 | 支持 | 支持 | 器件时钟 + SYSREF | 多 |
本文还有配套的精品资源,点击获取