ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

从并行总线到HSS核:SerDes链路预算与上板调试

从并行总线到HSS核:SerDes链路预算与上板调试

简介:这份资源是面向硬件接口协议方向工程师与高年级学生的SerDes(串行器/解串器)专业英文培训教材,依托IBM高速SerDes器件的研发实践,系统讲解从并行-串行转换、8B/10B与64B/66B编解码、时钟数据恢复(CDR)与锁相环,到前向纠错、差分信号与阻抗匹配等信号完整性设计要点,并延伸至功耗管理、标准兼容性等工程挑战,适合希望从数字逻辑思维转向高速串行接口设计的中高级读者补齐体系化知识。包内为1个PDF文件,压缩包约10.89MB,单册完整呈现原书章节结构与图表公式,便于按主题检索或整册通读。目前已有918人学习关注,说明该主题在实际项目中的需求度较高。读者可借此建立SerDes链路预算、均衡与抖动分析的完整框架,理解以太网、SAS/SATA、HDMI、DisplayPort及数据中心互连等场景下的接口选型逻辑,并结合书中案例掌握高速通道调试与问题定位的思路。

1. 这本教材解决的是「datasheet 看懂一半」的问题

SerDes 相关的资料,网上搜一圈基本是两极:要么是芯片手册里几百页的寄存器表,要么是零散的公式推导和眼图照片。这份国外某老牌半导体厂商的内部培训材料走的是中间那条路——先把并行总线为什么走不下去讲透,再把一颗 10Gbps 级别的 HSS 核拆成 PLL、发送、接收三个 slice 逐块说明,最后落到协议逻辑、参考时钟、抖动预算和上板测试。关键词是硬件接口协议,但重心不在协议栈本身,而在协议能不能在一条真实的差分通道上跑通。适合两类人:已经做过数字 IP、第一次要往芯片里集成高速串行核的;以及被叫去定位「链路偶尔误码、重启就好」这种问题的。前者能拿到配置顺序,后者能拿到一份可量化的排查清单。

2. 从并行总线到 HSS 核:引脚、时序、模拟三笔账

数字背景的工程师看 SerDes,第一反应往往是「一个复杂的 IO cell,配置寄存器就行」。这个判断在 1Gbps 以下勉强成立,往上就开始出问题。教材第一章花了整整一节讲并行数据总线的两个原生缺陷,这两个缺陷不是工程实现不好,而是物理上绕不过去,理解这一点,后面所有的均衡、CDR、编码才有落脚点。

2.1 引脚账:并行总线先在封装上崩掉

最朴素的数据搬运方式是把 n 位数据通路直接从一颗芯片连到另一颗,两边同源时钟同步采样。问题在于,每多一位数据就多一个 I/O 引脚,实际布线时还要按比例配地引脚来压制同步开关噪声,一个 32 位通路加上时钟、控制、地,轻松吃掉六七十个引脚。硅上能塞的晶体管按摩尔定律翻倍,封装引脚密度却远没有跟上这个节奏,这个剪刀差是 HSS 成为高集成度芯片默认 I/O 形式的直接原因。

换成一发一收两对差分线,引脚数量立刻从「与位宽成正比」变成常数。这条账最容易算,也最容易被当成全部理由——真正的代价在后面两笔。

2.2 时序账:源同步接口的时钟前传与 skew 天花板

为了绕开并行总线的时钟偏斜,常见做法是源同步:发送端把时钟和数据一起送出去,接收端用这根随路时钟去采数据。教材里把这个演进路径讲得很细,从共用系统时钟到时钟前传,再到更高速度的源同步接口,每一代都在跟同一个东西较劲——采样窗口。

算一笔具体的账:1Gbps 时一个 UI 是 1000ps,PCB 上 ±20ps 的走线失配、连接器、封装引入的偏斜还能容忍;到 10Gbps,UI 只剩 100ps,同样的 ±20ps 已经吃掉近半个眼宽,再加上建立保持时间、时钟抖动、占空比失真,窗口基本归零。这就是「数字信号假设失效」的具体含义:不是信号变差了,是留给「理想 0 和 1」的余量没了。到了这一步,必须把时钟从数据里恢复出来,也就是 CDR 存在的理由。

