简介:IEEE Std 802.3ab-1999 是千兆以太网 1000BASE-T 的正式规范文档,面向以太网 PHY 芯片设计、网络硬件开发与协议调试人员,用于解决四对 Cat 5 平衡铜缆上 1000 Mb/s 物理层实现所涉及的编码、传输与接口定义问题。压缩包仅含 1 个 PDF 文件,大小约 1.24MB,适合作为标准原文随时检索与对照。文档系统给出 1000BASE-T 的 PCS、PMA 与 MDI 子层要求,并涵盖自动协商机制、MASTER-SLAVE 同步方式、线缆连接器规范及信号平衡与阻抗匹配等内容,可帮助读者理解千兆以太网物理层参数、链路建立过程与芯片接口行为。已有 301 人学习,适合需要查阅权威条款、核对设计细节或补充协议基础的工程师与高年级学生。
1. 四对铜线跑千兆:1000BASE-T 到底把复杂度藏在了哪一层
很多人第一次认真看千兆网口的原理图会愣一下:Cat 5 双绞线的标称带宽只有 100 MHz,四对线,凭什么跑 1 Gbps?直觉答案是"把 100BASE-TX 的时钟加快十倍",但真这么做,信号在一百米铜缆上早就糊成一团,接收端连眼图都张不开。1000BASE-T 走的是完全相反的路:它不提高单对线的速率,而是把四对线当成一个联合信道,在以太网 PHY 芯片里塞进一整套数字信号处理——五电平调制、格状编码、回波消除、串扰消除、主从时钟同步。这份 802.3ab 标准真正值得读的地方,不是它定义了哪些寄存器位,而是它如何在一条被判了"带宽死刑"的铜缆上,用编码和 DSP 把香农限榨到极限。你排障时遇到的"链路能起但吞吐上不去""换根线就好了"这类玄学,绝大多数能在这一层的物理量里找到确定答案。
2. 频谱账本:125 MBd 与 PAM-5 是怎么被"算"出来的
2.1 从 1 Gbps 倒推:每对线必须扛多少
标准给出的约束很硬:四对 Cat 5 平衡铜缆,每对线的有效载荷 250 Mb/s,四对合起来 1 Gbps,双向同时跑,也就是全双工。注意这里的"四对"不是四条独立的高速通道各跑各的,而是一个绑定信道,后面会看到这个设计选择如何决定了整个接收机的结构。
先从最简单的方案算起:如果沿用 100BASE-TX 的 NRZ(两电平,每符号 1 bit),每对线要跑到 250 Mb/s,符号率就是 250 MBd。按奈奎斯特,这要求信道带宽至少 125 MHz,而 Cat 5 的标称带宽只有 100 MHz,再叠加二十几个 dB 的百米插入损耗,这条路直接封死。想降符号率,只能提高每符号携带的比特数。
于是问题变成一道整数规划:每对线每符号带 k bit,符号率就是 250/k MBd,要让它落进 100 MHz 的可用带宽里。k=2 给出 125 MBd,k=3 给出 83 MBd。但 k 越大,电平数越多,最小判决距离越小,对 SNR 的要求越苛刻。标准的答案是 k=2、五电平(PAM-5),符号率 125 MBd。
# 1000BASE-T 的频谱账本:从目标速率倒推符号率与所需信噪比 import math PAIRS = 4 # 四对双绞线 LINE_RATE = 1e9 # 目标线速率 1 Gbps(全双工,每方向) SYMBOL_RATE = 125e6 # 标准规定的符号率 125 MBd bits_per_pair = LINE_RATE / PAIRS / SYMBOL_RATE # 每对线每符号承载的比特 print(bits_per_pair) # 2.0 -> 正好对应 PAM-5 里"取 2 bit" def q(x): return 0.5 * math.erfc(x / math.sqrt(2)) def pam_ser(M, es_n0_db): """M 电平 PAM 的符号错误率近似:最小距离 d 由平均符号能量归一化得到""" es_n0 = 10 ** (es_n0_db / 10) d = math.sqrt(6 * es_n0 / (M ** 2 - 1)) # 归一化最小欧氏距离 return 2 * (1 - 1 / M) * q(d / 2) for snr in (18, 20, 22, 24): print(f"Es/N0={snr} dB -> 未编码 PAM-5 的 SER ≈ {pam_ser(5, snr):.2e}")这段代码的价值在于把"为什么必须编码"量化出来。四对线合起来的 4D 符号错误率目标在 10⁻¹⁰ 量级,换算到单对线的 PAM-5 符号错误率还要更宽松一些,但即便如此,未编码的 PAM-5 需要 Es/N0 落在二十四五个 dB 以上才够。而 Cat 5 在百米、带串扰、带回波的真实环境里,留给 PAM-5 判决的 SNR 裕量并没有这么宽裕,中间差的那几个 dB,就是后面格状编码要补的窟窿。
参数说明:es_n0_db是平均符号能量与噪声功率谱密度之比,不是带宽内的 SNR,两者差一个符号率因子;d是归一化后相邻电平的最小距离,M 越大 d 越小,这就是"电平数换带宽,但要付 SNR"的数学表达。
2.2 为什么是五电平,不是四电平也不是八电平
PAM-4 同样能做到每符号 2 bit、125 MBd,看起来是最自然的选择,标准却选了 5 个电平。原因藏在格状编码里:4D 符号每周期要额外携带 1 bit 冗余用于纠错,8 bit 数据加 1 bit 冗余等于 9 bit,摊到四对线上是每对 2.25 bit。PAM-4 的 2 bit 装不下这点余量,PAM-8 的 3 bit 又太浪费且 SNR 代价过高,5 个电平(log₂5 ≈ 2.32 bit)刚好卡在中间,既能承载 2.25 bit 的等效信息量,又不至于把判决距离压得太狠。
PAM-8 的代价可以粗算:电平数从 5 到 8,最小距离缩到约二分之一,在同样的误码率要求下需要多出六七个 dB 的 SNR。而 Cat 5 上最难缠的不是白噪声,是回波和近端串扰,这些干扰的余量本来就紧张,再拿六七个 dB 去换那点符号率,账算不过来。
| 调制方式 | 每符号比特 | 满足 250 Mb/s 所需符号率 | 相对 PAM-5 的 SNR 代价 | 结论 |
|---|---|---|---|---|
| PAM-2 (NRZ) | 1.0 | 250 MBd | 最低 | 超出 100 MHz 带宽,不可行 |
| PAM-3 | 1.58 | ~158 MBd | +3 dB 左右 | 仍超出可用带宽 |
| PAM-5 | 2.0(4D 平均 2.25) | 125 MBd | 基准 | 标准采用 |
| PAM-8 | 3.0 | ~83 MBd | +6~8 dB | 带宽有余、裕量不足 |
还有一层考虑容易被忽略:PAM-5 的电平集合是 {-2, -1, 0, +1, +2},中间那个 0 电平不只参与数据映射,它在接收端判决时提供了"无能量"的参照点,对回波消除后的残余偏移估计、对 DC 漂移的容忍都更友好。四电平没有这个天然的零点。
2.3 4D-PAM5:把四对线当成一个符号
这是 1000BASE-T 与所有百兆以太网最本质的结构差异。四对线在同一时刻各发一个 PAM-5 电平,这四个电平合起来构成一个 4D 符号,整个符号空间是 5⁴ = 625 个点。标准在这 625 个点里挑出 512 个合法组合,对应 9 bit(8 bit 数据 + 1 bit 冗余),剩下的点不是浪费,是为子集划分和直流平衡留的余地。
import itertools alphabet = (-2, -1, 0, 1, 2) space_4d = list(itertools.product(alphabet, repeat=4)) # 四对线各取一个电平 print(len(space_4d)) # 625:完整的 4D 符号空间 print(2 ** 9) # 512:标准实际使用的合法点数(8 bit 数据 + 1 bit 冗余) # 每对线的等效信息量:9 bit 摊到 4 对线 print(9 / 4) # 2.25 bit/pair/symbol,正好解释了为什么需要 5 个电平把四对线联合起来判决,收益不是"四倍"这么简单。相邻线对在同一束缆里,串扰是相关的,联合最大似然估计能利用这种相关性;更关键的是,4D 空间里的最小欧氏距离比单对线 1D 判决时的距离更大,这部分直接转化为编码增益。代价也很实在:四个符号必须在时间上严格对齐,任何一对线的传播时延偏差都会让"联合判决"退化成"四个独立的糊涂判决",所以第 4 章要专门讲 deskew。
3. PCS 拆解:8/9 格状编码与两套加扰多项式的意义
3.1 格状编码:用 1 bit 冗余换 6 dB
物理编码子层(PCS)干的第一件事不是编码数据,是制造冗余。标准采用的是一套 8 状态的 4D 格状编码(Trellis Coded Modulation),码率 8/9:每 8 bit 用户数据进来,其中一位送进卷积编码器、出来两位,与剩下七位拼成 9 bit,再去查表映射成四个 PAM-5 符号。
为什么要这么绕?因为直接在 PAM-5 上做独立符号判决,误码率曲线是一条陡峭但不挪位置的线;加了卷积约束之后,接收端不再是"逐个符号猜",而是"在状态转移图里找一条最可能的路径"。合法路径之间的欧氏距离大于任意符号之间的最小距离,等效于把误码率曲线整体左移——工程上常引用的量级是 6 dB 左右的编码增益,正好补上 2.1 节算出来的那个缺口。
# 8 状态格状编码的接收端骨架:每个状态只保留一条幸存路径(Viterbi 的核心一步) INF = float("inf") NUM_STATES = 8 def viterbi_step(metrics, branch_metric_fn, rx_4d): """metrics: 上一符号各状态的累积路径度量 branch_metric_fn(state, bit, rx_4d): 给定状态与输入位,返回该分支的平方欧氏距离""" new_metrics = [INF] * NUM_STATES survivor = [None] * NUM_STATES for state in range(NUM_STATES): if metrics[state] == INF: continue for bit in (0, 1): # 每个状态只有两条出边:冗余位取 0 或 1 nxt = ((state << 1) | bit) & 0x7 # 8 状态移位寄存器模型 cost = metrics[state] + branch_metric_fn(state, bit, rx_4d) if cost < new_metrics[nxt]: new_metrics[nxt] = cost survivor[nxt] = (state, bit) # 记录回溯信息 return new_metrics, survivor这段骨架省略了标准的子集映射表(那张表在标准文本里长得像密码本,是 4D 子集划分的结果),但结构是真实的:每符号 8 个状态、每状态 2 条分支、每条分支的度量来自四对线联合的平方欧氏距离。参数rx_4d是回波与串扰消除之后残留的四维软判决值,metrics是累积路径度量,survivor用于回溯输出比特。实际芯片里这一块是并行的 ACS 阵列,因为 125 MBd 的符号率意味着每 8 ns 就要完成一次全状态更新,软件模拟只用于验证。
8 个状态是刻意的折中。状态数翻倍能再挤出一两个 dB,但 ACS 单元数量、回溯深度、功耗都跟着涨,而 1000BASE-T 的 SNR 缺口只有那么大,多出来的增益换不来实际链路长度的提升。这是个典型的"够用就停"的工程决策。
3.2 加扰器:为什么主从两端要用不同的多项式
9 bit 在进映射表之前还要过一道加扰。加扰的目的有三个:把用户数据的频谱白化,避免长连 0 导致 PAM-5 长期停在中点电平、定时恢复环路失去激励;打散数据的周期性,防止某些图样在特定线对上产生窄带干扰;让发送序列在统计上接近随机,便于接收端把回波当作可辨识的确定性分量消掉。
有意思的是标准规定主从两端用不同的生成多项式:
def lfsr_scramble(bits, taps, seed=0x7FFFFFFFFFF, nbits=58): """通用 58 位 LFSR 加扰器;主从两端仅 taps 不同 master: 1 + x^39 + x^58 -> taps = (39, 58) slave : 1 + x^19 + x^58 -> taps = (19, 58)""" state = seed out = [] for b in bits: fb = 0 for t in taps: fb ^= (state >> (t - 1)) & 1 out.append(b ^ (state & 1)) # 输出比特与当前最低位异或 state = ((state << 1) | fb) & ((1 << nbits) - 1) return out master_seq = lfsr_scramble([0]*16, taps=(39, 58)) slave_seq = lfsr_scramble([0]*16, taps=(19, 58)) print(master_seq != slave_seq) # True:两端即使输入全同,线路上的序列也不同参数说明:taps决定反馈抽头位置,seed是初始状态(实际由训练阶段的同步过程确定),nbits是移位寄存器长度。两个多项式都是本原多项式,周期接近 2⁵⁸,足以覆盖任何实际数据长度。
两端用不同多项式的直接后果是:即便主从设备在同一时刻上电、发送完全相同的数据,两个方向在线路上的符号序列也高度不相关。这一点对回波消除器至关重要——回波消除器的参考输入是本地发送序列,它要估计的是"我发的东西经过混合电路泄漏回来多少",如果远端发的东西和自己的序列一模一样,那么从接收信号里区分"这是我自己的回波"还是"这是对方的数据"就变成了一道无解的题。用一个多项式区分两个方向,等于给回波消除器发了一张身份牌。
3.3 从 MDI 到 GMII:一条完整的接收链
把 PCS 和 PMA 串起来看,一个 1000BASE-T 接收通道大致是这么几级:混合电路给出初步的收发隔离,可编程增益放大器把信号拉到 ADC 的量程内,ADC 以符号率(或数倍过采样)采样,采样值先减回波、再减三个相邻线对的近端串扰,然后进均衡器补偿线缆的幅度衰减和群时延,最后交给 Viterbi 做序列估计,解扰后还原成 8 bit 数据,以 125 MHz 的节奏送进 GMII。
| 处理级 | 处理对象 | 典型实现思路 | 失败时的表征 |
|---|---|---|---|
| 混合电路 | 收发隔离 | 变压器 + 阻抗桥 | 回波余量不足,长线掉链 |
| AGC | 幅度归一 | 可变增益放大器 | 短线上饱和、长线上量化噪声大 |
| ADC | 模拟采样 | 每对线一个,常过采样 | 有效位数不够,判决距离缩水 |
| 回波消除 | 本地发送泄漏 | 自适应 FIR,LMS/RLS | 链路起来但误码随温度漂移 |
| NEXT 消除 | 邻对近端串扰 | 三路自适应 FIR | 短缆反而比长缆差 |
| 均衡 | 码间干扰 | FFE + DFE | 长缆距离上不去 |
| Viterbi | 格状码译码 | 8 状态 ACS 阵列 | 编码增益失效,误码率贴近未编码曲线 |
GMII 那一侧的时序很容易被忽略:8 bit 数据宽、125 MHz 时钟,正好 1 Gbps。这意味着 PHY 内部的 4D 符号处理、Viterbi 回溯、解扰全部要在 8 ns 的符号周期内流水完成,所以真实芯片里这些模块是深度流水线化的,Viterbi 的回溯深度通常要跨好几个符号周期,靠加流水延迟来换时序收敛。
4. PMA 与混合电路:同一对线上同时收发靠什么不打架
4.1 回波:自己发的信号比对方发的强得多
100BASE-TX 用一对线收、一对线发,收发天然隔离。1000BASE-T 把四对线全部改成双向同时收发,隔离问题瞬间变成主要矛盾:本地发送的差分信号幅度通常在伏级,经过百米 Cat 5 衰减后,从对端到达的远端信号可能只剩几十毫伏,而这两者在同一对线上叠加。混合电路(hybrid)靠变压器和阻抗桥做第一道隔离,能压掉一二十个 dB,但 Cat 5 的阻抗一致性、连接器的回波损耗、线缆的驻波都会让隔离度打折扣,残留下来的泄漏就是回波。
回波消除器的思路是"以己度人":它拿本地发送的符号序列作为参考输入,过一个自适应 FIR 滤波器,估计出这条路径(混合电路不平衡 + 线缆阻抗失配)的冲激响应,然后从接收采样里把这个估计值减掉。
def lms_echo_cancel(x_ref, d, mu=0.01, taps=64): """最简 LMS 回波消除器 x_ref: 本地发送符号序列(已知) d : 混合电路之后的接收采样(含回波 + 远端信号 + 噪声) mu : 步长,决定收敛速度与稳态失调的折中""" w = [0.0] * taps err_hist = [] for n in range(taps, len(d)): x = x_ref[n - taps + 1: n + 1][::-1] # 当前窗内的参考符号 echo_hat = sum(wi * xi for wi, xi in zip(w, x)) e = d[n] - echo_hat # 残差里应该只剩远端信号 + 噪声 for i in range(taps): w[i] += mu * e * x[i] # LMS 权重更新 err_hist.append(e) return w, err_hist参数说明:taps是消除器长度,要覆盖混合电路和线缆失配造成的回波拖尾;mu是步长,太大收敛快但稳态抖动大,太小则训练阶段收敛不完,链路建立超时;e是残差,也就是真正送给后续均衡和解码的信号。这段代码只演示原理,实际芯片里回波消除器是符号率甚至多倍符号率并行的,且训练阶段用的是标准的训练序列而不是随机数据,为的是让自适应滤波器在有限时间内收敛到稳定解。
这里有个反直觉的地方:回波消除的精度要求比"消除干净"更微妙。消除不足,残余回波会直接抬高噪声底;消除过头,自适应滤波器会开始拟合远端信号和噪声,反而引入新的失真。训练序列的设计、步长的调度、以及训练结束后的系数冻结策略,都是各家 PHY 芯片拉开差距的地方。
4.2 NEXT 与 FEXT:为什么短缆有时比长缆更难跑
四对线在同一束护套里,一对线的发送会通过分布电容耦合到相邻线对的接收端,这就是串扰。近端串扰(NEXT)发生在发送端附近,耦合路径短、衰减小,强度可能比远端来的有用信号还大;远端串扰(FEXT)经过整段线缆的双重衰减,通常小得多。
标准对两者的处理态度不同:NEXT 需要显式的自适应消除,接收端拿三个相邻线对的本地发送序列作为参考输入,各跑一个自适应滤波器,把耦合分量减掉;FEXT 在多数实现里不作显式消除,靠格状编码的增益和均衡器消化。这个取舍的原因是 FEXT 相对较弱,为它再增加三路长滤波器,面积和功耗的代价换不回等量的链路裕量。
这也解释了一个现场经常遇到的现象:同一条链路,短缆(比如十几米)反而比长缆更容易出问题。短缆的插入损耗小,远端信号强,但 NEXT 的耦合路径也更短、耦合更强,两相抵消之后,短缆的 SNR 未必更好;再叠加连接器处的回波损耗,短缆上的回波消除器工作点反而更难看。
4.3 MASTER-SLAVE:为什么两端不能都当主
四对线同时双向收发,意味着两端必须共享一个频率参考——如果两端各用各的晶振(哪怕标称频率一样,ppm 级偏差也会累积),接收端的载波恢复环路就得不停地追,符号定时会漂。标准的解法是强制一端为 MASTER、一端为 SLAVE:MASTER 用本地晶振作为发送时钟,SLAVE 从接收到的信号里恢复时钟,再用这个恢复出来的时钟驱动自己的发送,形成环回定时(loop timing)。这样整条链路只有一个时钟源。
MASTER-SLAVE 的归属由自协商决定,规则是双方各自宣告自己的主从偏好,冲突时按约定的优先级裁决。现场最常见的翻车是一端手动配置成强制 MASTER、另一端也强制 MASTER,链路直接起不来,或者起来了但误码率惨不忍睹。
还有一层:四对线的传播时延并不相同。Cat 5 的四对线绞距不同,信号沿线的传播速度有差异,百米链路上的线对间时延偏差可以到几十纳秒量级。125 MBd 的符号周期是 8 ns,几十纳秒的偏差意味着四个 PAM-5 符号根本不是"同时"到达的,4D 联合判决的前提被破坏。所以接收端必须做 deskew:在训练阶段测量每对线的相对延迟,用可调的延迟线或数字内插把四个符号流对齐,之后才能交给 Viterbi。这个对齐精度直接决定了 4D 编码的增益能不能拿到手。
5. 排查:千兆链路"能通但慢"时该看哪几个物理量
5.1 先分层,别一上来就怀疑线
千兆链路的故障有个稳定的分层顺序:链路层起没起来、协商结果对不对、错误计数涨不涨、吞吐卡在哪。跳过分层直接换线、换模块,是最典型的踩坑方式,因为换完之后"好了"往往只是运气,下一次同样的问题还会回来。
在通用系统上,几组命令就能把前两层的信息捞出来:
# 1) 协商结果:速率、双工、是否启用了自协商 ethtool eth0 | egrep 'Speed|Duplex|Auto-negotiation|Link detected' # 2) 对端宣告了哪些能力(看是否有一端只宣告了百兆) ethtool eth0 | sed -n '/Advertised link modes/,/Advertised pause/p' # 3) 错误计数:CRC/FCS 错误、载波错误、冲突计数 ip -s link show eth0判断逻辑很直接:Link detected: yes且速率协商到 1000 Mb/s 全双工,说明物理层训练完成、4D 符号对齐、Viterbi 已经在正常输出;Speed: 100Mb/s说明自协商降级了,问题在协商或线缆质量;如果速率是全千兆但ip -s link里的错误计数持续增长,那才是真正难查的那一类——物理层能维持链路,但 SNR 裕量被吃掉了。
注意Duplex: Half在千兆下是不该出现的状态。1000BASE-T 从标准到产品只有全双工一种形态,看到半双工基本可以判定是自协商失败后落到了并行检测的兜底逻辑上。
5.2 从回波损耗到 TCP 重传:一条完整的因果链
"能 ping 通但传文件慢"这类问题,根因链条通常是这样的:线缆或连接器的回波损耗超标 → 混合电路隔离度下降 → 回波消除器残余增大 → 进入 Viterbi 的 SNR 下降 → 译码后仍有残余比特错误 → 以太网帧 CRC 校验失败被丢弃 → 上层协议重传 → 有效吞吐掉到标称值的一半甚至更低。
这条链子上每一环都可以单独验证。回波损耗要用线缆认证测试仪测,看的是全频段内的回波损耗曲线,而不是"通断";NEXT 要看最差线对组合,因为四对线的绞距不同,某些组合的耦合天生更强;线对间时延偏差(skew)如果超限,表现是链路能起但误码率随温度或线缆弯折漂移,因为 deskew 的余量被吃掉了。
| 观测现象 | 最可能的物理层原因 | 验证方式 |
|---|---|---|
| 协商到 100 Mb/s | 某对线开路/短路,或 NEXT 严重超标 | 换线直连对比,看协商结果是否变化 |
| 千兆但吞吐腰斩 | 回波损耗超标导致残余误码 | 查 CRC 错误计数是否随流量增长 |
| 间歇性丢包、随温度变化 | 连接器接触不良或阻抗失配 | 重做端接,看误码是否消失 |
| 短缆比长缆更差 | NEXT 耦合强,回波消除器工作点差 | 换长缆对比,或换屏蔽线 |
| 链路完全起不来 | 两端主从配置冲突 | 双方恢复自协商 |
5.3
本文还有配套的精品资源,点击获取