ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

DDR3读写训练:Write Leveling、Read Gate与VREF

DDR3读写训练:Write Leveling、Read Gate与VREF 1. 先弄明白 DDR3 读写训练到底在解决什么问题DDR3 Read/Write training 这个东西第一次接触的人往往会把它当成一个玄学调参环节——板子焊好内存颗粒也焊好为什么不能直接跑非得在初始化的时候折腾一大堆扫描、采样、找窗口的流程我刚接触这块的时候也这么想直到自己拿示波器量了一次 fly-by 拓扑上的 CK 和 DQS才真正明白训练到底在补什么窟窿。先把结论放在前面DDR3 的 Write training写方向和 Read training读方向本质上都是在给内存控制器和颗粒之间那一段已知很烂的物理链路打补丁。DDR3 从 800MT/s 一路跑到 2133MT/sUIUnit Interval一个数据位的宽度从 1250ps 缩到 937ps 甚至更小而 PCB 走线的飞行时间偏差、颗粒内部 DLL 的相位抖动、tDQSS 和 tDQSCK 这两项参数本身允许的误差范围加起来很容易就把时序窗口吃掉一大半。控制器不训练等于闭着眼睛往一个已经歪掉的窗口里塞数据。这篇文章我打算把 DDR3 的这几个训练环节从头拆一遍Write Leveling 在做哪件事、Read Gate也叫 Read Leveling在框什么、DQ/DQS 的 data eye training 怎么找中心、VREF 在 DDR3 上为什么和 DDR4 完全不是一回事。适合正在做 DDR3 控制器 bring-up 的驱动/固件工程师也适合画 DDR3 板子想搞清楚自己布线余量到底留给谁的硬件同学。看完全文你会知道每一步训练背后那个为什么以及实际调的时候哪些坑是别人不会写在手册里的。1.1 从时序窗口说起为什么上电后内存不能直接用要理解训练得先接受一个前提DDR3 的物理层从来就不是理想同步的。写方向控制器→颗粒上控制器发出 CK、地址、命令和数据。地址命令走的是 fly-by 菊花链拓扑从控制器出来先到第一颗颗粒再到第二颗、第三颗每条走线都要经过一段传输线延迟。数据线 DQ/DQS 则是另一套拓扑通常是点对点或者 T 型走线长度和 CK 那条链路完全不一致。结果就是CK 到达第 N 颗颗粒的时刻和 DQS 到达第 N 颗颗粒的时刻差了一个几皮秒到几百皮秒不等的飞行时间差flight time skew。DDR3 规范里给 DQS 相对 CK 的偏移留了一个 tDQSS 参数正常是 0.75 到 1.25 个 tCK。也就是说颗粒本身就允许 DQS 比 CK 早到 25% 或者晚到 25%。单看这个数字好像还好但当周期只有 1.25ns 时25% 就是 312ps再加上走线 skew 和颗粒间的不一致控制器如果不做补偿写进去的数据很可能在颗粒端被采在 DQS 的跳变沿附近眼图直接闭合。读方向颗粒→控制器问题更大。颗粒收到读命令后内部的 DLL 会重新生成一个和 CK 对齐的 DQS 往外发这个 DQS 相对 CK 的偏移就是 tDQSCK。DDR3 的 tDQSCK 范围非常宽松不同颗粒之间、同一颗颗粒在不同温度和电压下都会漂。控制器那边根本不知道 DQS 什么时候会到也就不知道 FIFO 该在哪个时刻打开来锁存这一拍数据——这就是为什么要做 Read Gate training。所以训练不是优化是让链路能通。跳过训练的 DDR3 系统短走线、低速率、单颗颗粒的情况下可能侥幸能跑但只要颗粒数一多、速率一上 1600基本必挂。1.2 训练的三层目标相位、电平、时序我习惯把 DDR3 的训练拆成三层来看这样排查问题的时候能快速定位是哪一层没收敛。第一层是相位对齐解决的是信号什么时候到的问题。Write Leveling 属于这一层它把每个颗粒写方向的 DQS 相位拉到和 CK 对齐Read Gate training 也属于这一层它把控制器的读采样门拉到 DQS preamble 的位置。第二层是电平判决解决的是这个电压算 0 还是算 1的问题。DDR3 的 VREFDQ 是外部电阻分压送进来的参考电平通常取 VDDQ 的一半。参考电平偏了眼图的上下半区就不对称训练出来的窗口会偏中心。DDR4 把 VREFDQ 搬到了颗粒内部MR6可以逐颗粒、逐 bit 调DDR3 没有这个能力所以电平这一层更多是靠板级设计保证。第三层是逐位时序解决的是每个 bit 采样点落在哪的问题。DQ data eye training 就干这个它在相位和电平都定下来之后扫每个 DQ bit 的延迟找通过率最高、窗口最居中的那一点。这三层的顺序不能乱。相位没对齐就做 data eye扫出来的窗口会随着温度和电压漂得你怀疑人生。先把飞行时间差补偿掉再去抠每个 bit才是正确的推进方式。2. 核心概念拆解Write Leveling、Read Gate 与 DQ 训练这一节把 DDR3 训练里最核心的三个环节讲透。网上很多资料只给流程不给原理导致调的时候出了问题不知道怎么改所以我把每个环节为什么这么设计的部分补上配合实际能落地的操作方法。2.1 Write Leveling把每颗颗粒的写 DQS 拉回 CKWrite Leveling 是 DDR3 相对 DDR2 新引入的机制它存在的原因就是 fly-by 拓扑。DDR2 时代地址命令和数据线都用 T 型拓扑CK 到每颗颗粒的走线长度基本一致不需要逐颗粒补偿。DDR3 为了在高频下保证地址命令的信号完整性把 CK/ADDR/CMD 改成 fly-by代价就是每颗颗粒看到的 CK 时刻不同必须逐颗校准。它的工作原理说起来很巧妙颗粒在一个特殊模式下不去做正常的数据读写而是用写方向的 DQS 去采样 CK采到的结果通过DQ0 这颗引脚反馈回控制器。控制器逐步增加自己发出的 DQS 延迟颗粒反馈的值会从 0 变到 1这个跳变点就是 DQS 和 CK 对齐的位置。具体流程大致是这样几步把 MR1 的 A7 位置 1使能颗粒的 Write Leveling 模式。控制器发起一次写入操作产生一个 DQS 脉冲。注意这期间不需要真正的数据有意义DQ 是空跑。颗粒用 DQS 上升沿采样 CK把结果从 DQ0 输出。如果 CK 采样到是低电平反馈 0是高电平反馈 1。控制器扫描内部 DQS 延迟比如从 0 扫到 32 个 tap每个 tap 采样很多次通常 16 到 64 次统计 1 的比例。找到 0 到 1 的跳变区间取区间的中心作为最终延迟值。这里有几个容易踩的细节。第一颗粒内部对 DQS 到 DQ0 的输出本身有延迟而且这个延迟随温度变所以单次采样的结果会抖。这也是为什么要采样很多次取统计值而不是采一次就定。第二扫描的粒度要足够细一般控制器支持 1/64 tCK 甚至更细的相位调节太粗的话跳变点定位不准。第三Write Leveling 做完之后一定要把 MR1 的 A7 位清 0 退出这个模式否则后面正常读写会出问题——这个我见过不止一次有人忘记退出然后对着内存能初始化但读写全错的现象调了两天。还有一个前提条件x4 颗粒不支持 Write Leveling。如果你用的是 x4 的 DDR3MR1 A7 这个位是保留的飞线回来也没用。x4 颗粒一般用 T 型拓扑靠控制器侧的静态延迟补偿就够了。x8 和 x16 才需要逐颗粒做。2.2 Read Gate Training把 DQS preamble 框进采样门里Read 方向和 Write 方向的训练思路不太一样。写方向控制器是发送方可以自己调延迟读方向控制器是接收方颗粒什么时候把 DQS 发回来它控制不了只能猜。控制器的读通路里有一个门控信号gate它的作用是在 DQS 到来之前保持关闭避免噪声或者前一拍残留的边沿误触发在 DQS preamble 到来时打开让 DQS 作为 FIFO 的写时钟去锁存 DQ。这个 gate 的开启时刻如果偏早了会把 preamble 前的噪声锁进去偏晚了会丢掉 preamble 甚至第一个数据沿。Read Gate training 就是扫描这个 gate 的相位找 DQS 有效的位置。具体做法通常是控制器往一段内存写一个已知的模式然后反复读边读边扫 gate 延迟记录每次读回的数据是否正确。所有正确的 gate 位置会形成一段连续区间这个区间的中心就是最佳值。这里有个 DDR3 特有的难点DDR3 的 read preamble 只有 1 个 tCK而且不像 DDR4 那样可以编程成 1/2/3 个 tCK。窗口本来就窄再加上 tDQSCK 范围很大DDR3-1600 典型在 -400ps 到 500ps扫描范围必须覆盖足够的宽度否则可能整段窗口都落在扫描区间外面看到的现象就是所有 gate 位置都读错。遇到这种情况先别怀疑训练算法先把扫描范围拉大试试。训练用的数据模式也有讲究。常见的有 0x55/0xAA 交替、PRBS 伪随机序列还有利用颗粒自带的 MPRMulti Purpose Register。MPR 是 DDR3 里一个很好用的功能把 MR3 的 A2 位置 1 使能A1:A0 选择 4 个预定义 pattern 之一然后读的时候颗粒不读存储阵列而是直接输出这个固定 pattern。因为 pattern 完全已知且和存储阵列无关特别适合做训练和调试。缺点是用 MPR 的时候不能同时做 Write Leveling两个模式得分开用。2.3 DQ 眼图训练与 VREF 调整把窗口中心抠出来相位对齐做完接下来才是逐 bit 的精细活。写方向的 DQ training 是控制器调自己每个 DQ 相对 DQS 的输出延迟目标是让数据在颗粒端被 DQS 采在眼图正中间。做法是控制器写一组 pattern然后读回来比较——注意这时候读方向可能还没训练好所以更稳妥的做法是先保证读通路基本可用或者干脆利用某些控制器支持的写-读回环比如通过颗粒的 MPR 读回写入的数据。扫描每个 bit 的 DQ 延迟记录 pass/fail找到通过的窗口取中心。读方向的 DQ training 则是调控制器的采样点在每个 bit 上扫 DQS 的采样相位同样记录 pass/fail 窗口取中心。这一步和 Read Gate 的关系是Gate 定的是什么时候开始采DQ training 定的是在这个窗口里具体哪个点采。VREF 这块必须单独说因为 DDR3 和 DDR4 在这上面的差别经常被搞混。DDR3 的 VREFDQ 和 VREFCA 是外部提供的板子上用两个等值电阻从 VDDQ 分压出来送到颗粒的 VREFDQ/VREFCA 引脚。分压电阻的精度、位置、去耦都会直接影响判决电平所以 DDR3 的板级设计里这两个网络特别敏感。DDR4 把 VREFDQ 集成进颗粒内部MR6 可编程才实现了真正的逐颗粒 VREF 训练。那 DDR3 能不能做 VREF 训练取决于控制器。有些 SoC 的 DDR 控制器内部有自己的 VREF 生成电路可以扫描参考电平找眼图中心这种就是控制器侧的 VREF training和颗粒无关。如果控制器没有这个能力VREF 就固定为 VDDQ/2这时候板级设计的重要性就被放大了——分压电阻必须选 1% 精度尽量靠近颗粒放VREF 走线要加去耦远离 DQ 走线以避免串扰。3. 实操流程从上电到训练收敛的完整链路前面讲了原理这一节讲怎么落地。我把一次完整的 DDR3 训练流程按顺序拆开每一步都说明在做什么、判断标准是什么、出了问题往哪看。3.1 硬件前提布线规则对训练结果的直接影响训练算法再强也救不了烂板子。DDR3 的布线规则里有几条是直接决定训练能不能收敛的我按重要性排一下。同 byte lane 内 DQ 和 DQS 必须同层、等长。一个 byte lane 就是 DQ0-DQ7 加上 DQS0 这一组它们必须走同一个信号层参考同一个平面长度控制在 DQS 的 ±5mil严格一点 ±2mil以内。为什么因为训练是按 byte lane 为单位做的lane 内 skew 太大会导致某些 bit 的窗口偏出扫描范围表现出来就是这个 lane 里总有那么一两个 bit 训不过。DQS 差分对内等长要非常严格一般要求 ±5mil 以内阻抗控制到差分 80 欧姆对应单端 40 欧姆。DQS 和 DQS# 长度差太多会直接吃掉眼图水平方向的余量。CK 差分对同理对内等长 ±5mil而且 CK 的走线要尽量短、尽量直避免过孔换层。CK 是 fly-by 拓扑的基准它抖一点后面所有颗粒的 Write Leveling 都要跟着重来。ADDR/CMD 相对 CLK 的等长在 fly-by 拓扑里是分段的从控制器到第一颗颗粒再从第一颗到第二颗每一段都要单独匹配。不能像 T 型拓扑那样整体拉长。走线间距用 3W 原则DQ 之间、DQ 和 DQS 之间、数据组和地址组之间都要拉开减少串扰。串扰会直接把眼图压扁训练出来的窗口看起来很窄误码率上不去。还有一点容易被忽略VREF 分压电阻的位置。这两个电阻要尽量靠近颗粒的 VREFDQ/VREFCA 引脚走线短且加 0.1uF 去耦。VREF 上哪怕有几十毫伏的噪声判决门限就偏了读窗口直接不对称。3.2 训练前的寄存器与大前提检查真正开始训练之前有一批寄存器必须先配置好否则训练出来的结果没有意义。MR0里要确认 burst lengthBL8 还是 BC4、CAS LatencyCL、写恢复时间WR这些是正常读写的时序基础。MR1要设置 DLL enable必须使能训练依赖 DLL、输出驱动强度ODS、RTT_Nom 端接电阻以及后面要用到的 Write Leveling enable 位。MR2设置 RTT_WR 和 CWL写 CAS Latency。MR3在需要 MPR 时打开。除了寄存器还要检查几个大前提DLL 是否锁定。颗粒的 DLL 有锁定时间要求一般 512 个时钟周期训练前必须等够。电源是否稳定。VDD、VDDQ、VTT 都要在范围内特别是 VTT 端接电源纹波大了会严重影响飞线信号质量。时钟是否稳定。CK 频率确认无误PLL 锁定。温度是否在可控范围。训练一般在常温做如果板子会工作在宽温环境训练结果要做温度补偿或者定期重训。我一般会建议在训练前先做一次裸读裸写测试不训练直接按最宽松的时序读写一遍看看能不能过。如果连最宽松的时序都过不了说明硬件有问题这时候去调训练是在浪费时间。3.3 分步执行Write Leveling 到 DQ 训练的完整顺序一次标准的 DDR3 训练顺序大致如下我按实际执行的先后列出来第一步上电初始化。上电、复位、CK 稳定、CKE 拉高、DLL 锁定、配置 MR0-MR3 基本信息。第二步Write Leveling。逐颗粒或逐 rank 里的每颗颗粒执行。打开 MR1 A7扫描 DQS 延迟采样 DQ0 反馈找跳变点记录每个颗粒的写延迟。完成后关闭 MR1 A7。多 rank 的系统要对每个 rank 单独做因为 rank 之间的走线长度不同。第三步Read Gate Training。逐个 byte lane 执行。写已知 pattern扫描 gate 相位记录读正确的窗口取中心。多颗粒系统要按颗粒分别做因为 read 返回的 DQS 时刻不同。第四步Read DQ Training。在 gate 定好的基础上逐 bit 扫采样相位找每个 bit 的通过窗口中心。第五步Write DQ Training。逐 bit 调控制器的 DQ 输出延迟通过写-读回环或者 MPR 验证找窗口中心。第六步VREF 调整可选。如果控制器支持内部 VREF 生成扫描参考电平如果不支持跳过靠板级设计保证。第七步保存结果并验证。把训练出来的延迟值存到控制器寄存器然后跑一遍完整的内存测试比如全地址范围的 marching pattern 或者 PRBS 校验确认无误码。整个流程一般几百毫秒到几秒不等取决于扫描粒度和采样次数。训练时间是可以换精度的采样次数越多结果越稳但耗时越长。3.4 参数计算与窗口评估怎么判断训练结果好不好训练跑完了怎么知道结果能不能用我给你几个我自己常用的判断标准。Write Leveling 的跳变区间宽度。理想情况下扫 DQS 延迟时读到 0 的连续区间和读到 1 的连续区间应该各占一半左右跳变点清晰。如果跳变区很宽比如 0 和 1 混在一起分不清说明采样不稳定可能是 ODT 设置不合适或者参考电平偏了。如果整个扫描范围都是 0 或者都是 1说明扫描范围不够或者走线太长超出了补偿能力。Read Gate 窗口宽度。记录所有读正确的 gate 位置算一下连续区间的宽度。一个 UI 是 1/(2×数据速率)比如 DDR3-1600 是 1250ps。如果窗口宽度能到 0.3 UI 以上基本可用到 0.5 UI 以上比较健康只有 0.1 UI 那就很危险温度和电压一变就挂。DQ 训练窗口。逐 bit 看每个 bit 的通过窗口取其交集。最差的那个 bit 决定了整个 byte lane 的余量。如果某个 bit 的窗口明显比别人窄先查这一路的走线是不是有问题或者这颗 DQ 引脚焊接不良。窗口中心的偏移。训练取的是窗口中心但如果所有 bit 的中心都朝一个方向偏说明 VREF 偏了或者 CK 相位有系统性偏差值得回头查一下板级。4. 常见问题与排查技巧实录训练环节出问题的现象五花八门但归到底就几类。这一节我把遇到过的典型问题整理成表再补充几条手册里不会写的经验。4.1 常见现象速查表现象最可能的原因排查方向Write Leveling 全 0 或全 1扫描范围不足、DQ0 反馈链路不通、MR1 A7 未使能加大扫描范围量 DQ0 波形确认寄存器写入成功Write Leveling 跳变区模糊ODT 不匹配、VREF 偏移、采样次数太少调 RTT_Nom检查分压电阻增加采样次数Read Gate 全错gate 扫描范围不够、DQS 没回来、MPR 模式冲突拉大扫描范围示波器抓 DQS确认 MR3 配置部分 bit 训不过该 DQ 走线异常、焊接不良、串扰量该 bit 的走线长度补焊检查 3W 间距训练能过但跑一会儿报错温度漂移、VREF 噪声、电源不稳加温度补偿、VREF 加去耦、检查电源纹波换批次颗粒后训练失败颗粒参数差异、tDQSCK 分布不同重新训练检查颗粒型号是否一致多 rank 系统只有一个 rank 过rank 间走线长度差异过大分别训练检查两个 rank 的走线等长低频能跑高频不过训练余量不足、走线太长提高扫描精度优化布线降低速率表格只能给个方向实际排查还是要靠示波器和眼图。我一直建议做 DDR3 bring-up 的人手边常备一台带眼图分析的高带宽示波器很多问题看波形三秒就定位了光看寄存器调一天也调不出来。4.2 几条踩过坑才懂的经验训练结果必须存下来。DDR3 的完整训练动辄几百毫秒如果每次上电都重训系统启动时间会很难看。正确做法是训练一次把结果写进非易失存储后续上电直接加载fast boot。但要注意加载的结果不一定永远有效温度大范围变化、电源电压变动、换了颗粒批次都可能让旧结果失效。我一般会做两级策略——正常上电加载缓存结果跑一段自检自检不过再触发完整重训。注意训练的时机。训练最好在系统各电源都稳定、温度也稳定的条件下做。有些板子上电瞬间电源还在爬升这时候训练出来的结果就是错的等到电源稳了反而不匹配。我一般在初始化流程里加一个延时等电源和时钟都稳定再开始。采样次数和稳定性是矛盾的。每个 tap 采样 64 次能得到很稳的结果但训练时间是 16 次的四倍。实际项目里我一般用 32 次作为平衡点对大多数板子够用。VREF 分压电阻别用错阻值。DDR3 的 VREF 标准是 VDDQ/2两个等值电阻分压。有人图省事用不同阻值凑出个接近的电压结果眼图上下严重不对称。老老实实用两个相同的高精度电阻。MPR 是个好东西但要记得关。用 MPR 做训练之后MR3 的 A2 位要清掉否则后续读操作全读的是 MPR 固定 pattern不读真实数据。这个坑我踩过一次现象是读回来的数据永远一样查了半天才发现是 MPR 没退。温度补偿不是可选项。DDR3 颗粒的延迟随温度变化很明显常温训练出来的窗口到了 70 度可能就偏了。如果系统工作温度范围宽要么做温度传感器触发的重训要么在训练时留足够余量比如只取窗口中心附近 60% 的范围。别忽略地址命令路径。绝大多数训练都在讲 DQ/DQS但地址和命令线在 fly-by 拓扑上也有飞行时间差虽然 DDR3 没有正式的 CA training很多控制器仍支持调节 CMD/ADDR 相对 CK 的延迟。如果数据训练都过了但还是偶发错误回头看看地址线的设置。5. 延展DDR3 为什么在有些平台上还在被沿用聊训练聊到这里顺便回应一下搜索里经常出现的几个疑问因为它们和 DDR3 的实际应用场景直接相关。5.1 部分平台沿用 DDR3 的技术考量DDR4 出来之后DDR3 并没有马上消失一些平台仍然支持 DDR3 或者同时兼容 DDR3/DDR4。原因很实在成本、生态和兼容性。DDR3 颗粒便宜、供货成熟、控制器 IP 到处都是对很多工业控制、网络设备、嵌入式场景来说DDR3 的带宽和容量完全够用没必要为 DDR4 支付额外的板级成本DDR4 对走线、端接、电源的要求更严。当内存控制器同时支持 DDR3 和 DDR4 时主板厂商可以基于同一颗 SoC 做出两种内存版本DDR3 版本价格更低面向对成本敏感的市场。这类设计里DDR3 那一版的训练流程和纯 DDR3 平台是一样的Write Leveling 和 Read Gate training 一个都不能少。至于经常被一起搜到的某些 GPU 配 DDR3之类的说法其实是个概念混淆——高端计算卡的显存用的是 HBM 这类高带宽方案和主板上的 DDR3 系统内存完全是两个层级、两个用途的东西。系统内存跑的是操作系统和应用程序的代码数据显存跑的是 GPU 的计算负载两者互不替代。搞清楚这个区别就不会被一些不准确的描述带偏。5.2 从颗粒引脚看训练相关的信号DDR3 颗粒常见的 96-ball FBGA 封装里和训练直接相关的信号其实就那么几组DQ0-DQ7 是数据线其中 DQ0 在 Write Leveling 时兼职做反馈DQS/DQS# 是数据选通差分对读写方向的采样基准CK/CK# 是系统时钟差分对ODT 控制片上端接ZQ 接精密电阻做驱动校准VREFDQ 和 VREFCA 是参考电平输入。看引脚图的时候有个细节值得注意每颗颗粒的 ZQ 引脚必须接一个 240 欧姆、1% 精度的电阻到地。这个电阻用来校准颗粒内部的输出驱动强度和 ODT 阻值。电阻精度不够或者走线太长驱动强度就偏训练出来的眼图会整体变差。我见过有人 ZQ 电阻用 5% 的凑合结果怎么训都过不了换成 1% 立刻就好——这种问题特别隐蔽因为从现象上看和走线问题一模一样。另外VREFDQ 和 VREFCA 是两个独立的参考输入虽然都取 VDDQ/2但走线要分开各自去耦不要图省事合并成一路。数据参考和地址参考分开能减少相互干扰。最后再说一句我自己的体会DDR3 的训练看起来繁琐但它的每一步都是有明确物理意义的不是玄学。你把 fly-by 的飞行时间差、tDQSS/tDQSCK 的范围、眼图的构成这三件事想透再看训练流程就会发现每一步都在补一个具体的窟窿。真正难的不是算法而是把板级设计、寄存器配置和训练参数这三者串起来看——很多时候训练不过不是算法的问题是走线或者端接的问题你不去量波形光在固件里扫参数是扫不出来的。所以我的建议是做 DDR3 bring-up 之前先把示波器和眼图摸熟比死磕训练代码有用得多。
返回列表