DDR 简介


什么是 DDR ?

DDR 的全称其实是 DDR SDRAM (Double Data Rate Synchronous Dynamic Random Access Memory),即双倍数据速率同步动态随机存储器
从命名上看,其具有以下特性

  • 双倍数据速率:传统的 SDR 只在每个时钟周期的上升沿进行数据采样,而 DDR 则是在时钟的上升沿和下降沿均进行数据采样
  • 同步:内存工作需要同步时钟,内部命令的发送和数据传输都以它为基准
  • 动态随机存储器:内部的存储单元会漏电,需要每隔一段时间进行一次“刷新”才能保持数据

那么 DDR 有哪些技术需要我们关注?

  1. 双边采样
  2. 数据预取



历代 DDR 对比


特性 DDR DDR2 DDR3 DDR4 DDR5
电压 2.5 1.8 1.5 1.2 1.1
数据预取 2n 4n 8n 8n 16n
核心频率(Mhz) 100~200 100~266 100~266 200~400 200~450
时钟频率(Mhz) 100~200 200~533 400~1066 800~1600 1600~4600
数据传输率(MT/s) 200~400 400~1066 800~2133 1600~3200 3200~6400
  • 数据预取:在同一个时钟周期内,将相邻的列地址数据一起取出,由列地址取选择输出
  • 核心频率:DDR的真实运行频率
  • 时钟频率:I/O缓冲器的工作频率
  • 数据传输速率:数据传输位数




DDR 的基本原理


基本构成

Cell

500

DRAM中最基本的存储单元是 Cell ,由晶体管、存储电容组成。晶体管用来控制电容的充电和放电;电容则用来存储电荷,当电容存有电荷时,Cell 存储比特信息 “ 1 ” ;当电容不存有电荷时,Cell 存储比特信息 “ 0 ”

给晶体管的最上面一端(称为栅极)施加电压/取消电压,晶体管两端就可以导通,电容就会向位线进行充放电,我们就可以从位线上电容的充放电信息得到 Cell 存储的比特信息。电容的充放电其实是由电容与位线之间的电压差决定的,如:电容电压大于位线电压,则电容放电;电容电压小于位线电压,则电容充电;而位线在充放电之前是有一个 Pre-charge 操作,因此其是有一定电压的,后面再进行说明

那么把数据写入到 Cell 中也是如此,将位线拉高至电容供电电压,电容则存储比特信息 “ 1 ” ;将位线接地,电容则存储比特信息 “ 0 ”

前面提到的 “漏电” 是指在没有打开晶体管的情况下,电容也会随着时间的流逝内部存储的电荷会越来越少,所以需要内存控制器间隔一段时间对该电容进行 “刷新操作”,也就是重新读取其存储的比特信息并重新写入




Array

600

一个 Cell 只能存储 1 bit 数据,为了存储大量数据,需要构建起 Cell 阵列(这里称为 Array)。

可以看到每行 Cell 的晶体管栅极都是连在同一根字线上,也就是说当给字线加压时,该行所有的 Cell 被打开,电容就会向位线进行充放电,位线上电压的的微小变化会被感应放大器捕捉到获得 Cell 中存储的比特信息。而这些 Cell 的比特信息将被寄存到感应放大器中,最后又控制器发送过来的列地址选择对应的位线输出

这里其实还涉及DDR的预取技术,我们在给字线加压时,晶体管导通电容充放电,存储的比特信息其实已经暂存到感应放大器中了,那么在读取列地址数据时,再把相邻的几个位线的数据也读走,这就是 Prefetch 数据预取




Bank

600
一个 Array 的 Cell 存储的 1 bit 信息可以从与之连接的位线上获取,那么由 n 个 Array 组成的 Bank ,就可以获得 n bit 的存储信息,这个 n bit 其实就是对应内存颗粒的位宽(这里使用 8 bit 位宽的内存颗粒举例)

那么在读取这 8 bit 位宽的数据时,这 8 个 Array 其实是共用同一组行列地址(相当于一个行列地址同时给到了 8 个 Array,让其读取同一个位置的 Cell ,然后就可以从这 8 根位线上可以获得 8 bit 数据)



内存颗粒

1000
Bank Group 的概念是 DDR4 才有的,因此可能有些内存颗粒是有 Bank Group 的,但我们不需要关注这个,本质上我们都是读取其中一个 Bank 上的数据。只要给定一个行列地址给内存颗粒,其最终输出到外部 IO 引脚的数据位宽就是内存颗粒的位宽 n bit



内存颗粒组 & DDR内存条

1000
一组可以被内存通道同时访问的内存颗粒称为 1 个 Rank。这个 Rank 中的内存颗粒都共用同一个内存控制器提供的地址线和控制线,然后每个内存颗粒各提供一组输出线,组合起来就是内存通道的输出线

example

假设内存通道的数据位宽为 64 bit ,那么 8 个 8 bit 位宽的内存颗粒可以组成 1 个 Rank ,如图中上面一排 8 个内存颗粒。那么上图即 2 Rank 8 bit 位宽的 DDR




内存通道

1000
如果一根 DDR 的数据位宽为 64 bit ,而内存控制器的数据位宽也为 64 bit ,这叫单通道。如果内存控制器的数据位宽为 128 bit ,那么这个内存控制器可以连接两根 DDR ,这叫双通道



读写操作

读操作

一个完整的读操作包含以下 4 个阶段

  • Pre-charge(预充电):在读取 Cell 之前,需要把每根位线的电压预充电到电容的最大电压的一半
  • Access(访问):给某一行 Cell 的字线加压,该行所有的 Cell 导通,电容进行充放电
  • Sense(感知):电容与位线之间有电压差,位线会有微小的电压变化。而这个电压变化会被感应放大器捕捉到,从而得到电容存储的值
  • Restore(恢复):因为 Cell 的读取的具有破坏性,因此需要把值重新写回到电容中,此时位线会被拉高或接地
  • Pre-charge(预充电):由于恢复阶段时位线的电压被拉高或接地,如果不处理的话,下一次 Access(访问)时数据会被改写。因此需要把位线的电压给他恢复到电容的最大电压的一半