2.3 模拟账:均衡、CDR 与差分驱动接收

HSS 核内部大致可以拆成这么几块:串行器/解串器、发送端前馈均衡(FFE)、接收端均衡(DFE 或非 DFE 模式)、时钟数据恢复、差分驱动器、差分接收器、诊断通路(PRBS 与 loopback)、锁相环。教材用一张框图把这些块串起来,然后逐个展开,这个组织方式很值得学——它逼你承认每一块都在处理模拟量。

以 CDR 为例,它靠数据本身的跳变来对齐相位,跳变越稀疏,环路越容易漂。这直接推出两个设计约束:一是编码要保证足够的跳变密度(8B/10B 的最大连 0/连 1 是 5),二是加扰不能省。以 FFE 为例,它本质是用抽头系数去拟合信道的频率响应,系数给大了会过度放大高频噪声,给小了补偿不足,两头都是误码。这些参数在 datasheet 里是一张表,在这本教材里是一段带推导的说明,差别就在能不能自己判断「这个值为什么是这个值」。

2.4 信道与封装模型:别把走线当理想导线

教材的信号完整性章节从概率密度函数讲起,高斯分布和双狄拉克分布各自对应随机抖动和确定性抖动的建模方式,然后才进到抖动分量、总抖动模型、抖动预算和容限。这个顺序有点绕,但它解决的是一个很实际的问题:你在示波器上看到的眼图,和仿真里跑出来的统计眼图,凭什么相信是同一个东西。

信道本身要用 S 参数描述,插损随频率上升,到奈奎斯特频率(速率的一半)时衰减最狠。封装模型不能省,键合线、过孔残桩、AC 耦合电容都会在几 GHz 上变成不想要的谐振点。传统 SPICE 跑几百万比特不现实,所以教材专门讲了混合 SPICE/行为级模型和统计法分析——把线性信道用冲激响应处理,把非线性部分留给电路仿真,再用统计方法外推低概率事件。这套方法直接决定了你做链路预算时是拍脑袋还是能落到表格。

提示:做到链路预算这一步,先确认手上有三样东西——信道的插损曲线、封装的 S 参数或等效模型、收发两端的抖动指标。缺一样,后面的估算都只能当参考值用。

3. 把 EX10 核从复位带到链路 up:寄存器、速率档与 FFE/DFE 初值

教材第二章围绕一个教学用的示例核展开,代号 EX10,10Gbps 级别,明确说明是简化过的教学模型,但功能划分和真实产品是对得上的。这一章的价值在于它给了完整的寄存器说明和操作顺序,等于把「集成」这件事拆成了可执行的动作。下面按上电到链路的实际顺序梳理。

3.1 复位序列与 PLL 锁定:先等 lock 再动数据通路

顺序错一步,后面全是玄学。合理的上电次序是:供电稳定 → 参考时钟有效 → 全局复位 → PLL 上电复位与 VCO 粗校准 → 等锁定检测 → 释放发送/接收 slice 复位 → 写配置 → 使能输出。教材里专门有复位序列器和 HSS 重同步的章节,讲的其实是同一件事:PLL 没锁之前,任何对发送通路的配置都可能被未稳定的时钟打乱。

锁定检测不能当绝对真理用。实际做法是给一个超时窗口,检测不到 lock 就重新触发 VCO 粗校准,重试若干次仍失败则上报。很多「上电偶发不启动」的问题,根因就是只查了一次 lock 位、没做重试。

阶段关键动作判据
供电与参考时钟多路电源按序上电,参考时钟起振电源纹波在规格内,时钟摆幅与压摆率达标
PLL 初始化复位 PLL,触发 VCO 粗校准校准完成标志置位
锁定等待 lock 指示lock 稳定若干微秒且无抖跳
通路释放释放发送/接收复位各 slice 就绪状态可读
配置写速率档、均衡、终端、诊断回读一致

3.2 速率档选择:全速率、半速率、四分之一与八分之一

