
DDR3存储单元结构和原理
DDR SDRAM是类似一个网格阵列,其中基本存储单元称之为cell。

每个Cell包含一个电容Cbit和一个FET管,能存储一个bit的数据。如下图:

一个基本存储单元结构图如下图,storage capacitor为一个基本存储单元,当access transitor被选通时,可读可写;Row(word)line称为字线,也就是DDR的行地址线,它连在了FET的g极。通过控制字线电压就可以控制FET的开启与关闭了,也就可以对Cbit电容进行充电或者是放电了。Cbit里面如果存储有电荷,即S端电压为VCC,那么就是存储的1,否则就是存储的0,Ccol为寄生电容。
一个3行8列的SDRAM存储阵列如下图所示:

为了存储更多的bit,可以用如上的DRAM单元组成存储阵列。行对应的是word line,即字线。列对应的是bit line,即位线。当某一行的字线上通电后,这一行的cell上的电容就会经过位线进行充放电。通过读取位线上的电压变化,就能判断存储的是0,还是1。由于电容很小,打开字线后产生的电压波动也很小,所以在读取的时候,要经过sense amplifier进行放大。
每个位线都接在一个放大器上,由于每个cell的电容太小了,在读某一bit前,先对bit line进行precharge。预充的电压为工作电压的一半。这样在打开字线后,位线上的轻微变化也能被放大器捕捉到,并在本地还原、暂存字线对应整行cell的电压。其实,当读了位线(电容放电)后,电容上的电荷就会发生了改变,这是一种破坏性读出。为了解决这个问题,就需要放大器在读取cell存储的数据后,利用暂存的cell电压写回字线单元行。
DRAM刷新
由于cell的电容很小,并且CMOS晶体管在关闭的时候,也存在漏电,这样电容上的电荷也在随着时间的变化,逐渐变少。时间一长,存储的信息就会丢失。为了解决这一问题,具体做法是对于每个单元行,每过一段时间就自主地进行读取,等放大器暂存好信息后就立刻将其写回行。关于单元行的刷新时机也很有讲究,一般每64ms内就要对cell阵列进行一次全面刷新。
DRAM的读写

读操作过程:
在读取DRAM芯片上单个比特数据时:* 读取前,先给各条位线预充电(也称为precharge),即把位线电压拉高到供电电压的一半。拉高到一半的目的是和cell电容电压形成电压差,从而在打开单元行时,可利用电容的微弱充放电产生电压波动。预充电完成后,就可以断开位线与预充电电源的连接,此时位线处于悬空态,电压会保持为供电电压的一半。
开始读取,首先在地址总线上输入行地址,稍后立刻置“行地址选通”(即RAS)有效,置RAS有效后,DRAM芯片就把行地址缓存下来。
缓存好行地址之后,就把行地址送入译码模块,译码模块把行地址译码成独热码,独热码的每一位都接到对应的字线,然后把其中一条字线的电压值拉高。
把地址线上的地址从行地址转换成列地址,转换成列地址之后,外界会置“列地址选通”有效,然后DRAM会把列地址缓存起来。
拉高的字线所对应的单元行被打开,即单元行的所有晶体管导通,单元行的各个cell电容和位线连通。 如果cell保存比特信息1,即cell电容的电压等于供电电压,此时cell电容电压高于位线电压,电容放电,位线的电压稍稍上升。 如果cell保存比特信息0,即cell电容的电压等于地电压,即0电压,此时位线电压高于cell电容电压,位线向cell电容充电,位线电压稍稍下降。
放大器捕捉位线上的微弱电压波动,通过“差分感测”在本地生成并暂存cell电容电压。 如果cell电容等于供电电压,那么位线电压稍稍上升,放大器比较此位线和另一条基准线的电压,通过模拟电路的反馈来放大两者的电压差,最终在本地生成一个等于供电电压的输出电压,并用锁存器把输出电压锁存下来。 如果cell电容电压等于0,放大器最终生成等于0的输出电压,并用锁存器把0电压锁存下来。
放大器锁存好行数据之后,把行数据送往多到一选择器。
列地址缓存就把列地址送到多到一选择器,多到一选择器根据列地址,把单元行中的某一位送到输出线。
输出之后,还需要把放大器的数据写回到单元行,即根据放大器的锁存值,把位线拉高到供电电压或是0电压,位线向cell电容充放电,充放电结束之后,就可以关闭字线。
写回数据并关闭字线之后,连接位线和预充电电源,给位线预充电到供电电压的一半,为下一次读写做好准备。
读操作步骤:
关闭所有字线,W0,W1…Wn。让所有FET均不导通。
将位线B0通过预充电开关Precharge(图中未画出)拉到Vcc/2,即VB0=Vcc/2。(这个操作就是预充电Precharge)。
断开预充电开关Precharge Switch,停止充电。
将W0置为高电平Vcc,此时Cell0的FET导通。
如果原来存储的是1,Cbit电压大于VB0,那么Cbit会对字线B0充电,使得VB0>Vcc/2,此时VB0经过放大器Sense AMP后放大电压到VCC电平,即读出1。
如果原来存储的是0,Cbit电压小于VB0,于是字线B0会对Cbit充电,使得VB0<VCC/2,此时VB0经过放大器Sense AMP后电压被拉直GND,即读出0。

