多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

NAND高速接口三剑客:DBI、ODT与差分信号解析

NAND高速接口三剑客:DBI、ODT与差分信号解析 入行做存储硬件这些年总有人问我NAND Flash的接口都跑到3600MT/s了为什么还要搞出DBI、ODT、差分信号这么多名堂是不是协议委员会没事刷KPI我每次都得从头解释一遍这三个技术一个治功耗一个治反射一个治噪声缺一个都跑不稳。NAND Flash从最早的SDR接口一路演进到ONFI 5.0定义的NV-DDR3接口频率上了好几个台阶信号完整性问题已经不是“可以忽略”的细节而是决定系统能不能稳定跑满速的关键。这篇文章不聊玄学以ONFI 5.0为参考把DBI、ODT和差分信号到底在解决什么实际问题、怎么在板级落地一次讲清楚。适合做存储控制器、Flash接口设计、信号完整性测试的工程师也适合刚接触嵌入式存储的开发者。1. NAND接口的提速之路从单端并行到高速信号完整性战场1.1 ONFI 5.0到底带来了什么做NAND Flash的人都知道ONFI标准从早期的SDR模式一路走来目前大力推进的是NV-DDR系列接口。ONFI 5.0把数据速率拉到了3600MT/s数据线还是8根但每一根线在1秒内要完成36亿次电平翻转单个UI周期大约只有277ps。这个速度下任何PCB走线都不能再被当成一根普通的“导线”看待它就是一根实打实的传输线。接口速度提高之后最直观的变化是信号上升沿变快。上升沿变快意味着信号中包含的高频分量大幅度增加PCB走线上的寄生电阻、电感和电容都会被激发出来。低速SDR模式下信号沿可能有好几ns反射导致的振铃虽然存在但会在采样点到来之前衰减掉大半大家普遍不关心。到了NV-DDR3的3600MT/sUI只有277ps反射振铃直接落在数据有效窗口里一个过冲接着一个下冲接收端根本分不清这个电平到底是1还是0。早期NAND Flash接口基本是“并行总线SDR同步”的简单模型控制器给个RE#下降沿颗粒就把数据送出来时序余量宽裕得很。ONFI 5.0协议之所以把DBI、ODT、差分DQS这些概念写进规范本质上就是因为频率上去了传统单端并行接口那套“干拉”逻辑已经不够用。协议委员会不是没事找事是在为高速传输扫清物理层的坑。1.2 协议里的三张牌DBI、ODT、差分信号把这三个技术放在一起对比会更容易理解它们的分工。DBI治的是“功耗和同步开关噪声”ODT治的是“反射和振铃”差分信号治的是“共模噪声和参考电平漂移”。它们不是同一层面的东西但都服务于同一个目标让高速信号在接收端被可靠地采样。DBI通过降低数据线翻转率来减少动态功耗同时压低多根线同时翻转时的地弹噪声ODT通过在芯片内部提供可调的端接电阻把传输线上的反射能量吸收掉避免信号在走线上来回弹跳差分DQS则通过一对互补信号来提供稳定的时序基准抵消掉电源地噪声对采样时刻的影响。三者叠加在一起才让3600MT/s甚至更高频率的NAND接口具备量产可行性。我经常用一个比喻一条高速公路要从双车道改成八车道DBI相当于限制所有车不要同时猛踩油门ODT相当于在入口和出口铺减速带和吸能墙差分信号则相当于给最关键的引导车装上了双天线导航避免旁边大车气流扰动它。没有这些机制车多了路面就崩。2. DBI数据总线反转用一次“反转”换回全局安静2.1 数据翻转为什么是问题在高速接口里数据线每翻转一次都要对线上的寄生电容充放电一次。动态功耗的基本公式大家都知道P C × V² × f频率f上去之后功耗本身就是线性增长。而数据线上的翻转次数和数据内容强相关随机数据平均有一半的线会在每个周期发生翻转如果刚好遇到最坏的数据模式8根线同时从0跳到1瞬间的电流尖峰非常可观。这个电流尖峰不只是浪费功耗它会在电源和地回路上产生di/dt噪声表现为地弹和电源塌陷。地弹严重的时候接收端的参考地电平会瞬间偏掉几百毫伏本来判决电平是0.8V结果地平面被顶起来0.2V那输入高电平看起来就只剩下0.6V了误码率立刻飙升。多个IO同时翻转时这种同步开关噪声SSN还会叠加数据线越多、速率越高、危害越明显。所以DBI解决的问题本质上不是“能不能省电”这种锦上添花的事而是“高速随机数据下SSN会不会把接口直接压垮”的事。尤其NAND Flash数据几乎都是随机化的固件还会做数据加扰数据模式很难人为控制。如果不在协议层做干预高速读写时的最坏情况会反复出现信号完整性根本没有保证。2.2 DBI的工作机制与量化效果DBI的编码逻辑并不复杂很多做过DDR/LPDDR的朋友应该很熟。它通常以8根数据线为一个字节组额外增加一根DBI_n标志线。发送端在发送每个字节之前先统计这8根数据线相对上一个周期的翻转数。如果翻转数大于4也就是至少5根线需要翻转那就把所有数据线整体反转一次并把DBI_n拉低表示“这组数据被反转过”如果翻转数小于等于4数据线保持原样DBI_n保持高电平。接收端看到DBI_n为低时只需要把收到的数据再做一次反转就能恢复出原始数据。这项机制在ONFI 5.0的NV-DDR3模式下被定义为可选但推荐的功能具体开关由Feature Register控制颗粒和控制器必须双方都使能才能正常工作。从统计上看随机数据原本每根线的平均翻转率是50%经过DBI编码之后数据线的平均翻转率会降到36%左右大概比原来少了三成的IO动态翻转功耗。更重要的是最坏情况下8根线同时翻转的概率被大幅压低SSN带来的地弹自然也被压制住了。DBI付出的代价是多一根标志线以及收发端各多一级解码逻辑延迟和它换来的稳定性相比这点代价完全值得。2.3 配置DBI的实操心得DBI这功能不是打开就万事大吉我踩过几次坑。第一次调试一个高速NAND读写工程打开DBI后跑全0和全1测试发现功耗几乎没变化一度怀疑固件没生效。后来换成伪随机序列测试才看到明显差异。原因很简单全0/全1模式下数据本来就不怎么翻转DBI没有发挥空间。所以验证DBI状态时测试数据模式非常重要。常见的做法是使用PRBS伪随机码、地址递增/递减配合取反或者干脆让固件写真实文件系统的随机数据。对比DBI开启和关闭两种状态下IO电源的电流差以及眼图质量才能真正看出效果。另一个容易忽略的地方是DBI一开接收端和发送端必须同时知道当前字节是否被反转。NAND本身作为存储颗粒写数据时由控制器决定编码读数据时需要颗粒返回原来写入的DBI状态。如果控制器配置了DBI但颗粒固件不支持或者Feature设置被异常复位读出来的数据会全部乱掉。这个问题排查起来非常隐蔽因为波形看起来完全正常电压幅值、时序都合规只是数据全错。所以配置DBI之后第一件事就是跑一轮读写比对测试确认数据面没有问题然后再去优化功耗。3. ODT片内端接把信号反射“消化”在芯片里面3.1 反射是怎么来的为什么高速下必须处理传输线上的信号遇到阻抗不连续的点会产生反射。反射系数公式是Γ(ZL-Z0)/(ZLZ0)当接收端输入阻抗远大于走线特性阻抗时Γ接近1意味着信号几乎被全反射回去。反射信号回到源端再被反射回来如此往复走线上就会出现过冲、振铃严重时振铃幅度超过芯片绝对最大额定值长期工作会损伤IO短时间则会直接造成误码。低速率下反射振铃虽然也存在但因为信号沿比较缓振铃周期相对于UI很小在采样判决时刻早就衰减得差不多了。可到了3600MT/sUI只有277ps信号在走线上传播一个来回可能就要几百ps反射振铃直接覆盖整个有效窗口。这种情况下如果没有端接吸收反射接收端的波形会像蹦床一样弹个没完。常用的外部端接方案包括源端串联电阻和接收端并联电阻它们在高频下有一定效果但也存在天然短板外部端接电阻距离芯片引脚还有一段封装stub和引脚电感在高速下这个stub会造成新的阻抗不连续。ODT则把端接电阻做在die内部尽量靠近接收电路反射点在芯片内部就被吸收掉效果更接近理想情况。3.2 ODT在ONFI 5.0里的工作机制ODT听起来是个很“硬”的功能实际上它的实现非常依赖校准。NAND颗粒会把端接电阻做成多个档位比如常见的40Ω、60Ω、120Ω等具体有哪些档位要看ONFI规范和颗粒数据手册。由于芯片制造工艺存在偏差标称60Ω可能实际做出来只有45Ω或80Ω所以ONFI方案普遍支持ZQ校准。ZQ校准的思路很直接芯片上有一个ZQ引脚需要外接一颗高精度参考电阻通常选240Ω误差尽量小于1%。上电后或者控制器下发校准命令时NAND内部校准电路会以这个外部电阻为基准把内部端接电阻的修调码调准确保最终呈现出来的端接阻值落在目标档位附近。这个过程就像先用标准砝码把秤校好再拿它去称东西秤本身不准其他都白搭。ODT的实际使用还要区分读写方向。NAND在写操作时是接收端主控发过来的信号经过走线到达颗粒颗粒那一端需要开启ODT吸收反射而在读操作时NAND是发送端它驱动信号往主控方向走这个方向上ODT是否开启就要看主控对端接的支持情况。ONFI 5.0支持的动态ODT本质上就是让端接窗口跟随读写命令动态切换避免端接始终开启导致多余的功耗和信号幅度损失。3.3 板级ODT配置经验与陷阱ODT配置没有一刀切的方案完全取决于系统拓扑。单颗NAND贴片、走线又短的话很多时候ODT关闭也能跑得很稳但到了多颗粒并联或者菊花链拓扑远端颗粒的反射问题会非常突出不开启ODT很难把眼图打开。我之前做过一个4颗NAND并联的设计默认ODT关闭时写操作的眼图上有明显振铃稍微提高频率就开始报错。逐档试完ODT阻值之后发现60Ω档效果最好但代价是信号幅度从1.0V降到0.85V。从波形上看幅度虽然小了一点但振铃大部分被吸收整体误码率显著下降。这个例子说明ODT不是越大越好阻值太低会把信号“吃掉”太多接收端判决余量反而变小阻值太高则吸收反射能力不够。正确做法是遍历各档位配合真实读写测试选出最均衡的那个点。还有一个常见坑是ZQ校准失败。我遇到过颗粒的ZQ电阻虚焊导致所有ODT档位校准结果都漂移表现为波形上反射没有被端接掉甚至冒出莫名其妙的平台。排查这个问题时先看一眼ZQ引脚电压和外部电阻焊接往往比反复改寄存器更快。另外温度变化会影响校准结果量产时需要确保ZQ校准在正常工作温度附近完成必要时每隔一段时间重新校准。4. 差分信号DQS从“单打独斗”到“双线协作”4.1 单端DQS在高速下的窘境NAND Flash在DDR/NV-DDR模式下数据同步靠的是DQS信号。读数据时NAND会在发送DQ的同时送出DQS写数据时主控则用DQS对准DQ的中间颗粒据此采样。可以说DQS就是整个数据通道的“节拍器”节拍器准不准数据采样就一定好不了。单端DQS的问题是它的判决依赖一个固定的参考电压Vref。信号高过Vref判为高低过Vref判为低。高速下地弹和电源噪声会让接收端的参考地电平不断晃动Vref本身也很难保持绝对干净于是单端DQS的边沿位置会跟着噪声左右抖动。对于3200MT/s以上的接口哪怕十几ps的抖动都可能吃光用户能够容忍的时序预算。差分DQS则是用一对互补信号DQS_t和DQS_c来表示同一个时钟边沿接收端以两条线的交叉点作为跳变参考。任何共模噪声比如地弹、电源塌陷、外部电磁干扰都会同时出现在两条线上接收端把两路信号相减之后共模分量被抵消得一干二净。交叉点因此比单端信号的Vref交叉点稳定得多。差分信号虽然多占一根走线但换来的是更可靠的时序基准这也是ONFI协议在高速NV-DDR模式下特别强调DQS差分对的原因。4.2 差分DQS的PCB设计要点差分DQS在PCB设计上不能简单当成“两根线一起走”。最基础的要求是线宽、线距满足差分阻抗100Ω左右单端对地阻抗尽量做到50Ω。等长方面DQS_t和DQS_c之间的长度差要控制在很小范围内最好小于5mil否则交叉点会因为两条线到达时间不一致而变模糊。实际布线时还要特别注意参考平面的连续性。DQS差分对换层时旁边一定要打足够多的地孔保证回流路径短而且连续如果参考平面被挖断差分阻抗会突变信号完整性立刻劣化。DQS与DQ之间也要保持安全间距因为DQS是基准信号它最怕被旁边高速翻转的DQ串扰。很多板子在检查时只保证DQ组内部等长忽略了DQS与其他信号之间的间距结果高速时DQS抖动大得吓人。还有一点容易被忽略差分DQS线路上的任何不对称都会把共模噪声转化成差模噪声。比如线宽不一致、过孔不配对、两端负载电容不同都会破坏信号的对称性。所以差分走线要尽量保持对称过孔要成对打不要让一边多一个电容或电感。4.3 在示波器上验证差分DQS调试NAND接口时差分DQS的输出质量是必须测的。理想情况用差分探头直接抓DQS_t和DQS_c的差分波形手头没差分探头的话也可以用两路单端探头分别抓P和N然后使用示波器的A-B数学功能合成差分波形。看差分波形时我一般关注三个点交叉点清不清晰、差模摆幅够不够、边沿有没有出现台阶。交叉点抖动如果肉眼可见那说明差分DQS的时序稳定性已经出问题了差模摆幅过低则可能影响接收端灵敏度需要查一查端接和信号链路损耗。有条件的话把示波器切到眼图模式叠加几万个UI直接看交叉点的垂直和水平余量。差分DQS的抖动目标应该远小于数据窗口的20%到30%具体数值要以系统误码率来定。顺便提一句很多工程师习惯只测数据线DQ的眼图不测DQS。实际上一旦数据传输出错先看DQS往往比看DQ更快定位问题。DQS是“节拍器”节拍器乱跳数据眼图再好看也没有用。5. 从协议到板级落地中的关键细节与问题排查5.1 让DBI、ODT这些协议功能真正生效的三步配置协议规范写得再好最后都要落到控制器初始化和板级验证上。结合我做过的几个高速NAND项目建议按下面三步走。第一步先读设备。控制器上电后通过ONFI参数页把颗粒的Feature信息读出来确认当前NAND是否支持DBI、ODT支持哪些ODT阻值档位。不同厂商、不同制程的颗粒支持情况会有差异不能想当然认为ONFI 5.0就全带。第二步再写配置。在初始化序列里通过Set Features命令启用对应功能把ODT阻值和动态窗口配置好必要时还要完成ZQ校准。嵌入式平台通常还需要在设备树或者board file里设定timing mode让控制器进入对应的NV-DDR3速率档。这个阶段一定要反复确认写入寄存器的值和预期一致很多“信号问题”其实都是配置没生效。第三步后量测验证。配置完成后先跑一轮最简单的读写比对测试确认数据面正确然后再上压力测试。高速接口的最终验收必须靠示波器看波形有条件就抓眼图、统计误码率。寄存器显示“已启动”不代表波形合格只有量测通过才能说明ODT和DBI真实落地。5.2 常见问题排查速查表现象可能原因排查手法写数据随机错码频率升高更明显ODT未开启或ODT阻值档位不对检查Feature配置用示波器抓DQ/DQS波形看是否过冲、振铃读数据时DQS抖动大差分DQS不等长、参考平面不连续、与DQ串扰测量差分波形交叉点检查PCB走线对称性和间距功耗比预期高DBI未启用或测试数据模式翻转率太低配置DBI用PRBS随机序列对比功耗提高速率后训练失败ODT/DBI/timing组合需要重新训练执行完整training流程不要只调单个参数ZQ校准失败ZQ电阻虚焊、阻值不对或校准温度异常检查外部参考电阻重新校准并核对电压这张表其实覆盖了我实战中遇到的大部分问题。很多朋友一上来就怀疑PCB布局、怀疑电源噪声结果查了一整天最后发现是U-Boot里ODT配置被默认值覆盖了。所以我建议出问题时先过一遍协议配置再做信号量测顺序反了会浪费大量时间。5.3 调试NAND高速接口的个人经验做高速NAND调试这几年我最大的体会是先把初始化代码按协议文档逐条核对再去动烙铁和示波器。ODT、DBI这些功能一旦配置错波形上表现出来的症状和真正的PCB问题非常相似很容易把人带偏。我见过太多次“假信号问题”最后都是寄存器里一个bit没写对。测试pattern一定要多准备几种。全0、全1、PRBS、地址递增递减、真实文件系统数据至少五种轮着跑。别指望一个伪随机序列就能覆盖所有最坏情况不同数据模式对DBI、SSN的影响差很多。想验证系统上限就要把最不利的翻转模式主动构造出来。最后再分享一个小技巧数据线和DQS的走线长度匹配不要只盯着PCB总长看。DQS交叉点与DQ中心是否对齐还受封装延时、过孔延时、芯片内部路径差异影响。条件允许的话用仿真或者示波器实测一下tDQSS/tDQSQ用真实延时去做调整比单纯把PCB等长调到0.1mm更有效。毕竟高速接口容不得“差不多”每一百ps的偏差都可能决定系统能不能稳定跑在3600MT/s。
返回列表