示例核支持全速率、半速率、四分之一速率和八分之一速率几种工作模式,本质是串行器内部时钟频率与串行比特率之间的关系,直接决定并行侧总线宽度和内部时钟树的负担。10Gbps 串行速率下,全速率意味着内部要跑 10GHz 级时钟,代价极大;半速率用双边沿把时钟降到 5GHz;四分之一和八分之一速率进一步降频,代价是并行侧位宽变宽、走线和时序收敛压力转移到数字侧。

选档的判断依据有三个:串行速率、后端并行总线能收敛到的频率、功耗预算。教材的功耗章节把 HSS 功耗拆成与模式相关的几部分,多电源域、工艺、速率档都会改变静态和动态功耗的占比,所以档位不是越高越好,是匹配最好。

档位内部时钟关系并行侧位宽(以 10Gbps 为例)典型取舍
全速率等于串行比特率10bit时钟树最难,功耗最高
半速率比特率的一半20bit折中,常用
四分之一比特率的四分之一40bit数字侧时序宽松,位宽变大
八分之一比特率的八分之一80bit适合后端频率受限的场景

3.3 发送端 FFE 抽头初值怎么给

发送端前馈均衡的抽头通常分前游标、主游标、后游标,作用是用预加重或去加重去抵消信道对高频的衰减。初值不要一上来就顶格,教材的编程说明里给了范围,但没告诉你起点,实际做法是按信道插损分档给一个保守初值,再用误码率或眼图去扫。

我的习惯是:插损 3~6dB 的短通道先给轻预加重,主抽头占大头;10dB 以上开始加后游标;15dB 以上的背板通道才考虑前后游标一起上。每次只调一档,调完等链路稳定再测,否则你分不清是均衡起效还是 CDR 自己收敛过来了。

通道插损(奈奎斯特频率)前游标后游标备注
3~6dB关闭或最小轻微过均衡会放大高频噪声
6~12dB小中等优先调后游标
12~20dB小到中较大配合接收端 DFE 一起看
20dB 以上中大关注发送端功耗与线性度

3.4 接收端 DFE、AC/DC 耦合与相位旋转器

接收侧的可选项比发送侧多:DFE 与非 DFE 两种模式、终端方式、AC 或 DC 耦合、信号检测、相位旋转器控制、扩频时钟跟踪、眼质量指示。DFE 用判决反馈抵消后游标 ISI,在长通道上效果好,但在低损耗短通道上可能把高频噪声放大,反而不如非 DFE 模式干净——这是很典型的一条「参数不是越高级越好」。

AC 耦合要求数据流本身直流平衡,这也是编码和加扰存在的现实理由之一;DC 耦合省掉电容但要保证两端共模匹配。相位旋转器是采样相位在 UI 内的细调旋钮,配合眼质量指示可以在上电时扫一遍找眼图中心,比固定相位稳得多。扩频时钟跟踪则在参考时钟带扩频调制时保证 CDR 不丢锁。

3.5 用一张配置表加脚本管住几十个寄存器

示例核的寄存器按 slice 分组:全局、PLL、发送、接收,每组几十个字段。手写配置序列的下场是改了一个值忘了依赖关系,所以更稳的做法是把配置写成结构化表,用脚本做依赖校验和序列生成。

