DDR4学习笔记 —— 基础知识
DDR 简介
什么是 DDR ?
DDR 的全称其实是 DDR SDRAM (Double Data Rate Synchronous Dynamic Random Access Memory),即双倍数据速率同步动态随机存储器
从命名上看,其具有以下特性
- 双倍数据速率:传统的 SDR 只在每个时钟周期的上升沿进行数据采样,而 DDR 则是在时钟的上升沿和下降沿均进行数据采样
- 同步:内存工作需要同步时钟,内部命令的发送和数据传输都以它为基准
- 动态随机存储器:内部的存储单元会漏电,需要每隔一段时间进行一次“刷新”才能保持数据
那么 DDR 有哪些技术需要我们关注?
- 双边采样
- 数据预取
历代 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

DRAM中最基本的存储单元是 Cell ,由晶体管、存储电容组成。晶体管用来控制电容的充电和放电;电容则用来存储电荷,当电容存有电荷时,Cell 存储比特信息 “ 1 ” ;当电容不存有电荷时,Cell 存储比特信息 “ 0 ”
给晶体管的最上面一端(称为栅极)施加电压/取消电压,晶体管两端就可以导通,电容就会向位线进行充放电,我们就可以从位线上电容的充放电信息得到 Cell 存储的比特信息。电容的充放电其实是由电容与位线之间的电压差决定的,如:电容电压大于位线电压,则电容放电;电容电压小于位线电压,则电容充电;而位线在充放电之前是有一个 Pre-charge 操作,因此其是有一定电压的,后面再进行说明
那么把数据写入到 Cell 中也是如此,将位线拉高至电容供电电压,电容则存储比特信息 “ 1 ” ;将位线接地,电容则存储比特信息 “ 0 ”
前面提到的 “漏电” 是指在没有打开晶体管的情况下,电容也会随着时间的流逝内部存储的电荷会越来越少,所以需要内存控制器间隔一段时间对该电容进行 “刷新操作”,也就是重新读取其存储的比特信息并重新写入
Array

一个 Cell 只能存储 1 bit 数据,为了存储大量数据,需要构建起 Cell 阵列(这里称为 Array)。
可以看到每行 Cell 的晶体管栅极都是连在同一根字线上,也就是说当给字线加压时,该行所有的 Cell 被打开,电容就会向位线进行充放电,位线上电压的的微小变化会被感应放大器捕捉到获得 Cell 中存储的比特信息。而这些 Cell 的比特信息将被寄存到感应放大器中,最后又控制器发送过来的列地址选择对应的位线输出
这里其实还涉及DDR的预取技术,我们在给字线加压时,晶体管导通电容充放电,存储的比特信息其实已经暂存到感应放大器中了,那么在读取列地址数据时,再把相邻的几个位线的数据也读走,这就是 Prefetch 数据预取
Bank

一个 Array 的 Cell 存储的 1 bit 信息可以从与之连接的位线上获取,那么由 n 个 Array 组成的 Bank ,就可以获得 n bit 的存储信息,这个 n bit 其实就是对应内存颗粒的位宽(这里使用 8 bit 位宽的内存颗粒举例)
那么在读取这 8 bit 位宽的数据时,这 8 个 Array 其实是共用同一组行列地址(相当于一个行列地址同时给到了 8 个 Array,让其读取同一个位置的 Cell ,然后就可以从这 8 根位线上可以获得 8 bit 数据)
内存颗粒

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

一组可以被内存通道同时访问的内存颗粒称为 1 个 Rank。这个 Rank 中的内存颗粒都共用同一个内存控制器提供的地址线和控制线,然后每个内存颗粒各提供一组输出线,组合起来就是内存通道的输出线
假设内存通道的数据位宽为 64 bit ,那么 8 个 8 bit 位宽的内存颗粒可以组成 1 个 Rank ,如图中上面一排 8 个内存颗粒。那么上图即 2 Rank 8 bit 位宽的 DDR
内存通道

如果一根 DDR 的数据位宽为 64 bit ,而内存控制器的数据位宽也为 64 bit ,这叫单通道。如果内存控制器的数据位宽为 128 bit ,那么这个内存控制器可以连接两根 DDR ,这叫双通道
读写操作
读操作
一个完整的读操作包含以下 4 个阶段
- Pre-charge(预充电):在读取 Cell 之前,需要把每根位线的电压预充电到电容的最大电压的一半
- Access(访问):给某一行 Cell 的字线加压,该行所有的 Cell 导通,电容进行充放电
- Sense(感知):电容与位线之间有电压差,位线会有微小的电压变化。而这个电压变化会被感应放大器捕捉到,从而得到电容存储的值
- Restore(恢复):因为 Cell 的读取的具有破坏性,因此需要把值重新写回到电容中,此时位线会被拉高或接地
- Pre-charge(预充电):由于恢复阶段时位线的电压被拉高或接地,如果不处理的话,下一次 Access(访问)时数据会被改写。因此需要把位线的电压给他恢复到电容的最大电压的一半
电容在进行充放电时,原本的电荷被放掉了,这种信息丢失的读取行为称为 “ 破坏性读出 ”。因此,我们在读取完该行信息之后,还需要对该行进行恢复,这里就需要感应放大器把原本的信息重新写回到 Cell 中
另外,在 Restore 阶段,当前行的 Cell 存储的值暂存在感应放大器中,是由外部IO从感应放大器中取出,因此恢复与列读取是并行执行的
假设电容的最大电压为 3V ,那么预充电后位线的电压为 1.5V ,之后电容若是进行放电,则位线平衡后的电压是 1.5V + ;若电容是进行充电,则位线平衡后的电压是 1.5V -

- tRCD:“ DRAM收到行激活命令后,打开该行,将其存储的数据读取到感应放大器中 ” 的这段时间
- tCAS:” 从接收到命令到第一组数据传输到数据总线 “ 的这段时间
- tCCD:” 从发送第一列数据到最后一列数据发出 ” 的这段时间
- tRAS:DRAM 收到行激活命令到完成行恢复所需要的时间
- tRP:DRAM 执行预充电所需要的时间
- tRC:从行激活命令到下一次行激活命令的完整周期
写操作
一个完整的写操作包含以下 4 个阶段,前面 3 个阶段与读操作一样
- Pre-charge(预充电):在读取 Cell 之前,需要把每根位线的电压预充电到电容的最大电压的一半
- Access(访问):给某一行 Cell 的字线加压,该行所有的 Cell 导通,电容进行充放电
- Sense(感知):电容与位线之间有电压差,位线会有微小的电压变化。而这个电压变化会被感应放大器捕捉到,从而得到电容存储的值
- Recovery(覆盖):由于电容存储的信息被破坏性读取走了,此时的逻辑与行恢复同理,只不过重新写回的数据来自控制器发送过来的数据
- Pre-charge(预充电):将写数据的位线电压重新恢复到电容的最大电压的一半

- 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
我们常说的一个内存颗粒的位宽是多少,其实就是指一个 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
因为DDR4采用的是 8n 的数据预取,即每个DRAM颗粒在单个时钟周期能读取 8n 的数据出来(如果颗粒位宽是 8 bit ,那么每次读取就能获得 64 bit 的数据),而这 8n 的数据需要被外部的 I/O 给采集出去(需要 8 次采集动作),那么,结合 DDR 的双边沿采样技术,只需要外部 I/O 的时钟频率是核心频率的 4 倍即可