DDR 接口时序概念:DQS 随路时钟、边沿与中心对齐、读写裕量和 training
DDR(Double Data Rate,双倍数据率)内存接口在时钟的上升沿和下降沿各传一个数据,这件事在SDR 与 DDR IO 寄存器一篇里已经拆到触发器级。但芯片内部拼得出 ODDR/IDDR,不等于数据能在 PCB 上跨过十几厘米的走线被正确采样。DDR 接口时序概念要回答的,是控制器和 DRAM 之间这一小段物理链路上,时钟和数据按什么相位关系飞行、裕量从哪里来、上电后为什么还要做一连串 training。本篇是纯概念梳理,不绑定某一代 DDR 的具体参数。
本文要回答的问题
- 为什么所有器件共用一颗系统时钟的做法,在 DDR 频率下必然失效?
- DQS 是什么,它为什么必须和 DQ「随路」传输?
- 边沿对齐和中心对齐分别长什么样,读和写为什么采用不同的对齐方式?
- 建立时间和保持时间的裕量在 DDR 链路上是怎么被一点点吃掉的?
- ODT、write leveling、read/write training 各自在补偿什么,缺了会怎样?
一、系统同步时钟撑不住的不是频率,是偏斜
先看低速时代的做法:存储器和控制器共用一颗板上时钟,两边都在时钟沿动作,设计时用同一个时钟沿做时序检查。这要求「时钟到达控制器的时刻」和「时钟到达 DRAM 的时刻」相差足够小,小到一个时钟周期内还能容纳数据传播和器件延迟。
频率抬高后,问题不在时钟绝对快慢,而在偏斜(skew)相对单位时间间隔(UI,Unit Interval)不再可以忽略。DDR3-1600 的 UI 是 1.25 ns,DDR4-3200 的 UI 只有 0.625 ns,而板级走线每厘米传播延迟约 0.06–0.07 ns——时钟线和数据线在封装、过孔、走线上差出几厘米,对应的就是大半个 UI。再叠加器件之间的工艺差异、电压和温度漂移,任何「同时到达」的静态假设都会破产。
系统同步还有一个结构性缺陷:时钟走时钟树、数据走数据线,两条路径的加工误差、负载、电压系数都不同,它们的延迟差随工艺角和温度漂移,无法在设计阶段一次性消掉。真正的出路是换一个时序基准——让时钟跟着数据走同一条物理通道,这就是源同步。
这张卡是全篇的地图:时钟方案决定基准怎么来,随路信号决定基准长什么样,相位关系决定在哪一刻采样,裕量是采样可靠的数学条件,ODT 和 training 则是在物理和动态层面把裕量挣回来的手段。
二、DQS 随路:让时钟和数据共担同一套误差
源同步的核心动作是:不再用那颗独立的板级时钟直接采样数据,而是由发送方在发出数据的同时,发出一个数据选通信号 DQS(Data Strobe),接收方用 DQS 的边沿去采样和它一起到达的 DQ。可以把它理解成每笔快递自带签收章——数据什么时候有效,由和它同车抵达的选通说了算,而不是由全城统一的早八点钟声说了算。
共担路径误差是关键。DQS 和 DQ 在同一个封装里出芯片、走同一片 PCB 区域、过同样的温度场,二者的飞行时间一起变大或变小,它们的相对延迟却基本不动。系统同步时代那个大得离谱的「时钟路径减数据路径」误差项,被压缩成同一组走线之间的小段等长误差,量级从几纳秒降到几十皮秒。
工程上 DQS 通常按字节配对:每 8 位 DQ 配一组 DQS(x8 颗粒一组,x16 颗粒两组),DDR2 起 DQS 多为差分信号(DQS_t/DQS_c)以抗共模噪声。注意总线上那颗真正的差分时钟 CK 并没有消失——它仍然负责命令、地址和模式寄存器的时序,DQS 只管数据节拍。两套时钟的分工是理解后面 write leveling 的前提。
| 对比项 | 系统同步(共用 CK 采样数据) | 源同步(DQS 随路采样 DQ) |
|---|---|---|
| 采样基准 | 独立分发的板级时钟 | 与数据同路发出的选通 |
| 主要误差项 | 时钟路径与数据路径的全程差 | 同组走线间的小段等残差 |
| 温度/电压漂移 | 两条路径分别漂移,差值不可控 | 同生共灭,相对相位稳定 |
| 接收方能否自调 | 只能靠固定时序约束 | 可逐位延迟 DQS,主动找窗口 |
| CK 的角色 | 唯一时序基准 | 退居命令/地址域 |
三、边沿对齐与中心对齐:差的是半拍相位
有了随路 DQS,下一个问题是它和 DQ 的跳变沿怎么摆。两种基本关系是边沿对齐(edge-aligned)和中心对齐(center-aligned),区别恰好是半个 UI。
边沿对齐指 DQS 的边沿与 DQ 的跳变同时刻发生:DQS 每次翻转,DQ 正好也在换数。这意味着接收方不能直接拿这一跳去采样——跳变瞬间数据正是最不稳定的。边沿对齐时,接收侧要在内部把 DQS 相移约 90 度(四分之一周期),让采样点落到每拍数据的中央再采样。
读这张图抓住一点:DQS 的每个上升沿都踩在 DQ 的换数点上,数据眼在两个边沿之间张开。发送方把「换数时钟」原样交出去,把「采样时钟该挪多少」这件事留给接收方用内部延迟链解决——DDR 的写时序就是这种形态:控制器发出边沿对齐的 DQS/DQ,DRAM 在片内把 DQS 偏出 90 度后采样。
中心对齐则相反:发送方预先把 DQS 相移 90 度,让 DQS 边沿落在 DQ 数据眼的正中央再发出去。接收方拿到手就能直接采样,不需要自己再挪相位。
上图中每拍 DQ 从换数到下一次换数之间保持稳定,DQS 的上升沿正好点在稳定区间的中部,左右各剩约半 UI 的余量。DDR 的读时序采用这种形态:DRAM 知道控制器侧不应该再承担相移工作,于是自己在片内用 DLL(Delay-Locked Loop,延迟锁定环)把 DQS 挪到数据眼中央发出。
为什么读和写不统一成一种?因为相移电路只放在「这一代架构认为更方便的一侧」:写时 DRAM 已有 DLL,由它顺手偏相移最省事;读时让 DRAM 用同一个 DLL 输出中心对齐选通,控制器省掉每字节的模拟相移单元。这个分工从 DDR 延续到 DDR3,DDR4/5 之后控制器侧普遍有了可编程延迟链,形态进一步演化为「发送边出发、接收方 training 找中心」,但边沿对齐与中心对齐这两个相位概念没变。
还有一个必须提一笔的机制是 write leveling(写平衡)。DDR2/3 起地址命令时钟 CK 采用 fly-by 拓扑——CK 串行经过每颗 DRAM 以省噪声代价,于是同一时刻,不同位置颗粒看到的 CK 相位天然不同。控制器发出的 DQS 若只按一个固定延迟走,只能和其中一颗对齐。write leveling 让控制器在上电后逐个调整发给每颗颗粒的 DQS 延迟,利用颗粒内部反馈把 DQS 与该颗粒看到的 CK 对齐。它校准的是「DQS 与 CK 的跨拓扑关系」,和下一节里校准「DQS 与 DQ 关系」的 read/write training 不是同一件事。
四、读时序与写时序:方向一反,责任全反
把第三节的两种对齐落到完整事务上,可以看到读和写几乎是镜像关系:谁发 DQS、谁偏相位、预充(preamble)长什么样、训练时调哪条延迟链,全部相反。
| 维度 | 写(控制器 → DRAM) | 读(DRAM → 控制器) |
|---|---|---|
| DQS 发出方 | 控制器 | DRAM |
| 到达颗粒/控制器时的对齐 | 边沿对齐 | 中心对齐(片内 DLL 偏 90 度) |
| 采样方内部动作 | DRAM 把 DQS 偏相移后进数据眼 | 控制器直接用 DQS 沿采样 |
| 总线方向切换 | 控制器先驱动 DQS,再发数据 | DRAM 先出 preamble,控制器先开 DQS gate |
| 上电校准内容 | write leveling(对 CK)+ write delay training(对 DQ) | read training / read DQS gate training |
| 典型失败现象 | 部分颗粒写花、固定字节报错 | 读数据在码型边界偶发错、gate 早开读到毛刺 |
读方向有个写方向没有的额外动作:DQS gate(读选通门控)训练。总线空闲时 DQS 上没有有效翻转,控制器必须在 DRAM 真正回数据前「打开」接收 DQS 的使能,读完立刻关上。门开早了会把总线上的噪声或 preamble 边沿当数据,开晚了丢第一拍。read DQS gate training 就是逐比特测出这个开关时刻,再配合 read data training 把采样点挪进数据眼中心。写方向对应物是 write delay training:调控制器侧 DQ 相对 DQS 的延迟,让数据眼恰好包住 DRAM 内部偏相移后的采样沿。
DDR4 还引入了更细的 per-DQ(也称 Vref 或读数据)training:逐位独立测量最佳延迟,因为同一字节内 8 根 DQ 的等长误差和 I/O 延迟也不完全一致,一个字节共用一个延迟值已经不够。到 DDR5 这类颗粒内部还分担了更多训练职责,但「gate 定边界、delay 定中心、逐位收敛」的骨架没有变。
五、建立保持裕量:UI 是怎么被花光的
采样可靠的数学条件并不神秘,和芯片内部一样是建立时间与保持时间:采样沿到来前数据必须稳定至少 t_SU,到来后必须继续稳定至少 t_H。这套约束在静态时序分析(STA)里对应 setup/hold 检查,DDR 接口的特殊性只在于参与扣减的误差项全部来自板级物理世界。
以读方向中心对齐为例,半 UI(DDR 双边沿采样,每边只剩半个单位间隔)的名义裕量要依次支付:DQS 与 DQ 的走线不等长、颗粒 I/O 输出离散度、DLL 量化误差、DQS 占空比失真、DQS/DQ 抖动、串扰与 ISI(码间干扰)、控制器接收端的建立保持要求。剩下的才是真正可用于温度、电压长期漂移的余量。
| 裕量扣减项 | 来源 | training 能否补偿 |
|---|---|---|
| 走线等长残差 | PCB 几何长度差 | 可,延迟链逐拍抵消 |
| I/O 延迟离散 | 工艺批次差异 | 可,上电实测后写寄存器 |
| DLL 量化误差 | 延迟抽头有限分辨率 | 不可,只能靠更细抽头缓解 |
| 抖动(jitter) | 电源噪声、串扰 | 部分可,中心对齐最大化左右余量 |
| 反射与 ISI | 阻抗失配、码型相关 | ODT 缓解电气层,training 缓解采样点 |
| 温压漂移 | 运行环境变化 | 需周期性重训(如 ZQ 校准配合) |
这张表解释了一个常见疑问:既然 DQS 随路,为什么还要规定严格的 PCB 等长?因为随路只保证两条路径共同漂移,制造时刻留下的固定长度差仍然直接吃裕量;training 的延迟抽头分辨率也有限,不可能拿数字电路无限补偿物理布线。软件能补的是「可测、慢变、抽头分辨率以内」的部分,电气层的账得在 PCB 上先还掉。
六、ODT 与 training:在物理层和动态层各挣一笔余量
高频信号到达阻抗不连续点会反射,反射回来与原信号叠加造成眼图闭合,这是封装与信号完整性讲过的传输线问题。DDR 早期靠主板上的终结电阻,DDR2 起把终结电阻做进 DRAM 芯片,这就是 ODT(On-Die Termination,片上端接):控制器在写事务期间命令目标颗粒打开 ODT,让信号线在接收端匹配特性阻抗,反射在产生处就被吸收;读事务时则由控制器侧的终结接管。ODT 还分出多个阻值档位(如 240/120/60/40 欧姆并联组合),配合不同颗粒数与拓扑,通过模式寄存器选择。ODT 解决的是「数据眼本身张不开」的问题——眼都没有,training 找到的采样点也毫无意义。
training 解决的则是「眼在那里,但每块板、每颗芯片的位置都不同」的问题。整个上电校准可以看成一条逐级收敛的流水线:
图中蓝色节点是测量动作,橙色是电气前提,绿色是收敛判据,紫色是长期运行态。顺序不能颠倒:ODT 和 ZQ 没就绪时测出来的眼是变形的;write leveling 没做,DQS 连 CK 域都对不上,数据域训练无从谈起;gate 不定边界就找中心,第一拍数据可能整体错位。各代 DDR 的训练名目不断增加(DDR4 加 Vref training、CA training,DDR5 把部分训练移入颗粒并支持上电并行加速),但「先电气、再时钟域、再数据边界、最后眼中心」的依赖关系一直稳定。
最后区分三个容易混淆的角色:ODT 是被动电气元件,训练期间和正常工作期间都在,作用是让信号不反弹;training 是主动测量流程,上电跑一次或在温压变化后重跑,作用是把延迟值写进控制器和颗粒的寄存器;ZQ 校准则专门校准输出驱动阻抗和 ODT 阻值,通常挂在周期性维护里。三者共同保证一个结果:在每块个体不同的板子上,采样沿都落在数据眼中心并留有对称余量。想看这些事务在系统层面怎么被调度排进刷新和访问空隙,可以参考 DRAM 子系统的 channel、rank 与调度器全景。
这一篇在知识体系里的位置
本篇讲的是控制器与 DRAM 之间那段物理接口的时序概念。想从触发器级看清双边沿怎么发、怎么收,回到SDR 与 DDR IO 寄存器;想理解建立/保持检查在芯片内部的一般形式,读静态时序分析(STA);ODT 背后的反射、阻抗与眼图机制展开在封装与信号完整性(SI/PI);训练完成后的读写、刷新、bank 并行如何被内存控制器编排,则在DRAM 子系统全景。四篇分别回答「电路怎么拼、时序怎么算、信号为什么变形、事务怎么调度」,本篇卡在它们的交叉点:数据跨过 PCB 的那半个 UI。
总结
DDR 接口时序概念的主线是一句话:频率高到系统时钟的偏斜无法容忍后,DDR 改用源同步——发送方让 DQS 与 DQ 随路传输,共担路径误差;写时序在 DRAM 引脚呈边沿对齐、由颗粒内部偏相移采样,读时序由 DRAM 用 DLL 输出中心对齐 DQS、控制器直接采样,fly-by 拓扑下再用 write leveling 逐颗粒对齐 DQS 与 CK。可靠采样的条件仍是经典的建立/保持窗口,半 UI 的名义裕量要支付走线残差、工艺离散、抖动、反射等一系列账单,PCB 等长负责物理层还账,ODT 在片内吸收反射让数据眼张开,read gate、read/write delay 等 training 则在上电时逐字节乃至逐位测出门控边界和眼中心。理解「随路、对齐、裕量、校准」这四组概念,比记住任何一代 DDR 的具体训练步骤都更耐久。