# reg_plan.py —— 寄存器配置表校验与写序列生成 # 每条: (地址, 名称, 值, 依赖的前置寄存器名或 None) REG_PLAN = [ (0x000, "GLOBAL_RESET", 0x1, None), (0x010, "REFCLK_DIV", 0x2, "GLOBAL_RESET"), (0x020, "PLL_POR", 0x1, "REFCLK_DIV"), (0x024, "PLL_VCO_CAL", 0x1, "PLL_POR"), (0x028, "PLL_LOCK_EN", 0x1, "PLL_VCO_CAL"), (0x100, "TX_RATE_SEL", 0x1, "PLL_LOCK_EN"), # 1=半速率 (0x104, "TX_FFE_PRE", 0x00, "TX_RATE_SEL"), (0x108, "TX_FFE_POST", 0x06, "TX_RATE_SEL"), (0x10C, "TX_ENABLE", 0x1, "TX_FFE_POST"), (0x200, "RX_RATE_SEL", 0x1, "PLL_LOCK_EN"), (0x204, "RX_DFE_EN", 0x1, "RX_RATE_SEL"), (0x208, "RX_TERM_SEL", 0x2, "RX_RATE_SEL"), (0x20C, "RX_PHASE_ROT", 0x10, "RX_TERM_SEL"), (0x210, "RX_ENABLE", 0x1, "RX_PHASE_ROT"), ] def validate(plan): seen = set() for addr, name, val, dep in plan: if dep is not None and dep not in seen: raise ValueError(f"{name}: 依赖 {dep} 未先写入") if not (0 <= addr <= 0x2FF): raise ValueError(f"{name}: 地址 0x{addr:X} 超出片选范围") if not (0 <= val <= 0xFF): raise ValueError(f"{name}: {name} 的值 0x{val:X} 越界") seen.add(name) def emit(plan): lines = [] for addr, name, val, _ in plan: # 写命令格式按实际总线替换,这里用 16 位地址 + 8 位数据示意 lines.append(f"write 0x{addr:03X} 0x{val:02X} # {name}") return lines if __name__ == "__main__": validate(REG_PLAN) print("\n".join(emit(REG_PLAN)))

这段脚本做三件事:检查每条配置的依赖寄存器是否已经在前面的序列里出现过,防止顺序错;检查地址和值是否越界,防止手滑写错页;最后按顺序生成写命令。参数上要注意,dep填的是寄存器名而不是地址,因为地址在不同版本里可能挪,名字相对稳定;TX_FFE_POST的初值 0x06 只是示例通道的起点,换通道必须重新扫。

注意:配置表要跟着版本走。核的寄存器定义一变,脚本里的名字和地址必须同步更新,否则校验全过、链路照样不通。

4. 协议逻辑与参考时钟:8B/10B、deskew、时钟树与抖动预算

到这一层,讨论的对象从「一个核」变成「一条链路」。教材把协议逻辑和协议标准分成两章:一章讲编码、加扰、错误检测、位对齐、多链路去偏斜这些通用功能,另一章扫了一遍常见的接口标准族。对做集成的人来说,前者的可操作性更强。

4.1 8B/10B 与加扰:编码不是为了好看

8B/10B 把 8 位数据拆成 5B/6B 和 3B/4B 两段分别映射,用运行不一致性(running disparity)维持直流平衡,同时保证最大连 0/连 1 不超过 5,给 CDR 提供足够的跳变密度。代价是 25% 的带宽开销。64B/66B 开销低得多,但必须靠加扰来保证跳变密度和频谱铺开。

这两种方案的选择,本质是「带宽换抖动容限」还是「加扰换带宽」。教材里还专门列了位/字节序、条带与交织、错误检测与纠正这些功能块,它们看起来是协议层的事,实际会直接影响你在并行侧怎么对齐数据、怎么算 FIFO 深度。特殊字符的用途值得单独记一下:

特殊字符主要用途使用注意
K28.5逗号对齐,确定符号边界极性反转时有两种码型,需都识别
对齐字符多 lane 去偏斜的锚点插入周期决定可纠正的偏斜上限
空闲字符填充,维持跳变密度不能破坏直流平衡
错误传播字符标记上游检测到的错误避免错误被静默吞掉

4.2 多 lane 去偏斜的可复现算法

每条 lane 有独立的 CDR,恢复出来的数据在相位上互不相同,PCB 走线长度差、封装内延迟差都会变成 lane 间偏斜。做法是在发送端周期性插入对齐字符,接收端每条 lane 检测到对齐字符后把数据写入 FIFO,等所有 lane 都到齐再统一读出。可容忍的最大偏斜等于 FIFO 能缓冲的 UI 数,所以 FIFO 深度不是随便给的。