Tip

电容在进行充放电时,原本的电荷被放掉了,这种信息丢失的读取行为称为 “ 破坏性读出 ”。因此,我们在读取完该行信息之后,还需要对该行进行恢复,这里就需要感应放大器把原本的信息重新写回到 Cell 中

另外,在 Restore 阶段,当前行的 Cell 存储的值暂存在感应放大器中,是由外部IO从感应放大器中取出,因此恢复与列读取是并行执行的

Example

假设电容的最大电压为 3V ,那么预充电后位线的电压为 1.5V ,之后电容若是进行放电,则位线平衡后的电压是 1.5V + ΔV\Delta V;若电容是进行充电,则位线平衡后的电压是 1.5V - ΔV\Delta V

1000

  • tRCD:“ DRAM收到行激活命令后,打开该行,将其存储的数据读取到感应放大器中 ” 的这段时间
  • tCAS:” 从接收到命令到第一组数据传输到数据总线 “ 的这段时间
  • tCCD:” 从发送第一列数据到最后一列数据发出 ” 的这段时间
  • tRAS:DRAM 收到行激活命令到完成行恢复所需要的时间
  • tRP:DRAM 执行预充电所需要的时间
  • tRC:从行激活命令到下一次行激活命令的完整周期




写操作

一个完整的写操作包含以下 4 个阶段,前面 3 个阶段与读操作一样

  • Pre-charge(预充电):在读取 Cell 之前,需要把每根位线的电压预充电到电容的最大电压的一半
  • Access(访问):给某一行 Cell 的字线加压,该行所有的 Cell 导通,电容进行充放电
  • Sense(感知):电容与位线之间有电压差,位线会有微小的电压变化。而这个电压变化会被感应放大器捕捉到,从而得到电容存储的值
  • Recovery(覆盖):由于电容存储的信息被破坏性读取走了,此时的逻辑与行恢复同理,只不过重新写回的数据来自控制器发送过来的数据
  • Pre-charge(预充电):将写数据的位线电压重新恢复到电容的最大电压的一半

1000

  • tRCD:“ DRAM收到行激活命令后,打开该行,将其存储的数据读取到感应放大器中 ” 的这段时间
  • tCWD:” 从接收到命令到写入第一组数据 ” 的这段时间
  • tCCD:” 从发送第一列数据到最后一列数据发出 ” 的这段时间
  • tWR:DRAM 接收完数据后,需要一定的时间将数据写入 DRAM 基本单元
  • tRAS:DRAM 收到行激活命令到完成行恢复所需要的时间
  • tRP:DRAM 执行预充电所需要的时间
  • tRC:从行激活命令到下一次行激活命令的完整周期




容量计算

这里举一个简单的例子进行解释:
一个 Array 有 216 行 和 210 列,那么这个 Array 的容量为 216 * 210 = 64 Mb
一个 Bank 有 8 个 Array ,那么这个 Bank 的容量为 8 * 64 Mb = 64 MB
一个 Bank Group 有 4 个 Bank ,那么这个 Bank Group的容量为 4 * 64 MB = 256 MB
一个内存颗粒有 4 个 Bank Group,那么这个内存颗粒的容量为 4 * 256 MB = 1 GB
一根 DDR 内存条有 16 颗内存颗粒,那么这个内存条的容量为 16 * 1 GB = 16 GB

Tip

我们常说的一个内存颗粒的位宽是多少,其实就是指一个 Bank 里面有多少个 Array

我们每次读写一个逻辑地址,其实就是同时读取 8 个内存颗粒(假设这个 DDR 有 8 个内存颗粒,每个内存颗粒位宽为 8 bit)中同一个位置 Bank Group 里的 Bank 的 8 个 Array 的同一行同一列,这样我们就获得了 8 * 8 = 64 bit 的数据

再配合 DDR 的"数据预取技术",我们可以获得更多数据。如 DDR4 预取数据为 8n ,也就是读写一个逻辑地址,我们可以获得 8 * 8 * 8 = 512 bit 的数据




频率计算

  • 核心频率:DRAM 的工作频率
  • 时钟频率:I/O 采样频率
  • 控制器频率:


一般我们看到关于 DDR 的速率,比如 DDR4-2133,这里的 2133 是指 DDR4 的数据传输速率。因为 DDR 是双边沿采样的(上升沿和下降沿都进行采样),所以 DDR 的 IO 时钟频率是他的一半

  • 数据传输速率:2133 MT/s
  • I/O 时钟频率: 1066 Mhz
  • 核心频率: 266 Mhz
数据传输速率 = 2 \times I/O时钟频率 I/O时钟频率 = 4 \times 核心频率

因为DDR4采用的是 8n 的数据预取,即每个DRAM颗粒在单个时钟周期能读取 8n 的数据出来(如果颗粒位宽是 8 bit ,那么每次读取就能获得 64 bit 的数据),而这 8n 的数据需要被外部的 I/O 给采集出去(需要 8 次采集动作),那么,结合 DDR 的双边沿采样技术,只需要外部 I/O 的时钟频率是核心频率的 4 倍即可

参考文献


  1. SoC设计基础教程 —— 系统架构
  2. 一文搞懂DDR SDRAM工作原理
  3. 深入内存/主存:解剖DRAM存储器
  4. DDR 探密二:深入剖析 DRAM 芯片的存储原理
  5. DDR4读写测试(二):基本读写测试