DRAM写操作过程
写过程和读过程比较类似,就不详细描述,主要描述有差异的地方:* 位线预充电到供电电压的一半。
输入、缓存行地址,译码行地址,开通单元行,开通单元行后位线产生电压波动,放大器捕捉电压波动并还原、暂存行数据到本地。
输入、缓存列地址,与此同时置写使能有效,并在Data Buffer存进写入比特,注意,Data Buffer在读取DRAM时用来暂存输出比特,而在写DRAM时则用来暂存写入比特。
把写入比特送到一到多分配器,分配器根据列地址把写入比特送到对应的放大器中,放大器根据写入比特改写本地暂存值。
放大器根据暂存的电压值刷新单元行,刷新完毕后断开单元行的字线,刷新完毕后,重新给位线预充电,为下一次读写做好准备。
总的来说,读取一个比特的总体过程:获得行号,译码行号,开启单元行,放大位线电压波动并暂存数据到放大器,获得列号并根据列号选择一位进行输出,写回数据,关闭字线,重新预充电。 写一个比特的总体过程是:获得行号,译码行号,开启单元行,放大位线电压波动并暂存数据到放大器,获得列号并输入写入数据,根据列号把写入数据送到放大器并改写暂存值,写回数据,关闭字线,重新预充电。
那么要访问的一个字节的其他7bit是不是也存在这些单元行里?答案是否定的。 其实,还存在7个这样的bit存储阵列,其中相同的行列地址在这7个bit存储阵列相同位置取出相应的bit,这样便得到了完整的8bit(一个字节)数据。
另外,在读写过程中,时间主要消耗在“开启单元行”与“放大电压波动并暂存数据”。单元行的栅极可以抽象成一个个电容的并联,因此字线的拉高就是给这么多电容充电的一个过程,这将是很耗时及耗电的。由于放大器大部分是模拟电路,所以他的工作也不快。那么怎么提高DRAM的读写速度呢? 关键点在放大器的缓存区(row buffer),它缓存了单元行,但是一般我们只取出了其中的一个bit。如果要想提升速写速度,那就还访问这个单元行的其他bit,这时会直接从row buffer中取出相应的数据,不需要经历开启单元行、放大、读写数、写回的耗时过程。
写操作步骤:
写0
1---首先将位线B0拉低
2---然后将W0拉高,打开FET,Cbit通过B0放电置GND
3---拉低W0,完成写入0
写1
1---首先将位线B0拉高
2---然后将W0拉高,打开FET,Cbit通过B0充电至VCC
3---拉低W0,完成写入1
