学习完了DDR的基本组成和硬件结构原理之后,从整体上了解了DDR的特性和静态图,包括原理、管脚图等。那么本章就要从动态的角度来分析时序结构,包括read/write的整个过程到数据返回发生了什么。
对于DRAM,其主要由行和列组成,每一个bit中都是由类似右下图的类晶体管的结构组成,对于sdram的数据,可以通过控制column和row就可以访问sdram的随机地址的内容。
读取某一个bit的状态,就是选中word line,那么图示中的晶体管M1就会导通,通过bit line的sense就可以感知到这个时候电容Cs上的状态,例如,现在如果这个bit的状态为1,那么导通之后就会从bit line上得到1,反之也是同样的道理。
向某一bit写入1,首先通过row decoder选中word line,将会导致m1导通,那么bit line为1,会导致电容Cs充电,导致其电平为1,如果要写入,那么bit line的电瓶 为0,将会导致电容Cs放电,致使此时的电平为0。
由上面可以看出一个位只能表示一个bit,那么我们想读取多个位的时候,该怎么办呢?那就出现了ddr中的bank的概念,由多个memory array就组成了一个bank,如下图,一次可以读取2bit/4bit/8bit的数据
一个多个bank就可以组成一个memory device,如下图,一个dram的芯片,由8个banks组成,而每个bank由4个memory array构成,而此时每个bank输出4个bit的I/O bus,那么为什么会出现bank的概念呢?动态内存区别于静态内存要定时刷新,每读取一个状态的时候,都需要重新充电。如果没有采用bank,假设我们现在要读取01-08地址的数据,当读取01的地址后,要等这个bank自刷新后才能读取02地址的值,而采用8个bank之后,没有这类问题,例如我们读取完01地址之后,那么读取02,因为02与01的控制方式不同,所以对于这段时间01可以后台的完成自刷新,依次类推,那么就可以很好的解决动态内存需要刷新的问题。
上图中,对于RANK、DIMM等在深入浅出DDR系列(一)–DDR原理篇中已经详细介绍了。
了解了DDR的基本组成后,我们来看看DDR如何来完成一次的读写过程。如下图所示,DRAM 相关操作在内部大概可以分为以下的四个阶段:
command transport and decode: 在这个阶段,Host 端会通过 Command Bus 和 Address Bus 将具体的 Command 以及相应参数传递给 DRAM。DRAM 接收并解析 Command,接着驱动内部模块进行相应的操作。其中会根据将addr bus上的数据解码成对应的row address和通过bank control解码后得到对应的bank,其次对应的column也会解码得到对应的地址
in bank data movement: 在这个阶段,第一阶段发送需要读取的信息 Column 的地址给 DRAM。然后 DRAM 再将 Active Command 所选中的 Row 中,DRAM 就将 Memory Array 中的数据从 DRAM Cells 中读出到 Sense Amplifiers,或者将数据从 Sense Amplifiers 写入到 DRAM Cells。
in device data movement: 这个阶段中,数据将通过 IO 电路缓存到 Read Latchs 或者通过 IO 电路和 Write Drivers 更新到 Sense Amplifiers。
system data transport: 在这个阶段,进行读数据操作时,SDRAM 会将数据输出到数据总线上,进行写数据操作时,则是 Host 端的 Controller 将数据输出到总线上。
在上述的四个阶段中,每个阶段都会有一定的耗时,例如数据从 DRAM Cells 搬运到 Read Latchs 的操作需要一定的时间,因此在一个具体的操作需要按照一定时序进行。同时,由于内部的一些部件可能会被多个操作人员使用,例如读数据和写数据都需要用到部分 IO 电路,因此多个不同的操作通常不能同时进行,也需要遵守一定的时序。此外,某些操作会消耗很大的电流,为了满足 SDRAM 设计上的功耗指标,可能会限制某一些操作的执行频率。
在芯片上电后,完成初始化后,dram处于idle阶段,上图是需要进入各个阶段的时候,应该需要进行那些基本的操作,对于ddr使用比较频繁的几个基本命令访问方式如下:
内核资料直通车:最新Linux内核源码资料文档+视频资料
学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈
DRAM的基本命令是通过操作各种控制信号/地址信号的组合来完成,下表是DRAM的命令表
4. 1. Row Active Command
在进行数据的读写前,Controller 需要先发送 Row Active Command,打开 DRAM Memory Array 中的指定的 Row。Row Active Command 的时序如下图所示:
tRCD:RAS-to-CAS Delay(tRCD),内存行地址传输到列地址的延迟时间。
Row Active Command 通过地址总线指明需要打开某一个 Bank 的某一个 Row。DRAM 在接收到该 Command 后,会打开该 Row 的 Wordline,将其存储的数据读取到 Sense Amplifiers 中,这一时间定义为 tRCD(RCD for Row Address to Column Address Delay)。DRAM 在完成 Row Sense 阶段后,Controller 就可以发送 Read 或 Write Command 进行数据的读写了。这也意味着,Controller 在发送 Row Active Command 后,需要等待 tRCD 时间才能接着发送 Read 或者 Write Command 进行数据的读写。
tRAS: Row Active Time,内存行地址选通延迟
由于 DRAM 的特性,Row 中的数据在被读取到 Sense Amplifiers 后,需要进行 Restore 的操作。Restore 操作可以和数据的读取同时进行,即在这个阶段,Controller 可能发送了 Read Command 进行数据读取。
DRAM 接收到 Row Active Command 到完成 Row Restore 操作所需要的时间定义为 tRAS(RAS for Row Address Strobe)。
Controller 在发出一个 Row Active Command 后,必须要等待 tRAS 时间后,才可以发起另一次的 Precharge 和 Row Access。
Controller 发送 Row Active Command 并等待 tRCD 时间后,再发送 Column Write Command 进行数据写入。 数据 Burst Length 为 8 时的 Column Write Command 时序如下图所示:
tCWD/tCL/tCWL:内存CAS延迟时间
Column Write Command 通过地址总线 A[0:9] 指明需要写入数据的 Column 的起始地址。Controller 在发送完 Write Command 后,需要等待 tCWD (CWD for Column Write Delay) 时间后,才可以发送待写入的数据。tCWD 在一些描述中也称为 tCWL(CWL for Column Write Latency)
tWR(WR for Write Recovery)
DRAM 接收完数据后,需要一定的时间将数据写入到 DRAM Cells 中,这个时间定义为 tWR(WR for Write Recovery)。该值说明在一个激活的bank中完成有效的写操作及预充电前,必须等待多少个时钟周期。这段必须的时钟周期用来确保在预充电发生前,写缓冲中的数据可以被写进内存单元中。同样的,过低的tWD虽然提高了系统性能,但可能导致数据还未被正确写入到内存单元中,就发生了预充电操作,会导致数据的丢失及损坏。
要访问 DRAM Cell 中的数据,需要先进行 Precharge 操作。相应地,在 Controller 发送 Row Active Command 访问一个具体的 Row 前, Controller 需要发送 Precharge Command 对该 Row 所在的 Bank 进行 Precharge 操作。下面的时序图描述了 Controller 访问一个 Row 后,执行 Precharge,然后再访问另一个 Row 的流程。
DRAM 执行 Precharge Command 所需要的时间定义为 tRP(RP for Row Precharge)。Controller 在发送一个 Row Active Command 后,需要等待 tRC(RC for Row Cycle)时间后,才能发送第二个 Row Active Command 进行另一个 Row 的访问。
从时序图上我们可以看到,tRC = tRAS + tRP,tRC 时间决定了访问 DRAM 不同 Row 的性能。在实际的产品中,通常会通过降低 tRC 耗时或者在一个 Row Cycle 执行尽可能多数据读写等方式来优化性能。
一般情况下,为了保证 DRAM 数据的有效性,Controller 每隔 tREFI(REFI for Refresh Interval) 时间就需要发送一个 Row Refresh Command 给 DRAM,进行 Row 刷新操作。DRAM 在接收到 Row Refresh Command 后,会根据内部 Refresh Counter 的值,对所有 Bank 的一个或者多个 Row 进行刷新操作。
DRAM 刷新的操作与 Active + Precharge Command 组合类似,差别在于 Refresh Command 是对 DRAM 所有 Bank 同时进行操作的。下图为 DRAM Row Refresh Command 的时序图:
DRAM 完成刷新操作所需的时间定义为 tRFC(RFC for Refresh Cycle)。
tRFC 包含两个部分的时间,一是完成刷新操作所需要的时间,由于 DRAM Refresh 是同时对所有 Bank 进行的,刷新操作会比单个 Row 的 Active + Precharge 操作需要更长的时间;tRFC 的另一部分时间则是为了降低平均功耗而引入的延时,DRAM Refresh 操作所消耗的电流会比单个 Row 的 Active + Precharge 操作要大的多,tRFC 中引入额外的时延可以限制 Refresh 操作的频率。
一个完整的 Burst Length 的 Read Cycle 如下图所示:
下面是DDR常见的一些参数及定义如下:
tMRD Mode Register Delay 表示在进行初始化时,从LOAD MODE REGISTER命令发出到可以执行ACTIVE/REFRESH命令的时间
tRP Row Precharge Time 表示行预充时间,用来设定在另一行能被激活之前,现有的工作行需要充电时间
tRCD RAS to CAS delay 行寻址到列地址的延时时间
tCL CAS Latency 表示内存读写操作前列地址的潜伏时间
tWR Write Recovery TIme 表示写恢复延时,指在一个激活bank中完成有效写操作及预充电前,必须等待的时钟周琼
tRAS Row Active TIme 表示从内存行有效命令发出至预充电命令发出之间的最短时间
tWTR 表示读到写延时,在最后一次有效写操作和下一次读操作之间必须等待的时间
tREF Row refresh time 表示行刷新所需要时间
上述的 DRAM Timing 中的一部分参数可以编程设定,例如 tCAS、tAL、Burst Length 等。这些参数通常是在 Host 初始化时,通过 Controller 发起 Load Mode Register Command 写入到 DRAM 的 Mode Register 中。DRAM 完成初始化后,就会按照设定的参数运行。
在学习完DDR的基本操作和时序参数之后,我们就看看性能的影响。当频率和位宽固定后,带宽也就不可更改,但是在内存的工作周期内,不可能总处于数据传输的状态,因为要有命令、寻址等必要的过程。那么这些操作占用的时间越短,内存工作的效率就越高,性能也就越好。
对于我们来说,最好的方法是提高频率,但是提高频率会受多方面的影响,还有什么办法提高内存访问的速度。
多通道: 现代内存控制器从北桥移入CPU内部,而内存控制器都可以同时操作多个通道。比如现在的笔记本开始支持双通道、三通道,如果数据分布在不同通道的内存条上,内存控制器就可以不用管上面的这些延迟时序,同时可以读取它们,速度可以增加两倍,甚至三倍。
交织方式(Interleaving): 同一块内存分布到不同的通道中去,这样无论Cache命中与否都可以同时存取,多通道的技术才能发挥更大的用处
超频内存: 也就是提升DDR的频率来增加速度
对于DDR的读写以及一些时序参数的原理性知识后,下一章就进入到DDR的驱动调式篇,主要是对于一款控制器,我们该如何去调试DDR。其实对于DDR的调式,主要的读写的控制,都是由DDR的控制器完成了,我们主要是通过MRS模式/EMRS模式来完成对于DDR参数的配置,而对于MRS模式的使用,已经集成到DDR控制器中完成了,我们只需要根据控制器手册配置相应的寄存器就可以完成对于DDR调试。