S01 —— DRAM:一个电容加一个晶体管,是怎么存一个 bit 的
金句:复杂系统背后,往往只有几个简单的物理原理在支撑。理解 DRAM,先从最底层的 Cell 说起。
1. DRAM Cell 的物理结构
1.1 什么是 DRAM
DRAM(Dynamic Random Access Memory)是目前几乎所有通用计算设备的主内存。从手机到服务器,从 PC 到超算,DDR SDRAM 是主存的代名词。
DRAM 的核心特征:
- 易失性(Volatile):断电后数据丢失
- 按地址随机访问:任何地址的访问延迟相同(不像 SSD 按块访问)
- 每个 bit 靠一个电容的充放电存储:密度极高
1.2 一个 DRAM Cell 的电路结构
一个 DRAM Cell 只由两个元件组成:
WL(Word Line,字线)
│
───────┤ NMOS T(晶体管,开关)
│
├───┬────────────── BL(Bit Line,位线)
│
────┴─────
████ ← 存储电容(Storage Capacitor)
───────── 电荷 → 1,无电荷 → 0
│
GND
两个端口:
- WL(Word Line):控制晶体管开/关,由行解码器驱动
- BL(Bit Line):读取/写入数据的数据线,连接到列放大器
一个 Cell = 1 个 NMOS + 1 个电容1.3 电容存储电荷的原理
电容的基本结构:两个导体之间隔着一个绝缘体
┌──────────┐
────│ Plate A │──────── 导体(接电路)
│ ↓↓↓ │
│ 绝缘层 │
│ ↑↑↑ │
└──────────┘
────│ Plate B │──────── 导体(接电路)
└──────────┘
电容存储的电荷量 Q = C × V
C:电容值(由面积和绝缘层厚度决定)
V:电压
在 DRAM 中:
- "存 1":电容充电到 VDD,电荷 Q1
- "存 0":电容放电到 0V,电荷 Q0
充电 = 写入"1"
放电 = 写入"0"
检测电压变化 = 读取2. Bit Line 和 Word Line:Cell 是怎么被访问的
2.1 Bit Line(位线)
每个 DRAM Cell 不直接连到放大器,而是通过共享的 Bit Line(BL)连接。
一个 Bit Line 连接多个 Cell(通常 256~512 个):
BL(Bit Line,共享)
│
Cell 0 ──┤ ├── Cell 1 ──┤ ├── Cell 2 ──┤ ...
│ │ │
WL0 WL1 WL2
Word Line 控制哪个 Cell 接入 BL
同一时刻,每个 BL 上只有一个 Cell 接入
BL 的电压由列放大器(Sense Amplifier)检测。2.2 Word Line(字线)
Word Line 决定哪个 Cell 被选中接入 Bit Line。
Word Line 的工作原理:
WL=0(未选中):
→ NMOS 截止
→ Cell 与 BL 断开
→ 该 Cell 的电荷保持不变(静态保存)
WL=1(选中):
→ NMOS 导通
→ Cell 的电容与 BL 连通
→ 可以进行读/写操作
行地址解码器(Row Decoder):
→ 接收行地址(Row Address)
→ 选通对应的 Word Line
→ 一次选通一整行(所有 Cell 同时接入 BL)3. DRAM Array:Bank / Row / Column 的层次结构
3.1 从 Cell 到 Bank
单个 DRAM Cell 太小,无法独立寻址。DRAM 按层次组织:
DRAM 的组织层次:
Cell → Word Line Group → Subarray → Array → Bank → Channel
Cell:
- 1 个 bit 的存储单元
- 1 个 NMOS + 1 个电容
Word Line(字线):
- 横向排列,控制一整行 Cell 的选通
- 一次选通 1024~8192 个 Cell
Bit Line(位线):
- 纵向排列,连接一整列 Cell
- 每列一个 Bit Line
Subarray(子阵列):
- 256~512 行 × 512~1024 列
- 有自己的本地 Sense Amplifier
Array(阵列):
- 多个 Subarray 并排
- 共享列解码器
Bank:
- 多个 Array 组成一个 Bank
- 有独立的行解码器和列解码器
- 可以独立接受命令3.2 Bank 的详细结构
一个 Bank 的内部结构:
Column Decoder
│
Row Decoder ───┤├──┬──┬──┬──┬──┐
│ │ │ │ │ │
┌────┴──┴──┴──┴──┴──┴──┐
│ Array 0 │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │ │ │ │ │ │ │
│ │ SA│ │ SA│ │ SA│ │ ← Sense Amplifier
│ │ │ │ │ │ │ │
│ └───┘ └───┘ └───┘ │
└─────────────────────┘
Bank 的寻址能力:
- 行地址(Row Address):选通哪一行 Word Line
- 列地址(Column Address):在选中行中选择哪些列
- 一次 Row 激活 → 多列数据可以突发读取3.3 多 Bank 并行
现代 DRAM 芯片有多个 Bank(通常是 4~8 个),每个 Bank 可以独立工作。
多 Bank 并行的好处:
Bank 0:读取 Row 0 ← 正在操作
Bank 1:预充电/刷新 ← 可以重叠 Bank 0 的操作
Bank 2:读取 Row 5 ← 可以重叠
Bank 3:idle ← 等待
Bank 之间的切换延迟(tRRD):
- 激活一个 Bank 后,需要等待几个周期才能激活另一个 Bank
- DDR4 tRRD = 4 cycles(最小值)
Bank 并行 → 内存控制器可以流水线化多个请求
→ 提高整体带宽利用率3.4 内存地址到 Cell 的完整映射
DDR4 系统(8GB 容量,单通道 64-bit)地址映射示例:
CPU 地址 bit 分配(简化版):
[Bank Group][Bank][Row][Column][Channel]
- Bank Group(3 bits):选择 Bank Group(2 个 Bank Group)
- Bank(3 bits):选择 Bank(8 个 Bank)
- Row(16 bits):选择 Row(64K 行)
- Column(10 bits):选择列(1K 列)
- Channel(64-bit 并行)
行地址 → Row Decoder → 选通对应 Word Line → 一整行 Cell 接入 BL
列地址 → Column Decoder → 选通对应列 → 数据通过 IO 传输到 CPU
一次读操作的完整流程:
1. Row Decoder 根据 Row Address 选通某一行(所有列同时接入 BL)
2. Sense Amplifier 放大 BL 上的微弱电压变化 → 完整电平
3. Column Decoder 根据 Column Address 选通特定列
4. 数据通过 DQ 引脚传输到内存控制器
5. 如果不需要该行,执行 Precharge 关闭行4. DDR 协议:从 SDR 到 DDR5 的演进
4.1 为什么需要 DDR
DDR = Double Data Rate,核心思想是在一个时钟周期的上升沿和下降沿都传输数据。
SDR(Single Data Rate)vs DDR 对比:
SDR(SDRAM):
- 只在时钟上升沿传输数据
- 1 个时钟周期 = 1 次传输
- 频率 100MHz → 带宽 100MT/s(百万次传输/秒)
DDR1(DDR-266):
- 上升沿 + 下降沿都传输
- 频率 133MHz → 带宽 266MT/s
- 数据率(Peak Transfer Rate)= 2 × 时钟频率
DDR2(DDR2-800):
- 内部频率翻倍(2n Prefetch)
- 时钟 400MHz → 带宽 800MT/s
- 外部总线频率更高,但数据预取宽度更大
DDR3(DDR3-1600):
- 内部频率 4n Prefetch
- 时钟 800MHz → 带宽 1600MT/s
DDR4(DDR4-3200):
- 内部频率 8n Prefetch
- 时钟 1600MHz → 带宽 3200MT/s
DDR5(DDR5-6400):
- 内部频率 16n Prefetch
- 时钟 3200MHz → 带宽 6400MT/s4.2 Prefetch(预取)机制
DDR 速度提升的核心不是靠无限提高外部时钟频率(受物理限制),而是靠Prefetch。
Prefetch 原理:
SDR(1n Prefetch):
- 每个时钟周期传输 1 个数据字(64 bits)
- 内存阵列频率 = IO 频率
DDR1(2n Prefetch):
- 每个时钟周期传输 2 个数据字(128 bits)
- 内存阵列频率 = 1/2 × IO 频率
→ 内存阵列速度不变,但 IO 速度翻倍
DDR2(4n Prefetch):
- 每个时钟周期传输 4 个数据字(256 bits)
- 内存阵列频率 = 1/4 × IO 频率
→ 可以用更低的内部阵列频率实现更高的 IO 频率
DDR4(8n Prefetch):
- 每个时钟周期传输 8 个数据字(512 bits)
- 内存阵列频率 = 1/8 × IO 频率
→ DDR4-3200 的阵列频率只需要 200MHz
DDR5(16n Prefetch):
- 每个时钟周期传输 16 个数据字(1024 bits)
- 进一步降低内部频率要求
为什么 Prefetch 能提速?
→ 内存阵列(电容 + 放大器)的速度远低于 IO 接口速度
→ 一次从阵列读出更多的数据(Prefetch 宽度)
→ 用较低的阵列频率支撑较高的 IO 频率4.3 DDR 的关键技术参数
DDR4-3200(CL22)关键时序参数:
tCK(Clock Period):0.625ns(时钟周期,对应 1600MHz)
tCL(CAS Latency):22 个时钟周期(从读命令到数据输出)
tRCD(RAS to CAS Delay):13.75ns(行激活到列读取)
tRP(Row Precharge):13.75ns(行预充电时间)
tRC(Row Cycle):45ns(连续访问同一行的间隔)
tRFC(Refresh Cycle):350ns(刷新一行的时间)
延迟的绝对时间计算:
tCL = 22 × 0.625ns = 13.75ns
tRCD = 13.75ns(已经是绝对值,不是周期数)
突发传输(burst length):
DDR4 标准 BL = 8(一次读命令传输 8 个数据字 = 64 bytes)
即一个 Cache Line(64B)一次读完
DDR5 新特性:
- 双通道 per DIMM(每个 DIMM 有两个独立的 40-bit 通道)
- 更高的 Bank 数量(32 Bank,4 Bank Group)
- Same Bank Refresh(SBR)允许其他 Bank 继续访问
- 内部电压从 1.2V 降到 1.1V
- 眼图测试更严格,信号完整性要求更高5. 刷新(Refresh):动态 DRAM 的代价
5.1 为什么要刷新
DRAM 的”Dynamic”(动态)来自电容的漏电特性:
电容漏电的物理原因:
- 绝缘层不是完美的,总有微量隧穿电流
- 温度越高,漏电越快
- 60°C 时漏电速度比 25°C 快约 4 倍
电容电压衰减:
- 存储"1"(充满电)时,电压约 1.2V(VDD)
- 漏电后,电压缓慢下降
- 降到阈值(约 0.6V = 1/2 VDD)以下时,无法被 Sense Amplifier 正确判断为"1"
- 超过阈值 → 数据损坏
数据保持时间(Data Retention Time):
- 室温下约 64ms
- 高温下可能只有 16~32ms
结论:
→ 每 64ms(甚至更短)必须把所有行重新读取并写回
→ 这就是"刷新"(Refresh)5.2 刷新的实现
刷新操作:
每个 Bank 逐行刷新:
1. 激活一行(Row)→ 所有 Cell 数据被 Sense Amplifier 读取
2. 放大后立即写回(Restore)→ 电容重新充电到 VDD
3. 预充电(Precharge)关闭该行
4. 移动到下一行
DDR4 刷新规范(JEDEC):
- 每 64ms 必须刷新所有行(所有 Bank)
- 以 8192 行为例:64ms / 8192 ≈ 7.8μs / 行
- 刷新频率 ≈ 128KHz(每秒 12.8 万次刷新操作)
刷新时间计算(tRFC):
- 刷新一行的时间 tRFC ≈ 350ns(DDR4)
- 刷新 8192 行总时间 = 8192 × 350ns ≈ 2.87ms
- 占空比 = 2.87ms / 64ms ≈ 4.5%
实际上 DDR4 会用 1x/2x/4x 刷新模式:
- 1x 刷新:64ms 刷新所有行(标准)
- 2x 刷新:64ms 刷新所有行两次(高温补偿)
- 4x 刷新:高温加速刷新,保证数据可靠性5.3 刷新对性能的影响
刷新窗口内的带宽损失:
场景:游戏运行时,GPU 持续访问显存
刷新期间:Bank 正在刷新,无法接受新的读写请求
带宽损失示例:
- DDR4-3200,8192 行,每行 tRFC = 350ns
- 刷新占用的时间 = 8192 × 350ns = 2.87ms / 64ms = 4.5%
- 有效带宽 = 标称带宽 × (1 - 4.5%) ≈ 95.5%
延迟影响:
- 刷新期间访问请求被挂起
- tRRD(Bank 到 Bank 延迟)增加
- 长时间连续刷新导致突发延迟
DDR5 的改进——Same Bank Refresh(SBR):
传统刷新(All Bank Refresh):
所有 Bank 同时刷新,系统完全暂停
SBR(Same Bank Refresh):
刷新 Bank N 时,其他 Bank 继续保持访问
刷新开销降低到 < 0.5%
游戏/图形渲染时感知延迟大幅减少5.4 Self-Refresh(自刷新)
当系统空闲时,内存控制器可以让 DRAM 进入自刷新模式:
Self-Refresh 的工作原理:
- DRAM 内部有自己的刷新计时器
- 不需要外部控制器发送刷新命令
- 功耗降到最低(约 1~2mW per Gb)
- 用于:笔记本待机(S3)、手机待机
功耗对比(DDR4-8Gb,典型值):
- Active(持续读写):~500mW
- Idle(开放 Bank):~100mW
- Precharge Power-Down:~20mW
- Self-Refresh:~1~2mW6. 读写操作的时序详解
6.1 完整读操作的时序
DDR4 读操作的完整时序(行命中 Row Hit):
阶段 1:Row Activate(行激活)
tRCD = 13.75ns(行地址到列地址的延迟)
→ WL 拉高,一整行 Cell 接入 BL
→ Sense Amplifier 放大数据
阶段 2:CAS(列读取)
tCL = 13.75ns(列地址到数据输出)
→ Column Decoder 选通列
→ 数据从 Sense Amplifier 输出到 IO
阶段 3:突发传输
BL = 8(一次传输 8 个数据字)
每个字 1/2 时钟周期
持续时间 ≈ 4 × 0.625ns = 2.5ns
总延迟(行命中)= tRCD + tCL = ~27.5ns
---
行未命中(Row Miss)的场景:
阶段 1:Row Activate(行激活) tRCD = 13.75ns
阶段 2:CAS(列读取) tCL = 13.75ns
阶段 3:Precharge(预充电当前行) tRP = 13.75ns(如果需要)
阶段 4:新行 Activate(新行激活) tRCD = 13.75ns(新行)
阶段 5:CAS(新行读取) tCL = 13.75ns
总延迟(行未命中)= tRCD + tCL + tRP + tRCD_new + tCL
≈ 68.75ns(约 110 个 CPU 周期)
这就是为什么内存访问延迟高度依赖行地址的局部性。6.2 写操作的时序
DDR4 写操作:
写操作没有 CAS Latency 的概念,因为数据直接写入已激活的行。
基本流程:
1. Activate Row(激活目标行)
2. 直接写入 Column(写命令包含列地址和数据)
3. 数据在几个周期后被写入 Cell
Write Latency(WL):
- DDR4 写延迟约 12~18 个时钟周期
- WL = CL - 1(大约)
写后操作:
- 写操作完成后,数据在 Sense Amplifier 中
- 需要等待一段时间才能 Precharge
- tWR(Write Recovery)= 15ns
写穿(Write-Through)vs 写回(Write-Back):
- DRAM 本身不知道 Cache 的策略
- DRAM 每次写操作都直接写入 Cell
- Cache 的写回/写穿是 CPU 内存控制器的策略7. DRAM 芯片的内部结构:完整视图
一个 DDR4 x8 芯片(8Gb 容量)的内部结构:
┌─────────────────────────────┐
│ Row Decoder │
│ (行地址解码,选通 Word Line) │
└────────────┬───────────────┘
│
┌───────────┬──────────┴───────────┬────────────┐
│ │ │ │
Array 0 Array 1 ... Array 15 Array 31
(256 rows (256 rows (256 rows (256 rows
× 1024) × 1024) × 1024) × 1024)
│ │ │ │
└───────────┴──────────┬───────────┴────────────┘
│
┌────────────┴───────────────┐
│ Sense Amplifier Array │
│ (列放大器,放大 BL 电压变化) │
└────────────┬───────────────┘
│
┌────────────┴───────────────┐
│ Column Mux / Decoder │
│ (列选择,多路复用) │
└────────────┬───────────────┘
│
┌────────────┴───────────────┐
│ IO / DQ Pins │
│ (数据引脚,8-bit 宽) │
└─────────────────────────────┘
重要参数:
- 32 个 Array × 256 行 × 1024 列 × 1 bit = 8Gb
- 每个 Array 有独立的 Sense Amplifier
- 列多路复用(Column Mux)把 1024 列复用到 128 个 IO
- 16n Prefetch:一次从所有 Array 读 16 个字(16 × 8 = 128 bits)总结
- DRAM Cell:1 个 NMOS + 1 个电容,靠电容电荷存储 bit
- Bit Line / Word Line:BL 是共享数据总线,WL 控制选通哪个 Cell
- Bank / Row / Column 层次:Row 由 WL 选通(一整行接入 BL),Column 由列解码器选择
- DDR 协议:通过 Prefetch(2n/4n/8n/16n)在内部低频下实现高频 IO
- 刷新:电容漏电,每 64ms 必须刷新所有行,约 4% 带宽损失,DDR5 SBR 降至 <0.5%
- 读写时序:行命中 ~30ns,行未命中 ~70ns,局部性是性能关键
下篇预告(S02):SRAM 为什么不需要刷新?SRAM 的 6 个晶体管是怎么互相”锁死”数据的?SRAM 和 DRAM 的全面对比。
关注公众号「AI不着急」,回复”资料”获取内存学习路线图。
评论