2. SerDes核心架构:PCS层与PMA层划分
SerDes这玩意儿,说白了就是把并行数据转成串行,再在接收端转回来。但真正做起来,远没这么简单。我刚开始接触SerDes时,总觉得不就是个并串转换嘛,后来被现实狠狠教育了一顿——高速信号的眼睛图、抖动、误码率,哪个都不是省油的灯。
SerDes的架构,业界普遍分成两层:PCS(物理编码子层)和PMA(物理介质接入层)。这两层分工明确,各管一摊。
2.1 PCS层与PMA层的职责划分
PCS层主要负责数字逻辑处理,PMA层则处理模拟信号。你想想看,数字域和模拟域天生就是两路人,硬凑在一起反而麻烦。
| 层级 | 主要职责 | 典型模块 |
|---|---|---|
| PCS | 数据编码/解码、对齐、加扰/解扰、弹性缓冲 | 8B/10B编码器、CRC、FIFO |
| PMA | 并串转换、时钟生成与恢复、信号均衡 | Serializer、PLL、CDR、Equalizer |
我个人习惯把PCS看作"协议翻译官",PMA则是"信号搬运工"。PCS把上层协议的数据包翻译成物理层能理解的码流,PMA则负责把这些码流高速地扔到线上去。
关键点:PCS和PMA之间的接口通常是并行数据总线,宽度取决于SerDes的通道数。比如一个16:1的SerDes,PCS输出16位并行数据给PMA,PMA再串化成1位高速信号。
2.2 发送端架构
发送端,就是数据从芯片内部走向外部的那条路。我做过一个项目,发送端时钟抖动了几个皮秒,结果整个链路误码率直接爆表。嗯,这里要注意,发送端的每个模块都可能成为瓶颈。
2.2.1 Serializer(并串转换器)
Serializer的核心任务很简单:把N位并行数据转成1位串行数据。但实现方式有讲究。
常见的Serializer结构有两种:
- 树形结构:多级2:1 MUX级联,面积小,但时序收敛难
- 移位寄存器结构:用移位寄存器加载并行数据再串行输出,时序好控制,但功耗高
我建议在高速场景(>10Gbps)用树形结构,低速场景用移位寄存器。为什么?树形结构的关键路径更短,能跑更高频率。
// 简单的2:1 Serializer Verilog示例
module serializer_2to1 (
input clk_half, // 半速率时钟
input clk_full, // 全速率时钟
input [1:0] data_in,
output reg data_out
);
always @(posedge clk_full) begin
data_out <= clk_half ? data_in[1] : data_in[0];
end
endmodule
实战技巧:Serializer的时钟树设计很关键。我曾经遇到过因为时钟偏斜导致数据错位的问题,后来在布局时强制让时钟路径等长,问题就解决了。
2.2.2 FIFO(异步 FIFO)
FIFO在SerDes里扮演着"缓冲器"的角色。PCS层和PMA层工作在不同的时钟域——PCS用系统时钟,PMA用PLL生成的串行时钟。这两个时钟频率不完全同步,就需要FIFO来跨时钟域。
FIFO的深度怎么定?我一般按这个公式估算:
FIFO深度 = (|f1 - f2| / f1) * 最大数据包长度 * 安全系数
安全系数我通常取1.5到2。太小了会溢出,太大了浪费面积。
注意:FIFO的空满标志生成一定要用格雷码指针。二进制指针跨时钟域时会产生亚稳态,格雷码每次只变化1位,能有效降低亚稳态概率。这个坑我踩过,流片回来发现FIFO偶尔读空,查了两个月才发现是指针同步的问题。
2.2.3 PLL(锁相环)
PLL是发送端的"心脏",它负责生成高速串行时钟。没有PLL,Serializer就没法工作。
PLL的核心指标:
- 抖动(Jitter):RMS抖动要小于0.01UI(单位间隔)
- 锁定时间:一般要求小于100μs
- 频率范围:要覆盖协议要求的所有速率
我记得有一次做MIPI D-PHY,PLL的环路带宽设得太宽,结果电源噪声全耦合进来了,眼图惨不忍睹。后来把带宽压到500kHz以下,才勉强通过一致性测试。
2.3 接收端架构
接收端比发送端难做得多。发送端是自己控制信号,接收端面对的是经过信道衰减、噪声污染的"残废"信号。说白了,接收端要做的是"从垃圾里淘金"。
2.3.1 CDR(时钟数据恢复)
CDR是接收端最核心的模块。它要从数据信号里提取出时钟,再用这个时钟去采样数据。没有CDR,接收端就是瞎子。
CDR的架构主要有三种:
- 基于PLL的CDR:用鉴相器比较数据边沿和本地时钟相位,反馈调整VCO
- 基于DLL的CDR:用延迟锁定环调整采样时钟相位
- 基于过采样的CDR:用多相位时钟对数据过采样,再选择最佳采样点
我个人偏好基于PLL的CDR,锁定速度快,抖动性能好。但要注意,CDR的环路带宽要和数据速率匹配。带宽太宽,噪声抑制差;带宽太窄,跟踪不上频率变化。
经验值:CDR环路带宽一般设为数据速率的1/1000到1/500。比如10Gbps的数据,环路带宽设在10-20MHz比较合适。
2.3.2 Deserializer(串并转换器)
Deserializer是Serializer的逆过程,把1位串行数据转成N位并行数据。实现上通常用移位寄存器加计数器控制。
// 简单的1:8 Deserializer示例
module deserializer_1to8 (
input clk_ser, // 串行时钟
input clk_par, // 并行时钟
input data_in,
output reg [7:0] data_out
);
reg [2:0] bit_cnt;
reg [7:0] shift_reg;
always @(posedge clk_ser) begin
shift_reg <= {shift_reg[6:0], data_in};
bit_cnt <= bit_cnt + 1;
if (bit_cnt == 3'd7) begin
data_out <= shift_reg;
end
end
endmodule
Deserializer的关键是字对齐。串行数据流里没有明确的字边界,需要靠PCS层的对齐码来找到起始位置。我见过一个设计,Deserializer的字对齐逻辑写错了,导致接收到的数据全是错位的,调试了整整一周。
2.3.3 Equalizer(均衡器)
Equalizer是接收端的"救火队员"。高速信号经过PCB走线、连接器、电缆后,高频分量会被严重衰减,导致码间干扰(ISI)。Equalizer的作用就是补偿这种衰减。
常见的均衡器类型:
| 类型 | 原理 | 适用场景 |
|---|---|---|
| CTLE(连续时间线性均衡器) | 模拟滤波器,提升高频增益 | 中等损耗信道(<20dB) |
| DFE(判决反馈均衡器) | 数字反馈,消除后标ISI | 高损耗信道(>20dB) |
| FFE(前馈均衡器) | 数字前馈,消除前标ISI | 通常与DFE配合使用 |
我建议在SerDes设计里至少包含CTLE+DFE的组合。CTLE做粗调,DFE做细调。曾经有个项目,信道损耗达到30dB,只用CTLE根本打不开眼图,加上4阶DFE后,眼高从0提升到了200mV。
调试心得:Equalizer的系数自适应算法很关键。我一般用LMS(最小均方)算法来更新系数,收敛速度快,实现也简单。但要注意步长参数的选择——步长太大,系数震荡;步长太小,收敛太慢。
2.4 本章知识体系
下面这张图展示了SerDes核心架构的整体脉络,从发送端到接收端,每个模块各司其职:
这张图把发送端和接收端的模块关系画得很清楚。左边是发送端,PCS层处理完数据后,经过FIFO缓冲,送到Serializer串化,PLL提供高速时钟。右边是接收端,信号先经过Equalizer补偿信道损耗,CDR恢复时钟,Deserializer把串行数据转回并行,最后交给PCS层处理。
整个SerDes的设计,说白了就是要在功耗、面积、性能三者之间找平衡。我做了这么多年,最大的体会是:没有完美的架构,只有最适合当前应用场景的方案。比如MIPI D-PHY追求低功耗,PCIe追求高性能,USB追求兼容性——设计思路完全不同。
避坑指南:我曾经在一个项目中,为了省面积把FIFO深度从16减到8,结果在极端频率偏差下频繁溢出,导致链路中断。后来老老实实改回16,再也没出过问题。有些地方,真的不能省。
公众号:蓝海资料掘金营,微信deep3321