4. SerDes技术详解:SerDes架构(PCS+PMA)、8B/10B与64B/66B编码、时钟恢复(CDR)、预加重与均衡、SerDes通道建模
SerDes,说白了就是串行器/解串器。我做了这么多年高速接口设计,可以负责任地告诉你:SerDes是FPGA连接外部世界的咽喉。没有它,你的FPGA就只能跟板子上的其他芯片慢吞吞地握手。
这一章,咱们把SerDes的里里外外掰开揉碎。从架构到编码,从时钟恢复到信号补偿,再到通道建模——嗯,都是硬菜。
4.1 SerDes架构:PCS与PMA的分工
一个完整的SerDes,内部其实分两大块:PCS(物理编码子层)和PMA(物理介质接入子层)。我习惯把PCS比作“翻译官”,PMA比作“搬运工”。
- PCS:负责数据编码、解码、对齐、加扰。它处理的是数字逻辑。
- PMA:负责串行化、解串行化、时钟生成、时钟恢复。它处理的是模拟信号。
为什么这么分?因为数字逻辑和模拟电路的设计思路完全不同。PCS可以用标准单元库综合,PMA却需要定制化的模拟电路。我在项目中遇到过,有人把PCS和PMA混在一起设计,结果时序收敛困难,信号质量也一塌糊涂。
下面这张图,是我自己画的一个典型SerDes架构框图。你可以看到数据从FPGA逻辑出发,经过PCS编码,再交给PMA串行发送出去。接收端则是逆过程。
4.2 8B/10B与64B/66B编码
编码这玩意儿,说白了就是给数据加点“冗余”,让接收端能更好地恢复时钟和识别数据边界。
4.2.1 8B/10B编码
8B/10B编码,把每8位数据映射成10位码字。多出来的2位用来保证DC平衡(即0和1的数量尽量相等)和提供足够的跳变沿。
- DC平衡:避免信号长时间处于同一电平,防止接收端耦合电容充电饱和。
- 游程长度控制:连续相同比特不超过5个,保证CDR能持续锁定。
- 特殊码字(K码):用于帧对齐、空闲填充、时钟补偿。
4.2.2 64B/66B编码
64B/66B编码,效率提升到了97%。每64位数据块前面加2位同步头(Sync Header),用来标识数据块类型。
| 编码方式 | 效率 | 同步头 | DC平衡 | 典型应用 |
|---|---|---|---|---|
| 8B/10B | 80% | 无(靠K码) | 好 | PCIe Gen1/2, SATA, USB 3.0 |
| 64B/66B | 97% | 2位 | 需加扰 | 10G Ethernet, PCIe Gen3+ |
64B/66B需要配合加扰器(Scrambler)来保证DC平衡。加扰器用伪随机序列对数据进行异或处理,让数据看起来更“随机”。
4.3 时钟恢复(CDR)
CDR,全称Clock Data Recovery。它的任务是从串行数据流中提取出时钟信号。为什么需要CDR?因为发送端和接收端没有独立的时钟连线,接收端必须自己从数据里“挖”出时钟。
CDR的核心是一个锁相环(PLL)。它通过比较数据跳变沿和本地时钟的相位差,不断调整时钟频率和相位,最终锁定在数据速率上。
我常用的CDR架构有两种:
- 基于PLL的CDR:经典结构,锁定范围宽,但锁定时间较长。
- 基于相位插值器的CDR:锁定速度快,适合突发模式,但抖动性能稍差。
4.4 预加重与均衡
信号在PCB走线上传输,高频分量衰减比低频严重。这就导致信号的眼图闭合,误码率上升。预加重和均衡,就是用来补偿这种频率相关损耗的。
4.4.1 预加重(发送端)
预加重在发送端做。它在信号跳变时,额外增加一个幅度尖峰,补偿高频衰减。说白了,就是“先打一针强心剂”。
- 预加重系数:通常用百分比表示,比如3dB预加重。
- 预加重阶数:1阶、2阶、3阶。阶数越高,补偿越精细。
4.4.2 均衡(接收端)
均衡在接收端做。它用一个高通滤波器来提升高频分量。常见的均衡器有:
- CTLE(连续时间线性均衡器):模拟电路,功耗低,但补偿能力有限。
- DFE(判决反馈均衡器):数字电路,补偿能力强,但会放大噪声。
4.5 SerDes通道建模
通道建模,就是预测信号从发送端到接收端会经历什么。我常用的工具是IBIS-AMI模型和SPICE仿真。
通道模型包含以下几个部分:
- 发送端模型:包括输出阻抗、预加重、抖动。
- 通道模型:包括PCB走线、过孔、连接器、电缆。用S参数描述。
- 接收端模型:包括输入阻抗、均衡器、CDR。
下面是一个简单的通道仿真代码示例,用Python模拟一个带损耗的通道:
import numpy as np
import matplotlib.pyplot as plt
# 通道参数
f = np.linspace(0, 10e9, 1000) # 频率范围 0-10GHz
loss_dB_per_m = 0.1 * np.sqrt(f / 1e9) # 每米损耗,单位dB
length = 0.5 # 通道长度,单位米
# 通道传递函数
H = 10 ** (-loss_dB_per_m * length / 20)
# 绘制通道响应
plt.plot(f / 1e9, H)
plt.xlabel('频率 (GHz)')
plt.ylabel('幅度')
plt.title('通道频率响应')
plt.grid(True)
plt.show()
嗯,SerDes的内容就讲到这里。从架构到编码,从CDR到均衡,再到通道建模——每一个环节都是环环相扣的。你想想看,一个高速信号从FPGA出发,经过编码、串行化、预加重,穿过PCB走线,再经过均衡、CDR、解码,最终回到FPGA逻辑——这中间任何一个环节出问题,链路就挂了。
所以,做SerDes设计,一定要有全局观。不要只盯着某一个模块,要把它当成一个系统来看。
公众号:蓝海资料掘金营,微信deep3321