SerDes基础原理:PCS层与PMA层架构解析
各位同学,今天咱们来聊聊SerDes的核心架构。说实话,我刚接触SerDes那会儿,也被PCS和PMA这两个缩写搞得晕头转向。后来在项目中调了整整两周的误码率,才真正搞明白这两层到底在干什么。
SerDes,说白了就是串行器/解串器。它的任务很简单:把并行数据转成串行数据发出去,再把收到的串行数据转回并行。但真正实现起来,里面的门道可不少。
PMA层:物理介质适配层
PMA层是SerDes的最底层,直接跟物理介质打交道。我习惯把它比作「信号收发器」——负责把数字信号变成模拟信号,再通过差分对传出去。
PMA层主要干这几件事:
- 串行化/解串:把并行数据转成串行比特流,反过来也一样
- 时钟恢复(CDR):从接收到的数据流里提取时钟信号
- 预加重/均衡:补偿高频信号在传输线上的衰减
- 差分驱动:用差分信号驱动物理链路
嗯,这里要注意。PMA层的CDR电路是个关键点。我曾经在一个项目中,因为PCB走线阻抗不匹配,导致CDR锁不住时钟,误码率直接飙到10⁻⁴。后来加了预加重,才把误码率压到10⁻¹²以下。
核心要点:PMA层处理的是模拟信号,对PCB布局、电源噪声、参考时钟抖动都非常敏感。我建议在设计阶段就留出足够的裕量。
PCS层:物理编码子层
PCS层在PMA层之上,负责数据的编码、解码和链路管理。你想想看,如果直接把原始数据扔给PMA层发出去,接收端怎么知道数据从哪里开始?怎么保证DC平衡?这些问题就是PCS层要解决的。
PCS层的主要功能包括:
- 8B/10B或64B/66B编码:保证DC平衡,提供时钟恢复所需的跳变
- 通道绑定:把多个SerDes通道绑定成一个逻辑通道
- 链路初始化与训练:建立收发双方的同步
- 错误检测:通过编码规则检测传输错误
我个人习惯把PCS层看作「数据包装工」——它给原始数据加上各种标记,让接收端能正确解读。
8B/10B编码原理
8B/10B编码,说白了就是把8位数据映射成10位码字。为什么要多出2位?为了DC平衡和时钟恢复。
编码规则其实不复杂:
- 把8位数据分成5位和3位两部分
- 5位部分用5B/6B编码,3位部分用3B/4B编码
- 每个码字保证0和1的数量差不超过2
- 通过「运行差异度(RD)」控制极性
举个例子,数据0x00(8'b0000_0000)编码后变成10'b100111_0100或10'b011000_1011,具体用哪个取决于当前的RD值。
实战技巧:我在调试8B/10B链路时,习惯先检查RD值是否在正常范围内。如果RD值持续偏离,说明链路可能有误码。
8B/10B编码有个明显的缺点——开销太大。25%的带宽浪费在编码上。所以后来出现了64B/66B编码。
64B/66B编码原理
64B/66B编码只用了2位同步头,就把64位数据包起来了。开销只有3.125%,比8B/10B高效得多。
编码规则是这样的:
- 每64位数据前加2位同步头
- 同步头「01」表示数据块,「10」表示控制块
- 数据块直接透传64位数据
- 控制块包含8位块类型字段和56位控制信息
你可能会问:只有2位同步头,怎么保证DC平衡?其实64B/66B不保证DC平衡,它靠加扰器来解决这个问题。数据先经过一个自同步加扰器,再发送出去。
注意:64B/66B编码的同步头只有2位,如果连续出现误码,很容易造成同步丢失。我曾经遇到过因为电源纹波过大,导致同步头频繁出错,整个链路反复重训练。后来在电源上加了个LC滤波器才解决。
两种编码的对比
| 特性 | 8B/10B | 64B/66B |
|---|---|---|
| 编码效率 | 80% | 96.875% |
| DC平衡 | 保证 | 靠加扰器 |
| 时钟恢复 | 容易 | 需要加扰 |
| 实现复杂度 | 低 | 中 |
| 典型应用 | PCIe Gen1/2, SATA | 10G Ethernet, PCIe Gen3+ |
从表中能看出来,8B/10B适合低速场景,实现简单。64B/66B适合高速场景,效率更高。我建议初学者先从8B/10B入手,搞懂了再学64B/66B。
PCS与PMA的协同工作
这两层是怎么配合的?我画了个简单的流程图来说明:
从图上能看出来,数据在发送端先经过PCS层编码,再交给PMA层串行化发送。接收端反过来,PMA层先恢复时钟和解串,再把数据交给PCS层解码。
这里有个容易踩的坑:PCS层和PMA层之间的接口时序。我见过不少工程师把这两层的时钟域搞混了。PCS层通常用并行时钟,PMA层用串行时钟,中间需要做跨时钟域处理。
避坑指南:我曾经在一个项目中,PCS层输出数据给PMA层时,没做FIFO缓冲。结果因为时钟相位偏差,偶尔丢数据。后来加了个异步FIFO,问题就解决了。记住,跨时钟域一定要用FIFO或握手信号。
好了,PCS层和PMA层的基本架构就讲到这里。这两种编码方式各有千秋,选哪种取决于你的应用场景。低速链路用8B/10B,简单可靠;高速链路用64B/66B,效率更高。