# deskew_budget.py —— 根据实测 lane 偏斜算 FIFO 深度与余量 UI_PS = 100.0 # 10Gbps 下一个 UI 的时长 FIFO_DEPTH_UI = 16 # 设计给定的 FIFO 深度(单位 UI) MEASURED_SKEW_PS = {0: 0.0, 1: 180.0, 2: 420.0, 3: 650.0} # 各 lane 到达偏移 def check(skew_ps, ui_ps, depth_ui): worst = max(skew_ps.values()) - min(skew_ps.values()) worst_ui = worst / ui_ps margin_ui = depth_ui - worst_ui # 留 30% 余量应对温漂与电压变化 ok = margin_ui >= worst_ui * 0.3 return worst_ui, margin_ui, ok worst_ui, margin_ui, ok = check(MEASURED_SKEW_PS, UI_PS, FIFO_DEPTH_UI) print(f"最大偏斜 {worst_ui:.2f} UI, 剩余余量 {margin_ui:.2f} UI, 判定 {'通过' if ok else '不足'}")

参数含义很直白:UI_PS随速率变,FIFO_DEPTH_UI是 RTL 里定死的,MEASURED_SKEW_PS来自上板实测或封装加 PCB 的延迟估算。判定条件里那个 30% 不是标准,是我自己的习惯——只留一两个 UI 的余量,温度一变就容易翻车。真正要改设计时,优先动的是发送端对齐字符的插入周期,它决定 FIFO 需要多深。

4.3 参考时钟网络:单端还是差分,扇出怎么走

参考时钟的质量直接决定 PLL 输出抖动的下限。单端时钟省引脚、成本低,但对共模噪声和地弹敏感;差分时钟抗共模、抖动更低,代价是多一对引脚和一点功耗。教材在参考时钟章节里把时钟源、特殊时序要求、特殊测试要求分开讲,实际项目里最容易忽略的是「测试要求」——探点怎么留、探头负载会不会把时钟压塌,这些在流片前不定,后面只能靠猜。

时钟树布局上,几条经验值得写进检查表:走线尽量等长且避免跨分割,过孔数量控制到最少,终端匹配靠近接收端,差分对内的偏斜要远小于 UI 的一个零头,占空比失真单独测——它不像抖动那样有现成指标,但会直接吃掉采样窗口的一半。

4.4 抖动预算:Tj = Dj + n×Rj 怎么落成表

确定性抖动和随机抖动不能直接相加了事。随机抖动是高斯的,无界,只能按误码率给一个统计上限:Tj(BER) = Dj + n × Rj,其中 n = 2×Q,BER 为 1e-12 时 Q 约 7.03,n 约 14.07。确定性抖动包含占空比失真、ISI、周期性抖动和有界不相关抖动,通常保守地线性相加。

# jitter_budget.py —— 按目标误码率折算总抖动并核对 UI 余量 from statistics import NormalDist BER = 1e-12 UI_PS = 100.0 # 10Gbps RJ_RMS_PS = 1.2 # 随机抖动 RMS DJ_COMPONENTS_PS = { # 确定性抖动各分量,保守线性相加 "dcd": 3.0, "isi": 8.0, "pj": 2.5, "buj": 1.5, } q = NormalDist().inv_cdf(1 - BER) # 单边 Q 值 n = 2 * q # 双边上限系数 dj = sum(DJ_COMPONENTS_PS.values()) tj = dj + n * RJ_RMS_PS margin = UI_PS - tj print(f"Q={q:.2f}, n={n:.2f}") print(f"DJ={dj:.2f}ps, TJ={tj:.2f}ps, 眼宽余量={margin:.2f}ps ({margin/UI_PS*100:.1f}% UI)")

这段的输出可以直接填进链路预算表。要注意两个参数怎么定:RJ_RMS_PS取参考时钟加 PLL 的积分抖动,积分区间要写清楚,不写区间的抖动数字没有可比性;DJ_COMPONENTS_PS里 ISI 最好来自信道仿真而不是猜。余量算出来小于 20% UI 的时候,就该回头动均衡或换通道了,别指望 CDR 硬扛。

5. 避坑排查:五条链路不通的血泪记录

下面五条都是「现象看着像同一个,原因完全不同」的类型。教材给的是原理和寄存器定义,真正定位还得靠这套现象、原因、解决的拆法。

