第3章:链路层详解:帧结构与多链路
链路层是JESD204B三层的中间层,也是我最花功夫去抠细节的一层。底层物理层只管串行比特流,应用层只管数据内容,链路层则负责把比特流拼成有意义的帧,再送给应用层去解包。
说白了,这一层决定了你的数据怎么切、怎么对齐、怎么跨链路。我在调试第一个JESD204B项目时,80%的波形时间都用在了观察帧边界上。
3.1 帧结构基础
先明确两个最基础的概念:octet(8bit字节)和frame(帧)。链路层的最小单位是octet,一串连续octet组成一个帧。帧大小由参数F定义,F的值在链接建立时就约定好了。
举个例子。F=4表示每个帧包含4个octet。那么发送端每攒够4个octet就组成一个帧,打上帧边界标志,送给物理层。接收端则靠同步机制找到边界,从比特流里提取出一个个帧。
帧边界靠什么找?
靠初始帧同步序列,也就是ILAS阶段发的特定码组。说白了,接收端先锁定码组,再按F字节对齐。我在实验室里用逻辑分析仪抓过无数次波形,最怕的就是接收端不停丢帧锁定信号——一查,往往是F参数配错了。
帧结构里还有另一个重要参数K,它指定每帧包含多少个控制字节。通常K=0表示纯数据帧,但实际项目中K≥1的情况很常见,因为需要带控制字或校验信息。
3.2 多链路映射(Multi-Link)
JESD204B支持一条或多条物理链路。链路数用参数L表示。L=1就是单链路,L=2或L=4就是多链路。多链路的目的是提高总带宽,但代价是复杂度成倍增加。
多链路映射规则说简单也简单:每个octet按顺序循环分配到各条链路上。比如L=2,那么第1个octet分配给链路0,第2个octet分配给链路1,第3个octet又给链路0,以此类推。
注意这里有个坑:多链路必须保持帧对齐。每条链路的帧边界必须严格对齐,否则接收端会把不同链路的帧混在一起,数据根本解不出来。
⚠️ 我曾经在一个L=4的项目中忘记配置链路间帧对齐时序,结果接收端一直报"FRAME_ALIGN_ERROR"。查了三天才发现是FPGA逻辑里多了一条多余的流水线延迟,导致一条链路慢了1个frame clock。从此我对多链路对齐的时序检查格外小心。
多链路还有个小细节:SCR(加扰使能)必须在所有链路上保持一致。一条加扰一条不加扰,接收端会疯掉。
3.3 加扰器原理
加扰是可选功能,由参数SCR控制。加扰器使用LFSR(线性反馈移位寄存器)生成伪随机序列,与发送数据异或后输出。标准规定加扰多项式为 1 + x^14 + x^15。
为什么要加扰?两个目的:
- 避免长连0或长连1,保证时钟恢复
- 减少EMI,让频谱更平坦
加扰器在发送端每个帧的起始位置复位一次。复位值是全1(0xFFFF)。我见过有人为了方便直接给全0,结果接收端加扰后的数据完全错位。嗯,改回全1复位就好了。
💡 调试小技巧:在ILAS阶段关闭加扰,用已知码型验证链路稳定性。等链路锁定后再打开加扰,可以快速判断加扰逻辑是否有问题。
3.4 ILAS与帧同步过程
链路启动分为三个阶段:CGS(码组同步)→ ILAS(初始链路对齐序列)→ 用户数据。
CGS阶段接收端只找连续4个逗号字符(K28.5),找到了就初步同步。ILAS阶段则会发送4个多帧,每个多帧携带配置参数(F、K、L等)和帧对齐信息。
ILAS最关键的是帧对齐信号(FAS)。接收端从ILAS中提取FAS后,才能知道用户数据帧从哪里开始。我在项目里踩过的一个坑是:ILAS阶段发送的F字节数必须和用户数据阶段完全一致,否则接收端根本进入不了数据状态。
| 阶段 | 目的 | 关键参数 | 常见问题 |
|---|---|---|---|
| CGS | 码组锁定 | 逗号字符 | 误检/漏检 |
| ILAS | 配置传递+帧对齐 | F, K, L, SCR | 参数不匹配导致挂死 |
| 用户数据 | 正常传输 | F, K | 帧边界漂移 |
3.5 多链路应用实践
实际项目中,多链路常用于高采样率ADC或DAC。比如16位4通道ADC,单链路带宽不够,就用L=2把数据分到两条链路上。我做过的一个12Gbps项目,L=4才跑满带宽。
设计多链路时重点检查以下几点:
- 链路间延迟差:每条链路的电路板走线长度要尽量等长,FPGA内部要加可调延迟对齐
- 帧时钟同源:所有链路的frame clock必须从同一PLL产生,否则无法对齐
- 接收端缓冲:每条链路独立做弹性缓冲,再统一输出
多链路的测试思路
先单链路调通,再逐步增加链路数。每条链路单独验证CGS和ILAS通过后,再合起来看数据一致性。我在调试AD9680时就是这么干的,一步一脚印,省了很多弯路。
3.6 常见错误与排查
- 无法进入CGS:检查差分信号质量、GT复位顺序、逗号字符极性
- ILAS失败:核对发送端和接收端的F、K、L参数是否完全一致
- 帧不对齐:多链路场景,检查每条链路延迟差是否在允许范围内
- 数据错乱:加扰器复位值、多帧周期K值是否一致