||
DDR出身自SDRAM,严格的说应该叫DDR SDRAM,DDR SDRAM是Double Data Rate SDRAM的缩写,是双倍速率同步动态随机存储器的意思,所以,有很大一部分,两者是一样的,理解SDRAM,然后再来理解DDR。在SDRAM上的改进,效果应该更好一些,本文参考大神Tekkaman Ninja的博客中介绍的,并加入了一些自己的讲解。
先上一张SDRAM的结构图,如下图所示
SDRAM结构图
下面上一张简易的SDRAM工作流程图
SDRAM的内部是一个存储阵列,阵列就如同表格一样,将数据“填”进去。在数据读写时和表格的检索原理一样,先指定一个行(ROW),在指定一个列(COL),我们就可以准确的找到所需要的单元格,这就是内存芯片寻址的基本原理。这个单元格(存储阵列)就叫做逻辑BANK(简称L-Bank)。
SDRAM是多Bank结构,例如在一个具有两个Bank的SDRAM的模组中,其中一个Bank在进行预充电期间,另一个Bank却马上可以被读取,这样当进行一次读取后,又马上去读取已经预充电Bank的数据时,就无需等待而是可以直接读取了,这也就大大提高了存储器的访问速度。
为了实现这个功能,SDRAM需要增加对多个Bank的管理,实现控制其中的Bank进行预充电。在一个具有2个以上Bank的SDRAM中,一般会多一根叫做BAn的引脚,用来实现在多个Bank之间的选择。另外它们的行、列地址线共用,由行地址选通((CAS)、列地址选通(RAS)信号分时控制。
SDRAM简易工作流程图
图中用红色标明的就是我们需要找的几个主要时间,现在开始看图说话
1、芯片初始化
SDRAM 芯片内部有一个逻辑控制单元,并且有一个模式寄存器为其提供控制参数。因此,每次开机时都要先对这个控制逻辑核心进行初始化。
2、行有效
初始化完成后,要想对一个 L-Bank 中的阵列进行寻址,首先就要确定行(Row),使之处于活动状态(Active),然后再确定列。简单点理解就先传行地址过来。
3、列读写
行地址确定之后,就要对列地址进行寻址了。读写的信号和列地址是同时发过来的,读写的操作取决于WE#引脚,当他使能则为写,否则为读。
在发送列读写命令时必须要与行有效命令有一个间隔,这个间隔被定义为 tRCD,即RAS to CAS Delay(RAS 至 CAS 延迟),大家也可以理解为行选通周期,简单点理解就是说,在发完行地址后,再发列地址和读写信号时,需要延迟一下,这应该是根据芯片存储阵列电子元件响应时间(从一种状态到另一种状态变化的过程)所制定的延迟。
广义的 tRCD 以时钟周期(tCK,Clock Time)数为单位,比如 tRCD=2,就代表延迟周期为两个时钟周期,具体到确切的时间,则要根据时钟频率而定,对于PC100 SDRAM,tRCD=2,代表1000/100 * 2 = 20ns 的延迟,下图是tRCD=3的时序图。
SDRAM 时序图 tRCD说明
4、数据输出(读)
在选定列地址后,就已经确定了具体的存储单元,剩下的事情就是数据通过数据 I/O 通道(DQ)输出到内存总线上了。
但是在CAS发出之后,仍要经过一定的时间才能有数据输出,从CAS与读取命令发出到第一笔数据输出的这段时间,被定义为 CL(CAS Latency,CAS潜伏期)。由于CL只在读取时出现,所以 CL 又被称为读取潜伏期(RL,Read Latency),下图是CL=2的示意图。
SDRAM 时序图 CL说明
5、数据输入(写)
数据写入的操作也是在 tRCD 之后进行,但此时没有了 CL(记住,CL 只出现在读取操作中),行寻址与列寻址的时序图和上文一样,只是在列寻址时,WE#为有效状态。 为了保证数据的可靠写入,都会留出足够的写入/校正时间(tWR,Write Recovery Time),这个操作也被称作写回(Write Back)。tWR 至少占用一个时钟周期或再多一点(时钟频率越高,tWR 占用周期越多)
6、突发长度--(Burst Lengths)
突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输所涉及到存储单元(列)的数量就是突发长度(Burst Lengths,简称 BL)。 只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。这样,除了第一笔数据的传输需要若干个周期(主要是之前的延迟,一般的是 tRCD+CL)外,其后每个数据只需一个周期的即可获得。
7、预充电
由于 SDRAM 的寻址具体独占性,所以在进行完读写操作后,如果要对同一个Bank的另一行进行寻址,就要将原来有效(工作)的行关闭,重新发送行/列地址。Bank 关闭现有工作行,准备打开新行的操作就是预充电(Precharge)。 在发出预充电命令之后,要经过一段时间才能允许发送 RAS 行有效命令打开新的工作行,这个间隔被称为tRP(Precharge command Period,预充电有效周期)。和 tRCD、CL 一样,tRP 的单位也是时钟周期数,具体值视时钟频率而定。
8、刷新
之所以称为 DRAM,就是因为它要不断进行刷新(Refresh)才能保留住数据,因此它是 DRAM 最重要的操作。刷新操作与预充电中重写的操作一样,都是用 S-AMP 先读再写。 但为什么有预充电操作还要进行刷新呢?因为预充电是对一个或所有L-Bank 中的工作行操作,并且是不定期的,而刷新则是有固定的周期,依次对所有行进行操作,以保留那些久久没经历重写的存储体中的数据。但与所有 L-Bank 预充电不同的是,这里的行是指所有 L-Bank 中地址相同的行,而预充电中各 L-Bank 中的工作行地址并不是一定是相同的。比如我有四片,刷新是我依次刷新四片内存中的某个地址,然后再刷下一个;而预充电的工作行地址可以不同。
那么要隔多长时间重复一次刷新呢?目前公认的标准是,存储体中电容的数据有效保存期上限是64ms(毫秒,1/1000 秒),也就是说每一行刷新的循环周期是 64ms。这样刷新速度就是:行数量/64ms。我们在看内存规格时,经常会看到 4096 RefreshCycles/64ms 或 8192RefreshCycles/64ms 的标识,这里的 4096 与 8192 就代表这个芯片中每个 L-Bank 的行数。刷新命令一次对一行有效,发送间隔也是随总行数而变化,4096 行时为 15.625μs(微秒,1/1000 毫秒),8192 行时就为 7.8125μs。
刷新操作分为两种:自动刷新(Auto Refresh,简称 AR)与自刷新(Self Refresh,简称 SR)。
SR 则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是 STR(Suspend to RAM,休眠挂起于内存)。在发出 AR 命令时,将 CKE 置于无效状态,就进入了 SR 模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在 SR 期间除了 CKE 之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使 CKE 有效才能退出自刷新模式并进入正常操作状态。
第二节 DDR工作原理与时序(一)下面先介绍一些DDR的有关概念
DDR SDRAM 全称为 Double Data Rate SDRAM,中文名为“双倍数据流 SDRAM”。DDR SDRAM 在原有的 SDRAM的基础上改进而来。下图是DDR和SDRAM的数据传输对比图。
DDR和SDRAM的数据传输对比图
上图可以清楚的看到,DDR可在一个时钟周期内传送两次数据,上升沿传一次,下降沿传一次。
一、DDR的基本原理
DDR读操作时序图
从中可以发现它多了两个信号:CK#与DQS,CK#与正常 CK 时钟相位相反,形成差分时钟信号。而数据的传输在 CK 与 CK#的交叉点进行,可见在 CK 的上升与下降沿(此时正好是 CK#的上升沿)都有数据被触发,从而实现双倍数据传输,也就是DDR。下面来看DDR的内部结构图与SDRAM有什么不同(SDRAM的结构图可以参考上一节)。
DDR的结构框图
首先看上图的DDR SDRAM的结构框图,这个图重点要来说为何DDR SDRAM虽然操作的时钟频率和SDRAM一样,却能够在数据吞吐量上达到后者的两倍。也许你会不以为然,没错,DDR就是double data rata,不就是在SDR时钟单沿读写的基础上变成了DDR的时钟双沿读写嘛,速度这不就一下翻番了。很对,但是再往深入去,你思考过吗?难道DDR内部寻址时数据也是双沿读写么?非也,看上图中绿色的圈“X8/X16”,它表示DDR SDRAM外部的数据总线接口位宽,一般是8位或者16位。而它左边那个红圈里“X16/X32”则表示内部2-bit prefetch和实际存储单元间的位宽。那么从这里可以发现,实际上,DDR内部有着和SDRAM类似的结构,只不过在接口的output buffer与实际存储单元间多了一个2-bit prefetch。而这个2-bit prefetch与output buffer之间是X8/X16传输,但是它与存储单元之间却是X16/X32传输。你可以这样设想,在每次时钟的上升沿,2-bit prefetch存储着外部接口两次读写(即两个地址)的数据,而output buffer却是每个时钟的上升沿和下降沿都会读取一次数据(对应一个地址)。
理解了DDR的数据吞吐量提升的实质原因,在回头看看SDRAM的结构。如下图所示,绿色圈圈的那条连线大家可以返回上图比较一下。
SDRAM的结构框图
二、DDR与SDRAM的异同
DDR SDRAM 与 SDRAM 一样,在开机时也要进行 MRS(ModeRegister Set,模式寄存器的设置),不过由于操作功能的增多,DDR SDRAM 在 MRS 之前还多了一 EMRS 阶段(Extended Mode Register Set,扩展模式寄存器设置),这个扩展模式寄存器控制着 DLL 的有效/禁止、输出驱动强度、QFC 有效/无效等。
三、差分时钟
CK#的作用,并不能理解为第二个触发时钟,而是起到触发时钟校准的作用。
由于数据是在 CK 的上下沿触发,造成传输周期缩短了一半,因此必须要保证传输周期的稳定以确保数据的正确传输,这就要求 CK 的上下沿间距要有精确的控制。但因为温度、电阻性能的改变等原因,CK 上下沿间距可能发生变化,此时与其反相的 CK#就起到纠正的作用(CK 上升快下降慢,CK#则是上升慢下降快)。而由于上下沿触发的原因,也使 CL=1.5 和 2.5 成为可能,并容易实现。
DDR差分时钟
四、数据选取脉冲(DQS)
DQS 是 DDR SDRAM 中的重要功能,它的功能主要用来在一个时钟周期内准确的区分出每个传输周期,并便于接收方准确接收数据。每一颗芯片都有一个 DQS 信号线,它是双向的,在写入时它用来传送由内存控制器发来的 DQS 信号,读取时,则由DDR芯片生成 DQS 向内存控制器发送。完全可以说,它就是数据的同步信号。
在读取时,DQS 与数据信号同时生成(也是在 CK 与 CK#的交叉点)。而 DDR 内存中的 CL 也就是从 CAS 发出到 DQS 生成的间隔,数据真正出现在数据 I/O总线上相对于 DQS 触发的时间间隔被称为tAC。实际上,DQS 生成时,芯片内部的预取已经完毕了,tAC 是指上文结构图中灰色部分的数据输出时间,由于预取的原因,实际的数据传出可能会提前于 DQS 发生(数据提前于 DQS 传出)。
DQS 在读取时与数据同步传输,那么接收时也是以 DQS 的上下沿为准吗?不,如果以 DQS 的上下沿区分数据周期的危险很大。由于芯片有预取的操作,所以输出时的同步很难控制,只能限制在一定的时间范围内,数据在各 I/O 端口的出现时间可能有快有慢,会与 DQS 有一定的间隔,这也就是为什么要有一个 tAC 规定的原因(DDR中的tAC是在DQS触发和数据真正出现在I/O总线上的间隔时间)。而在接收方,一切必须保证同步接收,不能有 tAC 之类的偏差。这样在写入时,芯片不再自己生成 DQS,而以发送方传来的 DQS 为基准,并相应延后一定的时间,在 DQS 的中部为数据周期的选取分割点(在读取时分割点就是上下沿),从这里分隔开两个传输周期。这样做的好处是,由于各数据信号都会有一个逻辑电平保持周期,即使发送时不同步,在 DQS 上下沿时都处于保持周期中,此时数据接收触发的准确性无疑是最高的。
DDR DQS 写入时序图
在写入时,以DQS 的高/低电平期中部为数据周期分割点,而不是上/下沿,但数据的接收触发仍为 DQS 的上/下沿。
五、写入延迟
在上图DQS 写入时序图中,可以发现写入延迟已经不是0了,在发出写入命令后,DQS与写入数据要等一段时间才会送达。这个周期被称为 DQS 相对于写入命令的延迟时间(tDQSS,WRITE Command to the firstcorresponding rising edge of DQS)。
为什么要有这样的延迟设计呢?原因也在于同步,毕竟一个时钟周期两次传送,需要很高的控制精度,它必须要等接收方做好充分的准备才行。tDQSS 是 DDR 内存写入操作的一个重要参数,太短的话恐怕接受有误,太长则会造成总线空闲。tDQSS 最短不能小于 0.75 个时钟周期,最长不能超过 1.25 个时钟周期。
正常情况下,tDQSS 是一个时钟周期,但写入时接受方的时钟只用来控制命令信号的同步,而数据的接受则完全依靠 DQS 进行同步,所以 DQS 与时钟不同步也无所谓。不过,tDQSS产生了一个不利影响——读后写操作延迟的增加,如果 CL=2.5,还要在 tDQSS 基础上加入半个时钟周期,因为命令都要在 CK的上升沿发出。下图中,当 CL=2.5 时,读后写的延迟将为 tDQSS+0.5 个时钟周期(图中 BL=2)。
DDR读取时序图
另外,DDR 内存的数据真正写入由于要经过更多步骤的处理,所以写回时间(tWR)也明显延长,一般在3个时钟周期左右,而在 DDR-II规范中更是将 tWR 列为模式寄存器的一项,可见它的重要性。
六、突发长度
在 DDR SDRAM 中,突发长度只有 2、4、8 三种选择,没有了随机存取的操作(突发长度为 1)和全页式突发。这是为什么呢?因为 L-Bank一次就存取两倍于芯片位宽的数据,所以芯片至少也要进行两次传输才可以,否则内部多出来的数据怎么处理?但是,突发长度的定义也与 SDRAM 的不一样了,它不再指所连续寻址的存储单元数量,而是指连续的传输周期数,每次是一个芯片位宽的数据。
七、延迟锁定回路(DLL)
DDR SDRAM 对时钟的精确性有着很高的要求,而 DDR SDRAM 有两个时钟,一个是外部的总线时钟,一个是内部的工作时钟,在理论上 DDR SDRAM 这两个时钟应该是同步的,但由于种种原因,如温度、电压波动而产生延迟使两者很难同步,更何况时钟频率本身也有不稳定的情况(SDRAM 也有内部时钟,不过因为它的工作/传输频率较低,所以内外同步问题并不突出)。
DDR SDRAM 的 tAC 就是因为内部时钟与外部时钟有偏差而引起的,它很可能造成因数据不同步而产生错误的恶果。实际上,不同步就是一种正/负延迟,如果延迟不可避免,那么若是设定一个延迟值,如一个时钟周期,那么内外时钟的上升与下降沿还是同步的。鉴于外部时钟周期也不会绝对统一,所以需要根据外部时钟动态修正内部时钟的延迟来实现与外部时钟的同步,这就是 DLL 的任务。
DLL 不同于主板上的 PLL,它不涉及频率与电压转换,而是生成一个延迟量给内部时钟。目前 DLL 有两种实现方法,一个是时钟频率测量法(CFM,Clock Frequency Measurement),一个是时钟比较法(CC,Clock Comparator)。
CFM 是测量外部时钟的频率周期,然后以此周期为延迟值控制内部时钟,这样内外时钟正好就相差了一个时钟周期,从而实现同步。DLL 就这样反复测量反复控制延迟值,使内部时钟与外部时钟保持同步。
CFM 式 DLL 工作示意图
CC的方法则是比较内外部时钟的长短,如果内部时钟周期短了,就将所少的延迟加到下一个内部时钟周期里,然后再与外部时钟做比较,若是内部时钟周期长了,就将多出的延迟从下一个内部时钟中刨除,如此往复,最终使内外时钟同步。
CC 式 DLL 工作示意图
CFM 与 CC 各有优缺点,CFM 的校正速度快,仅用两个时钟周期,但容易受到噪音干扰,并且如果测量失误,则内部的延迟就永远错下去了。CC 的优点则是更稳定可靠,如果比较失败,延迟受影响的只是一个数据(而且不会太严重),不会涉及到后面的延迟修正,但它的修正时间要比 CFM 长。DLL 功能在 DDR SDRAM 中可以被禁止,但仅限于除错与评估操作,正常工作状态是自动有效的。
第三节 DDR工作原理与时序(二)上一节我们学习了DDR SDRAM的工作原理,这一节我们接着讲一下DDR2的一些知识,看看与DDR、SDRAM 有什么不同,这一节的内容也基本来自于网络。
DDR的发展沿着更高数据传输频率,更大内存容量的方向发展,DDR2中做到更高数据传输频率,由DDR的2-bit pretetch向4-bit pretetch发展,而扩展容量,除了增加每个L-Bank的容量以外,另外就是增加L-Bank数,也就是说在内存中,原来DDR中Bank线只有2根,一块内存芯片最多2^2=4片L-Bank,而在DDR2中变成了2^3=8片L-Bank。(下面的一些图和文档出自于芯片手册)
一、4-bit Prefetch
看看DDR2的三个频率的关系,下图是内部时钟均为133MHz的DDR2/DDR/SDRAM的比较,由此可以看到,相比于DDR,DDR2由于是4-bit Prefetch,外部时钟是内部总线时钟的2倍,而DDR和SDRAM中,这两个时钟频率相等。
DDR、DDR2、SDRAM比较表
在 SDRAM 与 DDR 时代,这两个时钟频率是相同的,但在 DDR-II内存中,内部时钟变成了外部时钟的一半。以 DDR-II533 为例,数据传输频率为 533MHz(对于每个数据引脚,则是 533Mbps/pin),外部时钟频率为 266MHz,内部时钟频率为 133MHz。因为内部一次传输的数据就可供外部接口传输 4 次,虽然以 DDR 方式传输,但数据传输频率的基准——外部时钟频率仍要是内部时钟的两倍才行。
DDR、DDR2、SDRAM比较图
二、 DDR-II的新操作与新时序设计
1、片外驱动调校(OCD,Off-Chip Driver)
DDR-II内存在开机时也会有初始化过程,同时在 EMRS 中加入了新设置选项,由于大同小异,在此就不多说了。在EMRS阶段,DDR-II加入了可选的OCD功能。
OCD的主要用意在于调整 I/O 接口端的电压,来补偿上拉与下拉电阻值。目的是让 DQS 与 DQ 数据信号之间的偏差降低到最小。调校期间,分别测试 DQS 高电平/DQ 高电平,与 DQS 低电平/DQ 高电平时的同步情况,如果不满足要求,则通过设定突发长度的地址线来传送上拉/下拉电阻等级(加一档或减一档),直到测试合格才退出 OCD 操作。
DOS 同步时序说明图
2、片内终结(ODT,On-Die Termination)
所谓的终结,就是让信号被电路的终端吸收掉,而不会在电路上形成反射,造成对后面信号的影响。
在 DDR 时代,控制与数据信号的终结在主板上完成,每块 DDR 主板在 DIMM 槽的旁边都会有一个终结电压岛的设计,它主要由一排终结电阻构成。长期以来,这个电压岛一直是 DDR 主板设计上的一个难点。而 ODT 的出现,则将这个难点消灭了。ODT 将终结电阻从主板上移植到了内存芯片内部,主板上不在有终结电路。ODT 的功能与禁止由内存控制器控制,ODT 所终结的信号包括 DQS、RDQS(为 8bit 位宽芯片增设的专用 DQS 读取信号,主要用来简化一个模组中同时使用4与 8bit 位宽芯片时的控制设计)、DQ、DM 等。
ODT说明图
上图中,左边就是DDR时代,在主板上完成信号终结,右边就是从DDR2开始,在内存芯片内部终结信号。在内存芯片工作时系统会把终结电阻器屏蔽,而对于暂时不工作的内存芯片则打开终结电阻器以减少信号的反射。由此DDR2内存控制器可以通过ODT同时管理所有内存引脚的信号终结。并且阻抗值也可以有多种选择。如0Ω、50Ω、75Ω、150Ω等等。并且内存控制器可以根据系统内干扰信号的强度自动调整阻值的大小。
3、前置 CAS、附加潜伏期与写入潜伏期
前置 CAS(Posted CAS)是为了解决 DDR 内存中指令冲突而设计的功能。它允许 CAS 信号紧随 RAS 发送,相对于以往的 DDR 等于将 CAS 前置了。这样,地址线可以立刻空出来,便于后面的行有效命令发出,避免造成命令冲突而被迫延后的情况发生,但读/写操作并没有因此而提前,仍有要保证有足够的延迟/潜伏期,为此,DDR-II引入了附加潜伏期的概念(AL,Additive Latency),与 CL 一样,单位为时钟周期数。AL+CL 被定义为读取潜伏期(RL,Read Latency),相应的,DDR-II还对写入潜伏期(WL,Write Latency)制定了标准,WL是指从写入命令发出到第一笔数据输入的潜伏期,不要将它和 tDQSS 弄混了,后者是指 DQS 而不是数据。按规定,WL=RL-1,即 AL+CL-1。
前置 CAS说明图
上图中,ACT表示的是激活信号,在没有前置CAS功能时,对其他L-Bank的寻址操作可能会因当前行的 CAS 命令占用地址线而延后,并使数据I/O总线出现空闲(上图中的BUBBLE处),当使用前置CAS后,消除了命令冲突并使数据I/O总线的利率提高。
前置 CAS说明
设置 Posted-CAS 后,必须附加潜伏期以保证应有延迟,此时读取潜伏期(RL)就等于 AL+CL,从中可以看出 AL 的值为 CL+tRCD-1。
第四节 简单介绍DDR3来自网友:http://blog.csdn.net/eshing/article/details/37567771。此博文以是镁光的(Micron MT41J128M8 1Gb DDR3 SDRAM芯片为例说明的。
首先,我们先了解一下内存的大体结构工作流程,这样会比较容量理解这些参数在其中所起到的作用。这部分的讲述运用DDR3的简化时序图。
DDR3的内部是一个存储阵列,将数据“填”进去,你可以它想象成一张表格。和表格的检索原理一样,先指定一个行(Row),再指定一个列(Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理。对于内存,这个单元格可称为存储单元,那么这个表格(存储阵列)就是逻辑 Bank(Logical Bank,下面简称Bank)。
DDR3内部Bank示意图,这是一个NXN的阵列,B代表Bank地址编号,C代表列地址编号,R代表行地址编号。
如果寻址命令是B1、R2、C6,就能确定地址是图中红格的位置
目前DDR3内存芯片基本上都是8个Bank设计,也就是说一共有8个这样的“表格”。
寻址的流程也就是先指定Bank地址,再指定行地址,然后指列地址最终的确寻址单元。
目前DDR3系统而言,还存在物理Bank的概念,这是对内存子系统的一个相关术语,并不针对内存芯片。内存为了保证CPU正常工作,必须一次传输完CPU 在一个传输周期内所需要的数据。而CPU在一个传输周期能接受的数据容量就是CPU数据总线的位宽,单位是bit(位)。控制内存与CPU之间数据交换的北桥芯片也因此将内存总线的数据位宽等同于CPU数据总线的位宽,这个位宽就称为物理Bank(Physical Bank,有的资料称之为Rank)的位宽。目前这个位宽基本为64bit。
在实际工作中,Bank地址与相应的行地址是同时发出的,此时这个命令称之为“行激活”(Row Active)。在此之后,将发送列地址寻址命令与具体的操作命令(是读还是写),这两个命令也是同时发出的,所以一般都会以“读/写命令”来表示列寻址。根据相关的标准,从行有效到读/写命令发出之间的间隔被定义为tRCD,即RAS to CAS Delay(RAS至CAS延迟,RAS就是行地址选通脉冲,CAS就是列地址选通脉冲),我们可以理解为行选通周期。tRCD是DDR的一个重要时序参数,广义的tRCD以时钟周期(tCK,Clock Time)数为单位,比如tRCD=3,就代表延迟周期为两个时钟周期,具体到确切的时间,则要根据时钟频率而定,DDR3-800,tRCD=3,代表30ns的延迟。
图中显示的是tRCD=3
接下来,相关的列地址被选中之后,将会触发数据传输,但从存储单元中输出到真正出现在内存芯片的 I/O 接口之间还需要一定的时间(数据触发本身就有延迟,而且还需要进行信号放大),这段时间就是非常著名的 CL(CAS Latency,列地址脉冲选通潜伏期)。CL 的数值与 tRCD 一样,以时钟周期数表示。如 DDR3-800,时钟频率为 100MHz,时钟周期为 10ns,如果 CL=2 就意味着 20ns 的潜伏期。不过CL只是针对读取操作。
由于芯片体积的原因,存储单元中的电容容量很小,所以信号要经过放大来保证其有效的识别性,这个放大/驱动工作由S-AMP负责,一个存储体对应一个S- AMP通道。但它要有一个准备时间才能保证信号的发送强度(事前还要进行电压比较以进行逻辑电平的判断),因此从数据I/O总线上有数据输出之前的一个时钟上升沿开始,数据即已传向S-AMP,也就是说此时数据已经被触发,经过一定的驱动时间最终传向数据I/O总线进行输出,这段时间我们称之为 tAC(Access Time from CLK,时钟触发后的访问时间)。
图中标准CL=2,tAC=1
目前内存的读写基本都是连续的,因为与CPU交换的数据量以一个Cache Line(即CPU内Cache的存储单位)的容量为准,一般为64字节。而现有的Rank位宽为8字节(64bit),那么就要一次连续传输8次,这就涉及到我们也经常能遇到的突发传输的概念。突发(Burst)是指在同一行中相邻的存储单元连续进行数据传输的方式,连续传输的周期数就是突发长度(Burst Lengths,简称BL)。
在进行突发传输时,只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。这样,除了第一笔数据的传输需要若干个周期(主要是之前的延迟,一般的是tRCD+CL)外,其后每个数据只需一个周期的即可获得。
突发连续读取模式:只要指定起始列地址与突发长度,后续的寻址与数据的读取自动进行,而只要控制好两段突发读取命令的间隔周期(与BL相同)即可做到连续的突发传输。
谈到了突发长度时。如果BL=4,那么也就是说一次就传送4×64bit的数据。但是,如果其中的第二笔数据是不需要的,怎么办?还都传输吗?为了屏蔽不需要的数据,人们采用了数据掩码(Data I/O Mask,简称DQM)技术。通过DQM,内存可以控制I/O端口取消哪些输出或输入的数据。这里需要强调的是,在读取时,被屏蔽的数据仍然会从存储体传出,只是在“掩码逻辑单元”处被屏蔽。DQM由北桥控制,为了精确屏蔽一个P-Bank位宽中的每个字节,每个DIMM有8个DQM 信号线,每个信号针对一个字节。这样,对于4bit位宽芯片,两个芯片共用一个DQM信号线,对于8bit位宽芯片,一个芯片占用一个DQM信号,而对于 16bit位宽芯片,则需要两个DQM引脚。
在数据读取完之后,为了腾出读出放大器以供同一Bank内其他行的寻址并传输数据,内存芯片将进行预充电的操作来关闭当前工作行。还是以上面那个Bank示意图为例。当前寻址的存储单元是B1、R2、C6。如果接下来的寻址命令是B1、R2、C4,则不用预充电,因为读出放大器正在为这一行服务。但如果地址命令是B1、R4、C4,由于是同一Bank的不同行,那么就必须要先把R2关闭,才能对R4寻址。从开始关闭现有的工作行,到可以打开新的工作行之间的间隔就是tRP(Row Precharge command Period,行预充电有效周期),单位也是时钟周期数。
在不同Bank间读写也是这样,先把原来数据写回,再激活新的Bank/Row。
数据选取脉冲(DQS)
DQS 是DDR中的重要功能,它的功能主要用来在一个时钟周期内准确的区分出每个传输周期,并便于接收方准确接收数据。每一颗芯片都有一个DQS信号线,它是双向的,在写入时它用来传送由北桥发来的DQS信号,读取时,则由芯片生成DQS向北桥发送。完全可以说,它就是数据的同步信号。
在读取时,DQS与数据信号同时生成(也是在CK与CK#的交叉点)。而DDR内存中的CL也就是从CAS发出到DQS生成的间隔,DQS生成时,芯片内部的预取已经完毕了,由于预取的原因,实际的数据传出可能会提前于DQS发生(数据提前于DQS传出)。由于是并行传输,DDR内存对tAC也有一定的要求,对于DDR266,tAC的允许范围是±0.75ns,对于DDR333,则是±0.7ns,有关它们的时序图示见前文,其中CL里包含了一段DQS 的导入期。
DQS 在读取时与数据同步传输,那么接收时也是以DQS的上下沿为准吗?不,如果以DQS的上下沿区分数据周期的危险很大。由于芯片有预取的操作,所以输出时的同步很难控制,只能限制在一定的时间范围内,数据在各I/O端口的出现时间可能有快有慢,会与DQS有一定的间隔,这也就是为什么要有一个tAC规定的原因。而在接收方,一切必须保证同步接收,不能有tAC之类的偏差。这样在写入时,芯片不再自己生成DQS,而以发送方传来的DQS为基准,并相应延后一定的时间,在DQS的中部为数据周期的选取分割点(在读取时分割点就是上下沿),从这里分隔开两个传输周期。这样做的好处是,由于各数据信号都会有一个逻辑电平保持周期,即使发送时不同步,在DQS上下沿时都处于保持周期中,此时数据接收触发的准确性无疑是最高的。
在写入时,以DQS的高/低电平期中部为数据周期分割点,而不是上/下沿,但数据的接收触发仍为DQS的上/下沿
3.容量的计算
上图为X8data的单颗DDR3架构图,行(Row)地址线复用14根,列(Column)地址线复用10根,Bank数量为8个,IO Buffer 通过8组数位线(DQ0-DQ7)来完成对外的通信,故此单颗DDR3芯片的容量为2的14次方乘2的10次方乘8乘8,结果为1Gbit,因为1B包含8bit,1GB/8=128MB。
如果我们要做成容量为1GB的内存条则需要8颗这样的DDR3内存芯片,每颗芯片含8根数位线(DQ0-DQ7)则总数宽为64bit,这样正好用了一个Rank。
假果还用128MB的DDR3芯片去做2GB内存条,结果就会有所不同。我们最好选用4根数位线(DQ0-DQ3),数量是16颗,这样也是用了一个Rank。
在K2的项目中我们要做容量为8GB的内存条,则数量用64颗128M的DDR3,这样位宽高达64X4=256bit,要做成4个Rank。
1.结构框图:
2.管脚功能描述
3.状态图:
Power on: 上电
Reset Procedure: 复位过程
Initialization: 初始化
ZQCL: 上电初始化后,用完成校准ZQ电阻。ZQCL会触发DRAM内部的校准引擎,
一旦校准完成,校准后的值会传递到DRAM的IO管脚上,并反映为输出驱动和ODT阻值。
ZQCS: 周期性的校准,能够跟随电压和温度的变化而变化。校准需要更短的时间窗口,
一次校准,可以有效的纠正最小0.5%的RON和RTT电阻。
Al:Additive latency.是用来在总线上保持命令或者数据的有效时间。
在ddr3允许直接操作读和写的操作过程中,AL是总线上的数据出现到进入器件内部的时间。
下图为DDR3标准所支持的时间操作。
Write Leveling:为了得到更好的信号完整性,DDR3存储模块采取了FLY_BY的拓扑结构,
来处理命令、地址、控制信号和时钟。FLY_BY的拓扑结构可以有效的减少stub的数量和他们的长度,
但是却会导致时钟和strobe信号在每个芯片上的flight time skew,这使得控制器(FPGA或者CPU)
很难以保持Tdqss ,tdss和tdsh这些时序。这样,ddr3支持write leveling这样一个特性,
来允许控制器来补偿倾斜(flight time skew)。存储器控制器能够用该特性和从DDR3反馈的数据调成DQS和CK之间的关系。
在这种调整中,存储器控制器可以对DQS信号可调整的延时,来与时钟信号的上升边沿对齐。
控制器不停对DQS进行延时,直到发现从0到1之间的跳变出现,然后DQS的延时通过这样的方式被建立起来了,由此可以保证tDQSS。
MRS: MODE Register Set, 模式寄存器设置。为了应用的灵活性,不同的功能、特征和模式等在四个在DDR3芯片上的Mode Register中,
通过编程来实现。模式寄存器MR没有缺省值,因此模式寄存器MR必须在上电或者复位后被完全初始化,
这样才能使得DDR可以正常工作。正常工作模式下,MR也可以被重新写入。模式寄存器的设置命令周期,
tMRD两次操作的最小时间,其具体时序图,如下图所示。模式寄存器,分为MR0、MR1、MR2和MR4。
MR0用来存储DDR3的不同操作模式的数据:包括突发长度、读取突发种类、CAS长度、测试模式、DLL复位等。
MR1用来存储是否使能DLL、输出驱动长度、Rtt_Nom、额外长度、写电平使能等。MR2用来存储控制更新的特性,
Rtt_WR阻抗,和CAS写长度。MR3用来控制MPR。
MPR: Multi-purpose register. 多用途寄存器。MPR的功能是读出一个预先设定的系统时序校准比特序列。
为了使能MPR功能,需要在MRS的寄存器MR3的A2位写1,并且在此之前需要将ddr3的所有bank处于idle状态;
一旦MPR被使能后,任何RD和RDA的命令都会被引入到MPR寄存器中,当MPR寄存器被使能后,
除非MPR被禁止(MR3的A2=0),否则就只有RD和RDA被允许。在MPR被使能的时候,RESET功能是被允许的。
Precharge Power Down: bank在in-progress命令后关闭
Active Power Down:bank在in-progress命令后依然打开
Idle:所有的bank必须预先充电,所有时序满足,DRAM的ODT电阻,RTT必须为高阻。
CWL:CAS write latency. 以时钟周期为单位,在内部写命令和第一位输入数据的时间延时,该单位始终为整数。
在操作过程中,所有的写延时WL被定义为AL(Additive Latency)+CWL。
Rtt: Dynamic ODT.DDR3引入的新特性。在特定的应用环境下为了更好的在数据总线上改善信号完整性,
不需要特定的MRS命令即可以改变终结强度(或者称为终端匹配)。在MR2中的A9和A10位设置了Rtt_WR。Ddr3中,
有两种RTT值是可以选择的,一种是RTT_Nom,另一种是RTT_WR;Rtt_Nom是在没有写命令的时候被选择的,
当有了写命令后,ODT就会变成Rtt_wr,当写命令结束后,又会回到Rtt_nom。也就是说,RTT在ODT使能后,出现,
当总线上没有数据的时候,采用的RTT值为RTT_nom;而当总线上有了数据后,要求此时的ODT的值为Rtt_wr。
具体的DDR3的ODT产生时序见图2。当ODT被使能后,必须要保持高电平ODTH4个时钟周期才可以有效;
如果写命令被放入寄存器并且ODT是高,那么ODT必须保持ODTH4或者ODTH8,这样ODT才可以有效。
ACT = ACTIVATE PREA = PRECHARGE ALL SRX = 自刷新推出
MPR = 多用处寄存器 READ = RD,RDS4,RDS8 WRITE=WR,WRS4,WRS8
MRS=模式寄存器集 READ AP=RDAP,RDAPS4,RDAPS8 WRITE=WRAP,WRAPS4,WRAPS8
PDE=掉电进入 REF=REFRESH ZQCL=ZQ LONG CALIBRATION
PDX=掉电推出 RESET=启动复位过程 ZACS=ZA SHORT CALIBTATION
PRE=预充电 SRE=自刷新进入
4、工作原理
在描述了上述的一些基本概念后,就可以对图1中的DDR3工作原理进行基本的描述了理解了。
首先,芯片进入上电,在上电最小为200us的平稳电平后,等待500usCKE使能,
在这段时间芯片内部开始状态初始化,该过程与外部时钟无关。在时钟使能信号前(cke),
必须保持最小10ns或者5个时钟周期,除此之外,还需要一个NOP命令或者Deselect命令出现在CKE的前面。
然后DDR3开始了ODT的过程,在复位和CKE有效之前,ODT始终为高阻。
在CKE为高后,等待tXPR(最小复位CKE时间),然后开始从MRS中读取模式寄存器。
然后加载MR2、MR3的寄存器,来配置应用设置;然后使能DLL,并且对DLL复位。
接着便是启动ZQCL命令,来开始ZQ校准过程。等待校准结束后,DDR3就进入了可以正常操作的状态。
对于基本的配置过程,现在就可以结束了。下面,结合CH1的控制器FPGA,说明对DDR3相关的配置。
上表中MRS可以设置Mode寄存器值
以 上图为例CS#,RAS#,CAS#,WE#为L,L,H,H。则指令为Row/Bank Active;随后CS#拉高,command无效,
在第4个时钟周期这4个信号变为L,H,L,H,对照表格,指令为Read,经过几个时钟周期延迟,在3CLK后读数据。
5. 基本功能
DDR3 SDRAM是高速动态随机存取存储器,内部配置有8个BANK。DDR3 SDRAM使用8n预取结构,以获得高速操作。8n预取结构同接口组合起来以完成在I/O脚上每个时钟两个数据字的传输。DDR3 SDRAM的一个单次读或写操作由两部分组成:一是在内部DRAM核中进行的8n位宽四个时钟数据传输,另一个是在I/O脚上进行的两个对应n位宽、半时钟周期的数据传输。
对DDR3 SDRAM的读写操作是有方向性的突发操作,从一个选择的位置开始,突发长度是8或者是一个以编程序列的长度为4的Chopped突发方式。操作开始于Active命令,随后是一个Read/Write命令。Active命令同时并发含带地址位,以选择Bank和Row地址(BA0-BA2选择BANK、A0-A15选择Row)。而Read/Write命令并发含带突发操作的起始Column地址,并确定是否发布自动预充电命令(通过A10)和选择BC4或BL8模式(通过A12)(如果模式寄存器使能)。
在正常操作之前,DDR3 SDRAM必要以预先定义的方式上电和初始化。
引入DDR3内存的动因
目前DDR2尚未完全取代DDR内存,在目前的整机环境下,DDR2基本能够满足各类型计算机的应用需求,那么最新一代的DDR3相比DDR2具有哪些优势,使得包括Intel和AMD以及A-DATA在内的众多国际顶级厂商都致力于DDR3的开发与应用呢?
最主要的原因是,由于DDR2的数据传输频率发展到800MHz时,其内核工作频率已经达到了200MHz,因此,再向上提升较为困难,这就需要釆用新的技术来保证速度的可持续发展性。另外,也是由于速度提高的缘故,内存的地址/命令与控制总线需要有全新的拓朴结构,而且业界也要求内存要具有更低的能耗。
CPU厂商的DDR3内存攻略
Intel计划在明年年中为其芯片组加入DDR3内存的支持。Intel芯片组事业部总经理Malinowski说,到那时市场才能准备好接受DDR3内存。
Intel最新的965芯片组家族只支持DDR2,并放弃了对DDR的支持。
AMD方面则要积极得多,与当年对DDR2内存的暧昧形成鲜明对比,这显然与AM2平台CPU在DDR2内存下表现不尽如人意有关:要表现出AMD CPU从DDR平台迁移到DDR2平台的优势,其对DDR2内存频率提高的要求比Intel Core更甚,但现阶段以DDR2 533/667为主的内存市场,则让AM2 CPU更多地受制于DDR2内存的高时延而不是受益于DDR2内存的高频率。
AMD计划在下一代的K8L架构CPU中全面导入对DDR3内存的支持。在AMD的路线图看,K8L CPU将支持同时DDR2和DDR3内存,但很显然,DDR2内存不是AMD最好的选择,高频率、低时序的DDR3内存必然会是AMD积极开拓的对象。
同时,加大对DDR3内存的支持力度,也可以让AMD改善与Intel的竞争中的被动地位。
DDR3内存的发展
早在2002年6月28日,JEDEC就宣布开始开发DDR3内存标准,但从目前的情况来看,DDR2才刚开始普及,DDR3标准更是连影也没见到。不过目前已经有众多厂商拿出了自己的DDR3解决方案,纷纷宣布成功开发出了 DDR3内存芯片,从中我们仿佛能感觉到DDR3临近的脚步。而从已经有芯片可以生产出来这一点来看,DDR3的标准设计工作也已经接近尾声。
半导体市场调查机构iSuppli预测DDR3内存将会在2008年替代DDR2成为市场上的主流产品,iSuppli认为在那个时候DDR3的市场份额将达到55%。不过,就具体的设计来看,DDR3与DDR2的基础架构并没有本质的不同。从某种角度讲,DDR3是为了解决DDR2发展所面临的限制而催生的产物。
由于DDR2内存的各种不足,制约了其进一步的广泛应用,DDR3内存的出现,正是为了解决DDR2内存出现的问题,具体有:
更高的外部数据传输率
更先进的地址/命令与控制总线的拓朴架构
在保证性能的同时将能耗进一步降低
为了满足这些要求,DDR3内存在DDR2内存的基础上所做的主要改进包括:
8bit预取设计,DDR2为4bit预取,这样DRAM内核的频率只有接口频率的1/8,DDR3-800的核心工作频率只有100MHz。
采用点对点的拓朴架构,减轻地址/命令与控制总线的负担。
采用100nm以下的生产工艺,将工作电压从1.8V降至1.5V,增加异步重置(Reset)与ZQ校准功能。
DDR3内存的封装
从规格来看,DDR3仍将沿用FBGA封装方式,故在生产上与DDR2内存区别不大。但是由设计的角度上来看,因DDR3的起跳工作频率在1066MHz,这在电路布局上将是一大挑战,特别是电磁干扰,因此也将反映到PCB上增加模块的成本。
预计在DDR3进入市场初期,其价格将是一大阻碍,而随着逐步的普及,产量的提升才能进一步降低成本。
DDR3内存的技术改进
那么,从技术看,DDR3内存与目前主流的DDR2内存相比,其特点体现在哪些方面呢?我们首先介绍DDR3内存针对DDR2中存在的不足的改进
逻辑Bank数量
DDR2 SDRAM中有4Bank和8Bank的设计,目的就是为了应对未来大容量芯片的需求。而DDR3很可能将从2Gb容量起步,因此起始的逻辑Bank就是8个,另外还为未来的16个逻辑Bank做好了准备。
封装(Packages)
DDR3由于新增了一些功能,所以在引脚方面会有所增加,8bit芯片采用78球FBGA封装,16bit芯片采用96球FBGA封装,而DDR2则有60/68/84球FBGA封装三种规格。并且DDR3必须是绿色封装,不能含有任何有害物质。
突发长度(BL,Burst Length)
由于DDR3的预取为8bit,所以突发传输周期(BL,Burst Length)也固定为8,而对于DDR2和早期的DDR架构的系统,BL=4也是常用的,DDR3为此增加了一个4-bit Burst Chop(突发突变)模式,即由一个BL=4的读取操作加上一个BL=4的写入操作来合成一个BL=8的数据突发传输,届时可通过A12地址线来控制这一突发模式。而且需要指出的是,任何突发中断操作都将在DDR3内存中予以禁止,且不予支持,取而代之的是更灵活的突发传输控制(如4bit顺序突发)。
寻址时序(Timing)
就像DDR2从DDR转变而来后延迟周期数增加一样,DDR3的CL周期也将比DDR2有所提高。DDR2的CL范围一般在2至5之间,而DDR3则在5至11之间,且附加延迟(AL)的设计也有所变化。DDR2时AL的范围是0至4,而DDR3时AL有三种选项,分别是0、CL-1和CL-2。另外,DDR3还新增加了一个时序参数——写入延迟(CWD),这一参数将根据具体的工作频率而定。
DDR3内存的新增功能
如果上一部分介绍的DDR3内存对DDR2内存的改进更多的是某种程度上的修正或简单提高的话,DDR3内存还有部分DDR2内存所不具备的功能,正是这些,让DDR3内存的表现有了根本性的提高
重置(Reset)
重置是DDR3新增的一项重要功能,并为此专门准备了一个引脚。DRAM业界已经很早以前就要求增这一功能,如今终于在DDR3身上实现。这一引脚将使DDR3的初始化处理变得简单。当Reset命令有效时,DDR3内存将停止所有的操作,并切换至最少量活动的状态,以节约电力。在Reset期间,DDR3内存将关闭内在的大部分功能,所以有数据接收与发送器都将关闭。所有内部的程序装置将复位,DLL(延迟锁相环路)与时钟电路将停止工作,而且不理睬数据总线上的任何动静。这样一来,将使DDR3达到最节省电力的目的。
ZQ校准
ZQ也是一个新增的脚,在这个引脚上接有一个240欧姆的低公差参考电阻。这个引脚通过一个命令集,通过片上校准引擎(ODCE,On-Die Calibration Engine)来自动校验数据输出驱动器导通电阻与ODT的终结电阻值。当系统发出这一指令之后,将用相应的时钟周期(在加电与初始化之后用512个时钟周期,在退出自刷新操作后用256时钟周期、在其他情况下用64个时钟周期)对导通电阻和ODT电阻进行重新校准。
参考电压分成两个
对于内存系统工作非常重要的参考电压信号VREF,在DDR3系统中将分为两个信号。一个是为命令与地址信号服务的VREFCA,另一为数据总线服务的VREFDQ,它将有效的提高系统数据总线的信噪等级。
根据温度自动自刷新(SRT,Self-Refresh Temperature)
为了保证所保存的数据不丢失,DRAM必须定时进行刷新,DDR3也不例外。不过,为了最大的节省电力,DDR3采用了一种新型的自动自刷新设计(ASR,Automatic Self-Refresh)。当开始ASR之后,将通过一个内置于DRAM芯片的温度传感器来控制刷新的频率,因为刷新频率高的话,消电就大,温度也随之升高。而温度传感器则在保证数据不丢失的情况下,尽量减少刷新频率,降低工作温度。不过DDR3的ASR是可选设计,并不见得市场上的DDR3内存都支持这一功能,因此还有一个附加的功能就是自刷新温度范围(SRT,Self-Refresh Temperature)。通过模式寄存器,可以选择两个温度范围,一个是普通的的温度范围(例如0℃至85℃),另一个是扩展温度范围,比如最高到 95℃。对于DRAM内部设定的这两种温度范围,DRAM将以恒定的频率和电流进行刷新操作。
局部自刷新(RASR,Partial Array Self-Refresh)
这是DDR3的一个可选项,通过这一功能,DDR3内存芯片可以只刷新部分逻辑Bank,而不是全部刷新,从而最大限度的减少因自刷新产生的电力消耗。这一点与移动型内存(Mobile DRAM)的设计很相似。
点对点连接(P2P,Point-to-Point)
这是为了提高系统性能而进行了重要改动,也是与DDR2系统的一个关键区别。在DDR3系统中,一个内存控制器将只与一个内存通道打交道,而且这个内存通道只能一个插槽。因此内存控制器与DDR3内存模组之间是点对点(P2P,Point-to-Point)的关系(单物理Bank的模组),或者是点对双点(P22P,Point-to-two-Point)的关系(双物理Bank的模组),从而大大减轻了地址/命令/控制与数据总线的负载。而在内存模组方面,与DDR2的类别相类似,也有标准DIMM(台式PC)、SO-DIMM/Micro-DIMM(笔记本电脑)、FB-DIMM2(服务器)之分,其中第二代FB-DIMM将采用规格更高的AMB2(高级内存缓冲器)。不过目前有关DDR3内存模组的标准制定工作刚开始,引脚设计还没有最终确定。
此外,DDR3还在功耗管理,多用途寄存器方面有不少新的设计。
第五节 Exynos 4412的DDR3初始化流程Exynos4412中有两个独立的DRAM控制器,分别叫DMC0和DMC1。DMC0和DMC1分别支持最大1.5GB的DRAM,它们都支持DDR2/DDR3和LPDDR2等,512 Mb, 1 Gb, 2 Gb, 4 Gb and 8 Gbit的内存设备,支持16/32bit的位宽。DRAM0 对应的地址是0x4000_0000~0xBFFF_FFF共1.5GB,DRAM1 对应的地址是0xA000_000~0x0000_0000共1.5GB。
在三星提供的数据手册《SEC_Exynos4412_Users Manual_Ver.1.00.00》的第1046页提供给了一段关于LPDDR2-S4的初始化步骤,LPDDR2表示低功耗DDR2,DDR3的初始化过程应和这个一样,我们就按这个过程来初始化DDR3:
DDR 大体初始化流程
上图告诉我们如何初始化DDR2类型的DRAM,主要分为:
初始化PHY DLL
初始化控制寄存器
初始化DRAM
三大步骤,具体细分共21个小步骤下面我们就从数据手册提供的步骤开始熟悉一下流程,步骤如下:
18.3.1 LPDDR2-S4
Use the sequence given here to initialize LPDDR2 devices. Unlessspecified otherwise, these steps are
mandatory. Note that the memory CK/CKn must be less than or equal to50 MHz before you initialize the
LPDDR2-S4 device.
1. DMC must assert and holdCKE to a logic low level to provide stable power for memory device and thenapply
stable clock.
2. Set thePhyControl0.ctrl_start_point and PhyControl0.ctrl_inc bit-fields to a correctvalue according to clock
frequency. Set the PhyControl0.ctrl_dll_on bit-field to"1" to activate the PHY DLL.
3. DQS cleaning: Set thePhyControl1.ctrl_shiftc and PhyControl1.ctrl_offsetc bit-fields to theappropriate value
according to clock frequency, board delay, and memory tDQSCKparameter.
4. Set thePhyControl0.ctrl_start bit-field to "1".
5. Set the ConControl. Atthis moment, an auto-refresh counter should be disabled.
6. Set the MemControl. Atthis moment, all power down modes should be disabled.
7. Set the MemConfig0register. When there are two external memory chips, set the MemConfig1register.
8. Set the PrechConfig andPwrdnConfig registers.
9. Set the TimingAref,TimingRow, TimingData, and TimingPower registers according to memory AC
parameters.
10. Set the QosControl0 to 15and QosConfig0 to 15 registers when a certain bus master requires QoS scheme.
11. Wait for thePhyStatus0.ctrl_locked bit-fields to change to "1". Verify whetherPHY DLL is locked.
PHY DLL compensates the changes of delay amount that pressure,volume, and temperature variation
causes during memory operation. Therefore, you should not power offPHY DLL for reliable operation.
It can be in power-off mode except when it runs at low frequency.When you use the power-off mode,
set the PhyControl0.ctrl_force bit-field to the correct valueaccording to the PhyStatus0.ctrl_lock_value[9:2]
bit-field for fix delay amount. Clear the PhyControl0.ctrl_dll_onbit-field to turn off PHY DLL.
12. Set thePhyControl1.fp_resync bit-field to "1" to update DLL information.
13. Confirm that Clock Enable(CKE) is in a logic low level at least 100ns after power on.
14. Issue a NOP command byusing the DirectCmd register to assert and hold CKE to a logic high level.
15. Wait for a minimum of 200ms.
16. Issue a MRS command byusing the DirectCmd register to reset memory devices and program the operating
parameters.
17. Wait for minimum of 1 ms.
18. Issue a MRR command byusing the DirectCmd register to poll the DAI bit of the MRStatus register.
This is to know whether or not Device Auto-Initialization iscomplete.
19. If there are two externalmemory chips, execute step 14 to 19 for chip1 memory device.
20. Set the ConControl toturn on an auto-refresh counter.
21. Set MemControl registerwhen you require power-down modes.
翻译上面的步骤:
1、DMC功能必须设置,并且要保持CKE为低电平,以便可以提供稳定的电源和时钟给DDR
2、根据时钟频率设置PhyControl0.ctrl_start_point 和PhyControl0.ctrl_inc bit-fields,并且设置PhyControl0.ctrl_dll_on bit-field 为 "1" 已启动PHY DLL。
3、DQS 清除,根据时钟频率、板子延时和芯片的tDQSCK参数设置PhyControl1.ctrl_shiftc 和PhyControl1.ctrl_offsetcbit-fields。
4、设置 PhyControl0.ctrl_start bit-field 为"1"。
5、设置ConControl,此时,不能使能自动刷新计数器(auto-refresh counter )。
6. 设置MemControl,此时,所有的power down模式应关闭。
7、设置MemConfig0 寄存器,当外面有两片存储芯片时,设置MemConfig1寄存器。
8、设置 PrechConfig和 PwrdnConfig寄存器。
9、根据DDR3的 AC参数设置TimingAref, TimingRow, TimingData, 和 TimingPower寄存器。
10、当总线主控者需要QoS时序参数时,设置QosControl0 到15寄存器和QosConfig0 到 15寄存器。
11、等待 PhyStatus0.ctrl_locked bit-fields 变成 "1",以确定 PHY DLL 是否锁定。PHY DLL 可以补偿压力、体积?和温度等环境的变化,因为在芯片工作期间,我们不能关闭了PHY DLL的电源,只有当他在低的时钟频率时才可以切换到Power-off 模式,当我们用power-off 模式,参考PhyStatus0.ctrl_lock_value[9:2]的延时参数来设置PhyControl0.ctrl_forcebit-field,清楚PhyControl0.ctrl_dll_on bit-field来关闭 PHY DLL。
12、设置PhyControl1.fp_resync bit-field 为 "1" 来更新 DLL的设置。
13、确保在电源上电后至少保持Clock Enable (CKE)在低电平100ns。
14、用DirectCmd 寄存器来执行一条NOP指令且保持CKE 为高电平。
15、至少等待200us。
16、发出MRS指令来重新设置存储芯片的操作参数。
17、至少等待1us。
18、用MRR指令来查询MRStatus的寄存器的DAI位,用这们来确定自动初始化过程是否完成。
19、如果外部有别的存储芯片,重复执行14到19步来设置芯片1。
20、设置ConControl来启动auto-refresh counter.
21、当我们要进行power-down模式,设置MemControl寄存器。
按照上边的步骤来设置就可以完成DDR的初始化,下一节我们进行UT4412BV03开发板的DDR操作。
第六节 查看原理图UT4412BV03的1GB的DRAM是由4片大小为128MX16的DDR3芯片组合而成,下面看一下UT4412BV03的原理图:
接在DMC0
接在DMC1
从上两图可以看出,这四片DDR 芯片被分成了两两一组,组成32位数据,从片选引脚可以看出:两片挂接到DMC0处,另两片挂接到DMC1处。
如何才能使用DRAM?对应UT4412BV03而言,由于用到了DMC0和DMC1,所有我们需要初始化DMC0、DMC1和DDR3 DRAM芯片。
第七节 程序相关讲解完整代码见目录8.ddr3_init,与前一章的代码相比,代码多了ddr3_mem_init.c。
1. start.S
.text
.globl _start
_start:
//关看门狗
ldr r1, = 0x10060000
mov r0, #0x0
str r0, [r1]
//使能Icache,P15协寄存器的第12位
orr r0, r0, #0x00001000
mcr p15, 0, r0, c1, c0, 0
//设置栈
ldr sp, =0x02050000
bl system_clock_init
bl ddr3_mem_init
bl main
halt:
b halt
代码同上一章的start.S相比,添加了 bl ddr3_mem_init,即就是调用DDR3初始化程序。
2. ddr3_mem_init.c
void ddr3_mem_init (void)
{
#if 0
unsigned int *p = (unsigned int *)0;
/* Async bridge configuration at CPU_core:
* 1: half_sync
* 0: full_sync */
p = (unsigned int *)0x10010350;
*p = 1;
#endif
/*****************************************************************/
/*DREX0***********************************************************/
/*****************************************************************/
DMC0_PHYCONTROL1 = 0xe0000086;
/*2. If on die termination is required, enable PhyControl1.term_write_en,
PhyControl1.term_read_en.*/
DMC0_PHYZQCONTROL = 0xE3854C03;
/*3. If ZQ calibration is required, disable PhyZQControl.
ctrl_zq_mode_noterm and enable PhyZQCon-trol.
ctrl_zq_start so that the PHY automatically calibrates
the I/Os to match the driving and termination impedance
by referencing resistor value of an external resistor
and updates the matched value during auto re-fresh cycles.*/
delay(0x10000);
DMC0_PHYCONTROL0 = 0x7110100A;
/*4. Set the PhyControl0.ctrl_start_point and PhyControl0.
ctrl_inc bit-fields to correct value according to clock frequency.
Set the PhyControl0.ctrl_dll_on bit-field to "1" to activate the PHY DLL.*/
DMC0_PHYCONTROL1 = 0xe0000086;
/*5. DQS Cleaning: set the PhyControl1.ctrl_shiftc and PhyControl1.
ctrl_offsetc bit-fields to the proper value according to clock frequency,
board delay and memory tDQSCK parameter.*/
DMC0_PHYCONTROL0 = 0x7110100B;
/*6. Set the PhyControl0.ctrl_start bit-field to "1".*/
DMC0_PHYCONTROL2 = 0x00000000;
/*DQS offset,默认值就是0x00000000,可以不用设置*/
DMC0_CONCONTROL = 0x0FFF301A;
/*7. Set the ConControl. At this moment,
an auto refresh counter should be off.*/
DMC0_MEMCONTROL = 0x00312640;
/*8. Set the MemControl. At this moment,
all power down modes and periodic ZQ(pzq_en) should be off.*/
DMC0_MEMCONFIG0 = 0x40C01323;
DMC0_MEMCONFIG1 = 0x60e01323;
/*9. Set the MemConfig0 register. If there are two external memory chips, also set the MemConfig1 register.*/
DMC0_IVCONTROL = 0x8000001F;
/*Memory Channel Interleaving*/
/*实验了一下可以省略,用默认值就可以*/
DMC0_PRECHCONFIG = 0xff000000;
/*10. Set the PrechConfig and PwrdnConfig registers.*/
DMC0_TIMINGAREF = 0x000000BB;
DMC0_TIMINGROW = 0x4046654f;
DMC0_TIMINGDATA = 0x46400506;
DMC0_TIMINGPOWER = 0x52000a3c;
/*11. Set the TimingAref, TimingRow, TimingData and
TimingPower registers according to memory AC parame-ters.*/
/* chip 0 */
DMC0_DIRECTCMD = 0x07000000;
/*19. Issue a NOP command using the DirectCmd register to assert and to hold CKE to a logic high level.*/
delay(0x10000);
/*20. Wait for tXPR(max(5nCK,tRFC(min)+10ns)) or set tXP to tXPR value before step 17. If the system set tXP to tXPR, then the system must set tXP to proper value before normal memory operation.*/
DMC0_DIRECTCMD = 0x00020000;
DMC0_DIRECTCMD = 0x00030000;
DMC0_DIRECTCMD = 0x00010002;
DMC0_DIRECTCMD = 0x00000328;
delay(0x10000);
DMC0_DIRECTCMD = 0x0a000000;
/*26. Issues a ZQINIT commands using the DirectCmd register.*/
delay(0x10000);
/*27. If there are two external memory chips, perform steps 19 ~ 26 procedures for chip1 memory device.*/
#if 0
/* chip 1 */
DMC0_DIRECTCMD = 0x07100000;
delay(0x100000);
DMC0_DIRECTCMD = 0x00120000;
DMC0_DIRECTCMD = 0x00130000;
DMC0_DIRECTCMD = 0x00110002;
DMC0_DIRECTCMD = 0x00100328;
delay(0x100000);
DMC0_DIRECTCMD = 0x0a100000;
delay(0x100000);
#endif
DMC0_PHYCONTROL1 = 0xe000008e;
DMC0_PHYCONTROL1 = 0xe0000086;
delay(0x10000);
/*****************************************************************/
/*DREX1***********************************************************/
/*****************************************************************/
DMC1_PHYCONTROL1 = 0xe0000086;
DMC1_PHYZQCONTROL = 0xE3854C03;
delay(0x10000);
DMC1_PHYCONTROL0 = 0x7110100A;
DMC1_PHYCONTROL1 = 0xe0000086;
DMC1_PHYCONTROL0 = 0x7110100B;
DMC1_PHYCONTROL2 = 0x00000000;
DMC1_CONCONTROL = 0x0FFF301A;
DMC1_MEMCONTROL = 0x00312640;
DMC1_MEMCONFIG0 = 0x40C01323;
DMC1_MEMCONFIG1 = 0x60e01323;
DMC1_IVCONTROL = 0x8000001F;
DMC1_PRECHCONFIG = 0xff000000;
DMC1_TIMINGAREF = 0x000000BB;
DMC1_TIMINGROW = 0x4046654f;
DMC1_TIMINGDATA = 0x46400506;
DMC1_TIMINGPOWER = 0x52000a3c;
/* chip 0 */
DMC1_DIRECTCMD = 0x07000000;
delay(0x10000);
DMC1_DIRECTCMD = 0x00020000;
DMC1_DIRECTCMD = 0x00030000;
DMC1_DIRECTCMD = 0x00010002;
DMC1_DIRECTCMD = 0x00000328;
delay(0x10000);
DMC1_DIRECTCMD = 0x0a000000;
delay(0x10000);
#if 0
/* chip 1 */
DMC1_DIRECTCMD = 0x07100000;
delay(0x100000);
DMC1_DIRECTCMD = 0x00120000;
DMC1_DIRECTCMD = 0x00130000;
DMC1_DIRECTCMD = 0x00110002;
DMC1_DIRECTCMD = 0x00100328;
delay(0x100000);
DMC1_DIRECTCMD = 0x0a100000;
delay(0x100000);
#endif
DMC1_PHYCONTROL1 = 0xe000008e;
DMC1_PHYCONTROL1 = 0xe0000086;
delay(0x10000);
/*****************************************************************/
/*Finalize********************************************************/
/*****************************************************************/
DMC0_CONCONTROL = 0x0FFF303A;
/*28. Set the ConControl to turn on an auto refresh counter.*/
DMC1_CONCONTROL = 0x0FFF303A;
/*28. Set the ConControl to turn on an auto refresh counter.*/
}
大家可以结合程序,对照Exynos 4412的DDR3的初始化流程分析下。
第八节 编译代码和烧写运行将sd卡插入PC,在Ubuntu终端执行如下命令:
#cd 8.ddr3_init
#make
# sudo ./sd_fusing.sh /dev/sdb bl2.bin
第九节 实验现象将sd卡插入UT4412BV03中,选择sd卡启动,然后上电。(注:内存的地址范围0x40000000-0x7FFFFFFF,共1GB)
对0x40000000进行读取
对0x6ff00000进行读取
对0x70000000写入0x12345678
对0x70000000进行读取