2. Self-Refresh 技术基础

2.1 DRAM 为什么要刷新?

DRAM 的存储单元说白了就是一个电容加一个晶体管。电容会漏电,数据放久了就丢了。所以我们必须周期性地给电容“充电”,也就是 refresh。这个周期一般是 64ms(商业级)或 128ms(工业级),具体看颗粒规格。我刚开始做低功耗项目时,一直觉得刷新是个“后台自动完成的活”,直到有一次 Self-Refresh 的时序没算对,导致芯片在睡眠模式下丢了数据…… 从那以后我就对这个环节特别敏感。

刷新操作本身很简单:激活一行 (ACT),然后立刻预充电 (PRE),不涉及列选。每次刷新一个 row,所有 bank 可以同时刷(同一 row 地址),但不同颗粒厂家的策略略有差异。

2.2 两种刷新模式:谁在干活?

为什么要有两种刷新模式?想想看——CPU 在工作时,内存控制器可以定期发送 REF 命令,这叫 Auto-Refresh。但芯片进入睡眠后,CPU 停了,PLL 也关了,谁来发 REF?这时候就需要 DRAM 自己给自己刷,也就是 Self-Refresh。

  • Auto-Refresh:由内存控制器主动控制,DRAM 处于“待命”状态,功耗较高(大约几十 mW)。
  • Self-Refresh:DRAM 内部定时器自己触发,不需要外部时钟,功耗极低(几 μW 到几十 μW)。

🔑 关键点:Self-Refresh 是低功耗状态的核心技术,几乎所有 LP-DDR、DDR3L/4 都支持。

2.3 Auto-Refresh vs Self-Refresh 对比

下面这个表格是我自己整理的项目笔记,每次做时序验证时都会拿出来对一遍。我建议你也把它存下来。

对比项 Auto-Refresh Self-Refresh
控制源 外部内存控制器 DRAM 自身定时器
功耗 高(活跃态) 极低(睡眠态)
时钟依赖 需要外部时钟 内部振荡器(不需外部时钟)
退出延迟 无(命令后可直接访问) 有(tXSNR / tXSR,通常几 μs)
使用场景 正常读写操作期间 低功耗待机、睡眠、保留
刷新间隔 由控制器按 tREFI 发出 内部固定 tREFI(与Auto相同)

⚠️ 业界误解:有人以为 Self-Refresh 时 DRAM 完全不耗电,其实它内部仍有一个微弱的振荡器和状态机在工作。我见过一个项目把 Self-Refresh 功耗估算为 0,结果电池续航差了很多。

2.4 进入和退出 Self-Refresh 的流程

以 DDR4 为例,时序大致是这样:

  1. 控制器等待所有 pending 的读写完成(bank idle)。
  2. 发出 PRE ALL 命令,所有 bank 预充电。
  3. 等待 tRP 之后,发出 SRR(Self-Refresh Request)命令,或者直接进入 CKE 低电平驱动的 Self-Refresh 模式(具体取决于协议)。
  4. DRAM 内部开始自行计时刷新,此时 CKE 保持低电平。
  5. 退出时,拉高 CKE,等待 tXSNR(退出 Self-Refresh 到第一个有效命令之间的延迟)。
  6. 发出 REF 命令或 ZQCL 完成校准后,恢复正常操作。

💡 我个人习惯在 RTL 验证时加一个形式化的断言:从 Self-Refresh 退出后必须至少间隔 tXSNR 才能发第一个读写命令。否则仿真能过,硅片上可能丢数据。

2.5 Self-Refresh 的时序验证要点

验证 Self-Refresh 时序时,我一般重点检查以下几点:

  • 进入条件:所有 bank 确实处于 idle,没有正在执行的 burst 或刷新。
  • 内部刷新间隔:Self-Refresh 时内部的 tREFI 是否完全覆盖了标准的 7.8μs(DDR4@85°C),或者更长的 3.9μs(高温)。
  • 退出时序:tXSNR(退出到第一个命令)、tXSR(退出到第一个刷新,部分标准)是否满足最小值。
  • 数据保持:长时间 Self-Refresh 时 DRAM 温度变化可能影响 refresh 周期,有些颗粒需要定期“唤醒”做温度补偿刷新。

2.6 知识结构图:刷新机制全景

下面这张图把 DRAM 刷新机制的两种模式串联起来了。你看一下箭头指向,就是你做时序仿真时需要理解的数据流。

DRAM 刷新机制 DRAM 刷新机制 Auto-Refresh Self-Refresh 外部控制器驱动 命令周期性发送 功耗 ~50mW 内部定时器驱动 无需外部时钟 功耗 ~10μW 关键区别 控制源、功耗、退出延迟、应用场景

2.7 实际项目中的一点踩坑记录

我曾经在一个 LP-DDR4 的项目里遇到 Self-Refresh 退出后数据不稳定的问题。分析后发现是退出时 DRAM 内部的 DQS 时钟恢复需要时间,而 SoC 的 PHY 提前发出了读命令。解决方案很简单:在 PHY 端增加一个来自 DRAM 的“准备好”信号检测,或者在设计中强制插入一个额外 NOP 周期。从那以后我养成了一个习惯:所有 Self-Refresh 退出路径的 STA 约束里,必须把 tXSNR 作为最大延迟检查,并把时钟恢复路径单独设为一个 false path 避免约束冲突。

⚡ 核心回顾:Self-Refresh 是实现极低功耗的关键,但时序验证时必须关注退出延迟、内部刷新间隔、温度补偿等细节。Auto-Refresh 和 Self-Refresh 的本质区别是谁来控制刷新时序——一个靠外部命令,一个靠内部定时器。

你如果在项目里碰到 Self-Refresh 时序 fail,先确认三个东西:进入时 bank 是否全部 idle、退出时是否等了足够长的 tXSNR、仿真模型里 Self-Refresh 的 tREFI 是不是正确的温度系数版本。做好这三步,大部分问题都能解决。