4. 初始化与校准:DDR初始化流程

DDR的初始化,说白了就是让颗粒从「冷启动」进入「正常工作」状态。这个过程如果没走对,后面读写数据全是错的。我刚开始调DDR的时候,就吃过这个亏——上电时序没卡好,结果数据眼怎么都睁不开。

嗯,咱们一步步来拆解。

4.1 DDR初始化流程

DDR颗粒的初始化,硬件上有一套固定的「剧本」。你得按顺序演,不能跳步。我习惯把它分成四个阶段:

  1. 上电与复位:先给电,再拉复位
  2. 时钟稳定:等PLL锁住,时钟干净了再往下走
  3. 配置寄存器:通过MRS命令写模式寄存器
  4. ZQ校准:校准输出驱动和ODT

核心要点:整个初始化过程,DDR控制器必须严格按照JEDEC规范的时间参数来发命令。比如tRFC、tMRD这些,少一个周期都不行。

4.1.1 上电与复位

上电时,VDD和VDDQ要同时上升。我见过有人只给VDD供电,VDDQ晚了几毫秒,结果颗粒直接锁死。嗯,这里要注意:

  • 上电后,CKE必须保持低电平至少100μs
  • 复位信号RESET#要拉低至少200μs
  • 之后释放复位,再等500μs才能开始配置

你想想看,这些时间参数在数据手册里都有,但很多人就是不看。我曾经在一个项目里,因为复位时间不够,DDR死活初始化不过去,查了两天才发现是时序问题。

4.1.2 配置寄存器

DDR颗粒内部有好几个模式寄存器(MR0~MR3)。你得通过MRS命令一个个写进去。我建议的配置顺序是:

寄存器 配置内容 典型值
MR0 突发长度、CAS延迟 BL=8, CL=11
MR1 DLL使能、ODT阻抗 DLL=1, ODT=40Ω
MR2 写恢复时间、CWL WR=6, CWL=9
MR3 MPR模式、温度补偿 MPR=0

我个人习惯在配置完每个寄存器后,读回验证一下。虽然DDR颗粒一般不会写错,但万一地址线有虚焊呢?

4.1.3 ZQ校准

ZQ校准说白了就是让DDR颗粒自己调整输出驱动强度。它通过一个外部电阻(通常是240Ω)来校准内部阻抗。

校准分两种:

  • 长校准:初始化时做一次,耗时512个时钟周期
  • 短校准:运行时定期做,耗时64个时钟周期

我的经验:ZQ校准完成后,一定要检查ZQ引脚的电平。如果一直高或一直低,说明校准失败了。这时候别急着重试,先查一下外部电阻有没有焊好。

4.2 FPGA端DDR校准

颗粒初始化完了,但FPGA这边还没完。你得让FPGA的DDR控制器和颗粒「对齐」。这一步叫校准,也叫训练。

为什么需要校准?因为PCB走线有延迟,温度电压会漂移。你不校准,数据眼可能根本不在采样窗口内。

4.2.1 DQS门控校准

DQS门控校准,目的是找到DQS信号的「有效窗口」。DQS在读操作时是边沿对齐的,你得把它移到数据眼中间。

具体做法:

  1. 发一个读命令,但不读有效数据
  2. FPGA内部产生一个门控信号,去捕获DQS
  3. 调整门控的延迟,直到找到DQS的上升沿和下降沿

我曾经在一个项目里,因为DQS门控没调好,读回来的数据全是0x55和0xAA交替。嗯,一看就知道是采样位置不对。

4.2.2 读数据眼训练

读数据眼训练,就是找到DQ数据在DQS边沿附近的「最佳采样点」。说白了,你要找到那个「眼睛睁开最大」的位置。

训练步骤:

  • 写一组已知数据到DDR(比如0xAA, 0x55)
  • 读回来,调整DQS的延迟
  • 找到数据正确的延迟范围
  • 取中间值作为最终延迟

关键点:读数据眼训练通常要遍历所有byte lane。每个lane的延迟可能不一样,因为PCB走线长度不同。我建议每个lane单独训练,不要偷懒用同一个值。

4.2.3 写数据眼训练

写数据眼训练和读训练类似,但方向相反。这次是FPGA往DDR颗粒写数据,颗粒内部也有一个采样窗口。

写训练的核心是调整DQS相对于DQ的相位。DDR协议要求DQS在写操作时是中心对齐的,但实际走线延迟会让它偏移。

我常用的方法:

  1. FPGA写一组数据到DDR
  2. 读回来检查是否正确
  3. 调整DQS的相位步进(比如每次1/32个时钟周期)
  4. 找到所有bit都正确的相位范围

注意:写训练时,DDR颗粒内部也有一个DLL。如果颗粒的DLL没锁住,写训练永远过不了。所以一定要先确认颗粒初始化完成,DLL锁定信号拉高。

4.3 校准流程总览

我把整个初始化+校准的流程画了一张图,方便你理解:

DDR初始化与校准流程 1. 上电与复位 2. 时钟稳定 3. 配置寄存器 4. ZQ校准 5. DQS门控校准 6. 读数据眼训练 7. 写数据眼训练 DDR颗粒初始化 ZQ校准 FPGA端校准

从图上你能看到,颗粒初始化是串行的,必须一步步来。而FPGA端的三个校准可以并行做,但实际中我建议还是串行做,因为资源够用,调试起来也方便。

我的建议:校准完成后,一定要做一次全地址的读写测试。写0xAA、0x55、0x00、0xFF,再读回来对比。如果全过,说明校准没问题。如果某个地址范围出错,大概率是时序裕量不够。

嗯,这一章的内容就到这儿。初始化与校准是DDR调优的基础,后面所有的高性能读写都建立在这个基础上。你想想看,如果初始化都没做好,后面的优化就是空中楼阁。

可可精品资料库