IEEE Std 802.3-2022 在 49章,介绍了10GBASE-R的PCS(Physical Coding Sublayer,物理编码子层)64b/66b原理。
下面这几个 10G 以太网物理层变种均使用该同步头:
10GBASE-SR(多模光纤,短距离)
10GBASE-LR(单模光纤,中距离)
10GBASE-ER(单模光纤,长距离)
10GBASE-LRM(老的多模光纤)
10GBASE-KR(背板铜缆,数据中心内部)
10GBASE-T 是 IEEE 802.3 标准中定义的 10 Gbit/s 以太网通过双绞铜缆(即普通网线)传输 的物理层规范,简单说就是“10G 铜缆以太网”。
PCS在Tx方向将用户数据进行加扰,添加同步头后送往PMA,在Rx方向接收PMA的数据,进行同步并去掉同步头,然后解扰恢复出并行数据送给MAC层,数据流向如下:

GEAR BOX可以理解为“变速箱”,用来做速率匹配。因为输入数据是64bit,输出数据为66bit,每隔32clk就会多出一拍数据。
PCS中的数据在PMA中做并串和串并转换,低bit先发送:

前面说到,PCS将用户数据(如XGMII)从32/64bit位宽转换成66bit。为什么是 66 位?因为前 2 位是“同步头”(sync header),后面 64 位是实际负载,所以叫 64B/66B。前 2 位的同步头用于快速锁定边界,这些数据块只在 PCS 内部存在,外面完全看不到(不感知这个同步头),具体怎么转全看 49.2.4 的编码表。这就是为什么 10GBASE-R能做到极低的编码开销(66/64 = 1.03125,仅 3.125% 开销),远比 1000BASE-X 的 8B/10B(25% 开销)高效得多。
64B/66B编码要做到:
编码必须保证比特流里有很多 0↔1 的跳变(high transition density)。
为什么?因为接收端没有单独的时钟线,全靠从数据里自己“抠”出时钟(Clock Data Recovery, CDR)。跳变得少,CDR 就漂移、失锁。
有限连 0/连 1 长度(run-length-limited):
最长连续 0 或 1 不会超过某个值(64B/66B 加上扰码后,最长跑长大概 66 左右),避免基线漂移(DC wander)和电磁干扰问题。
快速同步
每个 66 位块前 2 位的同步头,让接收端能在几百比特之内就找到“块边界在哪里”,这叫 Block Lock。 找到边界之后,后面的解码、解扰、错误检查就全都能对齐了。
编码规则如下图:

一个 66-bit 块 = 连续两个 XGMII 周期的 8 个字符 XGMII 是双 32-bit(4 字节 × 2 路),两个周期正好 8 字节 → 打包成一个 66-bit 块。
8 个字符的编号规则
D0 D1 D2 D3 D4 D5 D6 D7 → 纯数据八字节
C0–C7 → 普通控制字符(比如 Idle、Error)
S0 或 S4 → Start(帧起始),只能出现在第 1 或第 5 个位置(对应 XGMII 的 lane 0)
T0–T7 → Terminate(帧结束),可以出现在任意位置
O0 或 O4 → Ordered_set(比如 /LPI/、/LF/、/RF/),也只能出现在第 1 或第 5 个位置
下标 0~3 属于第一个 XGMII 周期,4~7 属于第二个周期。
块格式只有两大类
同步头 = 01 → 纯数据块:01 + 8 个 D0~D7
同步头 = 10 → 控制块:10 + 8-bit 块类型字段(block type field)+ 若干控制字符/数据混合
XGMII接口66B编码举例:
场景一:纯数据传输 (Data Block)
XGMII 状态: 正在传输一个大文件的中间部分。
输入: 8 个字节全是数据,XGMII 的控制位(TXC)全是 0。
数据内容:11 22 33 44 55 66 77 88 (16进制)
查表: 对应表格第一行 D0 D1 D2 D3 D4 D5 D6 D7。
编码结果:
Sync: 01
Payload: 直接就是 11 22 33 44 55 66 77 88
最终 66B: 01 11 22 33 44 55 66 77 88
场景二:数据包开始 (Start of Packet)
以太网规定,数据包必须从第 0 通道 或第 4 通道 开始。
XGMII 状态: 开始发送一个新包。
输入: 第 1 个字节是 /S/ (Start),后面 7 个字节是前导码/SFD/MAC地址数据。
XGMII 数据: FB 55 55 55 55 55 55 D5 (FB 是 Start 的控制码)
XGMII 控制位: 1 0 0 0 0 0 0 0 (只有第1个字节是控制符)
查表: 找到以S_0 开头的那一行 -> S0 D1 D2 D3 D4 D5 D6 D7。
编码结果:
Sync: 10 (因为有控制符)
Block Type Field: 0x78 (看表格中间那列,对应S_0 行)
Payload: 扔掉S_0 (因为 Type Field 0x78 已经隐含了“第一个字节是 Start”的意思),只保留后面 7 个数据字节。
最终 66B: 10 78 55 55 55 55 55 55 D5
这种机制极其巧妙地把 8 bit 的控制开销压缩到了 2 bit (Sync) + 偶尔出现的 8 bit (Type Field) 中。
不过个人觉得上述的控制码表没那么重要,主要是和XGMII接口配合使用,当我们不关心接口,只把PCS+PMA用来传输数据的时候,我们只需要考虑把数据正确恢复出来即可。给我32个32bit数据,我就恢复出对应的32个32bit数据就完事了,不用考虑XGMII 64bit数据,还有8bit控制符这些。
评论