第一条:PLL 报锁定,链路就是不通。现象是 lock 位读回来稳定为 1,发送端也有输出,接收端信号检测却时有时无。原因多数在参考时钟质量——摆幅不够、压摆率太缓、或者占空比失真过大,PLL 在窄带内能锁,但送进 CDR 的相位噪声已经把眼图糊掉了。解决方式是先用示波器直接测参考时钟的差分摆幅、上升时间和占空比,别只看频率对不对;然后确认时钟走线没有跨分割、终端匹配在接收端而不是悬空。

第二条:常温测试全过,高温一跑就误码。现象是误码率随温度上升几个数量级,冷却后恢复。原因是 VCO 粗校准在常温下选中的频段在高温漂出范围,或者电源纹波在高温下变大导致 PLL 带内噪声抬升。解决方法是在高温下重跑一次 VCO 校准并记录频段码,如果和常温差得多,说明校准窗口设计太窄;同时检查多路电源的上电顺序和去耦,HSS 功耗随模式变化,动态负载会把电源拉出纹波。

第三条:随机码型没事,特定码型误码率暴涨。现象是 PRBS 测试正常,一跑真实业务流量就出问题。原因通常是加扰没开或配置不一致,长连 0 让 CDR 失去跳变参考;也可能是 8B/10B 的运行不一致性在两端配置不同,导致特殊字符识别错位。解决方式是先确认两端加扰开关和多项式一致,再用包含长连 0 的测试码型单独验一遍,别只信 PRBS-31。

第四条:多 lane 能起链路,业务数据整体错位。现象是每条 lane 单独测都通,拼起来数据错列。原因是去偏斜 FIFO 深度不够,或者对齐字符的插入周期太长,导致偏斜超出可纠正范围;也可能是一侧把对齐字符当普通数据写进了 FIFO。解决方式是先测各 lane 的实际到达偏斜,按第 4.2 节的脚本核一遍 FIFO 余量,再检查对齐字符的识别逻辑是否在写入前就把它剥掉。

第五条:环回测试眼图漂亮,上板接真实通道就崩。现象是内部 loopback 全通,接上背板就误码。原因是 loopback 点靠近发送端,信号根本没经过封装和信道,均衡参数是在「零损耗」假设下调的。解决方式是把 loopback 点逐级往外挪——先近端、再经过封装模型、最后到真实通道,每挪一级重调一次 FFE 和 DFE。这条最容易被忽略,因为环回测试太容易过,过了就不想再动。

提示:每次改配置只动一个变量,改完记录回读值和误码率。同时改三四个参数然后说「好了」,下次出问题你没有任何线索可回溯。

6. 上板验收的最小闭环:用 PRBS、分层环回和眼质量把结论钉死

链路起来不等于能交付。教材的测试与诊断章节给了很完整的一套:JTAG 的边界扫描、PRBS 码型与环回路径、逻辑内建自测试、制造测试和特性化测试。落到日常验收,我会砍到一条最小闭环,四步走完才算过。

第一步,PRBS 分层打。用最长码型跑误码,同时把环回点从近端逐级外移到真实通道,每一级记录误码率和持续时间。码型至少要覆盖一种含长连 0 的,光跑 PRBS-31 会漏掉 CDR 跳变密度不足的问题。

第二步,扫相位。用相位旋转器在整个 UI 内步进,每步读眼质量指示或误码计数,画出浴盆曲线。曲线开口的中心才是采样相位该放的位置,而不是上电默认值。

第三步,压边界。把电压拉偏、温度拉到上下限,重复第一步和第二步。很多链路在标称条件下余量看着有 40%,一拉偏就剩个位数,这个数字才是能不能量产的依据。

第四步,核功耗。按工作模式对一遍电流,尤其是速率档切换和环回使能前后的差值,和教材里的功耗分解表对不上就说明有模块没关。

这套流程我吃过亏。早期有个项目,环回全通、常温误码为零,直接进了下一阶段,结果现场批量出现偶发误码。回头查才发现验收时没做相位扫描,采样点一直停在默认位置,离眼图中心偏了将近三分之一 UI,常温恰好够用。从那以后我每次上板都把「扫相位、画浴盆」当成硬性步骤,哪怕时间再紧也不跳。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表