二、SerDes系统架构:PMA、PCS、MAC层关系
做SerDes设计这些年,我经常被问到一个问题:PMA、PCS、MAC这三层到底是怎么分工的?说实话,我刚入门那会儿也经常搞混。你以为PMA只管模拟、PCS只管数字?嗯,实际情况要复杂得多。今天咱们就把它彻底拆干净。
2.1 标准的三层架构
任何一个完整的SerDes链路,从MAC到物理介质,都会经过三个功能层:
| 层级 | 全称 | 核心职能 | 典型接口 |
|---|---|---|---|
| MAC | Media Access Control | 数据封装、流控、寻址 | GMII / XGMII |
| PCS | Physical Coding Sublayer | 编解码、对齐、扰码 | PCS服务接口 |
| PMA | Physical Medium Attachment | 串行化、时钟恢复、驱动 | SerDes模拟接口 |
你可能在芯片手册里见过类似的分层图。我个人的理解是:MAC负责“会说话”,PCS负责“把话编成对方听得懂的暗号”,PMA负责“把暗号喊出去”。三层缺一不可。
关键认知:这三层之间是“服务+接口”的关系,不是简单的黑盒嵌套。PCS向上对MAC暴露数据通路,向下对PMA发送并行码字。
2.2 每一层到底干了什么?
MAC层——协议的大脑
MAC层做的是帧级别的处理。比如说以太网MAC会加前导码、帧起始定界符、CRC32校验。我在一个10G项目里遇到过MAC侧给的时钟域和PCS侧完全异步,结果PCS侧怎么都抓不到有效帧头。后来加了个弹性缓冲才解决。说白了,MAC和PCS之间的时钟容差,你得在设计时就预留好。
- 数据封装:添加/剥离帧头、帧尾
- 流量控制:Pause帧、Credit机制
- 地址过滤:只接收目标地址匹配的帧
- 错误检测:CRC32或FCS
PCS层——数字的枢纽
PCS是SerDes里最“累”的一层。它要把MAC来的并行数据变成线路上适合传输的格式。我曾经调试过一个25G链路,眼图一直睁不开,折腾了两周才发现是PCS里的扰码器多项式配错了,导致频谱能量集中在低频段。你想想看,这种bug用仿真都不好抓。
PCS的主要工作包括:
- 64B/66B或8B/10B编码:保证直流平衡、提供时钟信息
- 扰码:打散长连0/1,减少EMI
- 对齐标记插入:多通道时做lane deskew
- 同步头检测与锁定:识别码字边界
- RS-FEC编码/解码:前向纠错(部分设计)
小提示:PCS设计的难点不在于单个功能,而在于所有功能要在同一个时钟域里流水起来,而且延迟要可预测。我建议你一开始就把流水线级数用寄存器配成可调,后面调试会省很多事。
PMA层——模拟的硬仗
PMA是离物理介质最近的一层。它做两件核心事:并串转换和时钟数据恢复(CDR)。我曾经参与过一个28nm的16Gbps项目,PMA的CDR锁定范围调小了,低温下相位裕量不够,比特误码率直接到10⁻⁴。最后只能改版重流……嗯,从那之后我每次签PMA的CTS(时钟树综合)都会反复确认锁定窗口。
- Serializer / Deserializer:并行→串行 / 串行→并行
- 时钟生成:PLL / DLL
- 时钟数据恢复:相位插值器或Bang-Bang型CDR
- 线路驱动/均衡:TX的预加重、RX的CTLE/DFE
- 阻抗校准:匹配50Ω或100Ω
2.3 三层之间的接口信号
这是很多人容易忽略的——层间接口定义直接决定了你的设计能不能和别人的IP对接。以最常见的XGMII扩展千兆媒体独立接口为例:
| 接口 | 位置 | 数据宽度 | 时钟 | 特点 |
|---|---|---|---|---|
| MAC ↔ PCS | XSBI / XGMII | 32位或64位 | DDR或SDR | 需要FIFO缓冲CDC |
| PCS ↔ PMA | PMA服务接口 | 10/20/40位 | 线路速率/n | 一般是源同步时钟 |
| PMA ↔ 介质 | 模拟差分对 | 1位 | 嵌入时钟 | AC耦合电容 |
注意这里的PCS到PMA接口宽度,说白了就是编码后的码字宽度。比如8B/10B编码后是10位,64B/66B编码后是66位。我把这个接口的时序额外加了两级寄存器做retiming,就是因为有一次在量产测试时发现布线延迟超标导致setup违例。
避坑:MAC和PCS之间的时钟域交叉,不要直接用双触发同步。一定要用异步FIFO,并且FIFO深度要能容忍最差情况的时钟频率偏移。我曾经见过有人偷懒只用了4深度的FIFO,结果板级跑5分钟就丢包——这属于低级错误。
2.4 三者关系的一张图
下面这张SVG图展示了从MAC到物理介质的完整数据流向,以及各层之间的关键接口。你可以看到PCS处于承上启下的位置,左边连着协议世界,右边连着模拟世界。
读图要点:注意PCS层有两组箭头——一组向上与MAC交互,一组向下与PMA交互。PCS是唯一同时处理协议级和物理级逻辑的层次,所以它的设计最脆弱,也最容易出bug。
2.5 实际项目中的层间配合
我给你讲个真实案例。某次多通道SerDes芯片调试,PCS输出端对齐标记一直插错位置,导致接收端无法做lane deskew。我排查了三天,最后发现是PCS在初始化阶段没有正确等待PMA的锁相环锁定信号。说白了,就是层间握手时序没做对。我跟团队定了一条规矩:所有层间状态机必须用valid-ready握手,不能用固定延迟假设。
另一个常见问题是:很多人觉得PMA是模拟工程师的事,PCS是数字工程师的事,结果两边接口定义留了二义性。比如PMA给PCS的时钟是线速率的1/N,但N到底取多少,文档没写清楚。我建议在项目一开始就出一张层间接口定义表,包括信号名、方向、位宽、时钟域、极性、时序要求。这张表要由PCS和PMA两边共同签字。
重要:千万不能用空口协商的方式决定层间接口——比如“PMA给PCS一个大概的时钟”。数字RTL一旦按某个时钟周期写好,后面模拟改一点,整个PCS都得重综合。我吃过这个亏,一次改版多花了三个月。
2.6 简化设计中的层合并
有些低功耗或低成本应用会把PCS和PMA合并成一层。比如USB3.0的PHY,PCS和PMA往往集成在一个硬核里。这时候你拿到的接口直接就是MAC级的。但我始终觉得:理解完整分层,你才懂得硬核里面到底封了什么。不然你连signal integrity出了问题该找谁都不知道。
我个人习惯,哪怕是集成的硬核PHY,我也会要求厂商提供PCS和PMA的分离文档。你想想看,线路上眼图不好,到底是TX的预加重强度不够,还是PCS的扰码没开?分不清楚就没法定位。
2.7 一张表串起全流程
咱们把从MAC发出数据到PMA发送到线上的完整流程列一下,方便你后面查漏:
| 步骤 | 所在层 | 操作 | 输出 |
|---|---|---|---|
| 1 | MAC | 封装帧(加前导、目标地址等) | 并行数据+帧有效信号 |
| 2 | MAC→PCS | 跨时钟域FIFO写入 | 异步FIFO |
| 3 | PCS | 64B/66B编码(或8B/10B) | 编码码字 |
| 4 | PCS | 扰码(X⁵⁸+X³⁹+1等多项式) | 加扰码字 |
| 5 | PCS | 插入对齐标记(每16384个码字一次) | 含对齐标记的码流 |
| 6 | PCS→PMA | 并行接口输出(如66位) | 并行码字+同步时钟 |
| 7 | PMA | Serializer(并转串) | 高速串行数据 |
| 8 | PMA | 预加重/去加重 | 整形后的模拟信号 |
| 9 | PMA→介质 | CML驱动输出到PCB走线 | 差分对信号 |
反过来,接收方向就是完全逆过程:PMA的CDR先恢复时钟和串行数据,Deserializer转成并行,交给PCS做解码、解扰、对齐检测,最后通过FIFO返回MAC。
总结三层关系:MAC决定发什么,PCS决定怎么编码发,PMA决定用什么电信号发。三层环环相扣,任何一层的失误都会在误码率上暴露出来。