摘 要:通用DDRSDRAM控制器的设计方法,以及一种解决DDR SDRAM所特有读写方式难于控制的问题的方法。
关键词:双数据率SDRAM数字锁相环预充电 突发读写
SDRAM是具有同步接口的高速动态随机访问存储器。它由于具有大容量、读写速度较快、支持突发式读写及价格低廉而得到了广泛的应用。但是近几年来,市面上出现了一种从SDRAM技术发展而来的DDR(Double Data Rate)SDRAM新型存储器。该存储器除了具有SDRAM的所有优点外,还由于采用了双时钟差分信号等技术,使其在时钟触发沿的上、下沿都能进行数据传输(传输速率是普通SDRAM的2倍),且在价格上也低于SDRAM。在需要大容量存储器的系统中,如台式机、工作站、服务器、高性能图形适配器等选用DDR SDRAM将是一种很好的选择。但是DDR SDRAM的控制时序比较复杂,要想和MCU、DSP等控制器芯片接口就必须利用可编程门阵列(如FPGA)设计一个DDR SDRAM控制器。但由于它在时钟的上升沿和下降沿均能读取数据,这就使得DDR SDRAM控制器较普通的SDRAM控制器更难于设计。为此,本文给出了一种通用DDR SDRAM控制器的一般设计方法,并利用数字锁相环技术解决了DDR SDRAM特有的读写方式难于控制的问题。
1 DDR SDRAM的基本操作和命令
掌握DDR SDRAM(以下简称DDR)的操作是成功设计一个DDR SDRAM控制器的前提条件。下面是一般的DDR所具备的操作。
DDR支持的常用命令有:空操作(Nop)、激活操作(Active)、突发读(Burst Read)、突发写(Burst Write)、自动刷新(Autorefresh)、预充电(Precharge)、模式寄存器配置(Mode Register Set)等。所有的操作命令都通过信号线RAS_N、CAS_N、WE_N共同控制。其基本操作命令如表1所示。
在进行读、写操作之前必须激活DDR存储体。一旦一个存储体被激活,它就必须在此存储体的下一个激活命令发出之前进行预充电。当对一个存储体读或写访问后,如果下一次要访问的行和当前访问的行不是同一行,则需要结束当前的存储体并重新打开它。预充电就是用来结束已激活的存储体的。
访问DDR的基本命令是读和写操作。当读命令发出时,地址总线上出现的就是要读的起始地址,1~3个时钟周期后要读的数据将会出现在数据总线上;当写命令发出时,起始地址和数据就分别出现在地址总线和数据总线上。在做读操作时,数据出现在数据总线上的周期数是由CAS延迟(CAS Latency,CL)决定的。CL依赖于DDR的速度和存储器时钟的频率。一般而言,时钟频率越快CL就越大。在BR或者BW命令初始化后,就会进行突发读或突发写,直到完成当前的突发长度(Burst length,BL)或突发结束(Burst Terminate,BT)命令发出才结束该操作。DDR存储器支持突发的长度为2、4或8个数据周期。
由于DDR是利用电容存储电荷的原理来保存信息的,而电容会逐渐放电。因此为了保证每个存储单元数据的正确性,DDR SDRAM控制器必须周期性地发出自动刷新命令,用户无需干预。在自动刷新命令发出之前,所有存储体都必须经过预充电并已经处于空闲状态。一旦刷新开始,由于内部有地址计数器,所以不需要外部地址的控制。
DDR中有模式寄存器,它的各种操作模式是:CAS延迟、地址模式、突发长度、突发类型、测试模式等。通过模式寄存器配置(MRS)命令将值写入到模式寄存器中。
2 DDR SDRAM 控制器的设计
2.1 DDR SDRAM控制器简介
本文讨论的DDR SDRAM控制器(简称DDR控制器)一方与MCU等控制器接口,另一方与DDR接口。同MCU等控制器的接口主要有地址总线(ADDR)、数据总线(DATA)、3位的命令总线(CMD[2:0])以及命令回答(CMDACK)等。地址总线和数据总线的位数取决于DDR的总线位数。DDR控制器接收从MCU发来的命令及数据,对命令进行译码,并向DDR发出相应的操作及数据。与DDR接口的一方主要是RAS_N、CAS_N、WE_N等控制信号线以及数据总线DDRDATA、地址总线DDRADDR等。整个DDR控制器由3个模块构成:控制接口模块、命令模块和数据通路模块。控制接口模块接收从MCU来的命令和相关存储器地址,对命令进行译码并将请求发送给命令模块;命令模块接收从控制接口模块译码后的命令和地址,产生相应的命令给DDR;数据通路模块在读命令READA和写命令WRITEA期间处理数据交换。DDR控制器总框图如图1所示。
2.2 DDR控制器的命令
DDR控制器共完成8种操作:NOP、READA、WRITEA、REFRESH、PRECHARGE、LOAD_MODE、LOAD_REG1、LOAD_REG2,其控制命令如表2所示。
这8种操作都是由MCU在命令总线CMD[2:0]上向DDR控制器发出的,DDR控制器在接收到诸如READA、WRITEA、REFRESH、PRECHARGE、LOAD_MODE等命令时将会向MCU发回答命令CMDACK。当MCU收到CMDACK命令后会在1个时钟周期后向DDR控制器发NOP命令。DDR控制器在发CMDACK命令的同时也会向DDR发相应的操作,也就是将DDR的RAS_N、CAS_N、WE_N置成相应的高位或低位。如果命令是READA或WRITEA,则需要重新从数据总线上读出数据或写入数据。各命令的功能如下。 (1)NOP空操作命令。在MCU接收到CMDACK命令后,MCU就会在一个时钟周期后向DDR控制器发出NOP命令。
(2)READA命令是带有预充电的突发读操作。MCU向DDR控制器发出READA命令的同时在地址总线ADDR上发出要读的地址;DDR控制器接收到后将向DDR发出激活(Active)命令,并向MCU发出CMDACK命令;几个时钟周期后,要读的DDR中的突发数据会由DDR控制器通过数据总线传送给MCU。
(3)WRITEA命令是带有预充电的突发写操作。其过程和READA的过程类似,也是在DDR控制器接收到MCU发出的WRITEA命令期间,在地址总线ADDR上接收要写入的地址,然后DDR控制器向DDR发出激活(Active)命令,并向MCU发出CMDACK命令。只是在WRITEA命令有效期间,要写入DDR的第一个突发数据就已经出现在数据总线上了。
(4)REFRESH命令是DDR控制器指示DDR完成自动刷新的命令。
(5)PRECHARGE命令是控制器指示DDR完成存储体预充电的命令。
(6)LOAD_MODE是用来配置DDR中的模式寄存器的,其值就是在MCU向DDR控制器发出LOAD_
MODE命令的同时在ADDR总线上传送的数值。当DDR控制器向DDR发出模式寄存器配置(MRS)命令时,ADDR总线上的值就会直接映射到DDR的地址总线上。
(7)LOAD_REG1和LOAD_REG2是配置DDR控制器内部2个寄存器的命令。
2.3 DDR控制器的内部寄存器
DDR控制器内部有2个16位的配置寄存器:REG1和REG2,其值分别由命令LOAD_REG1和LOAD_REG2命令写入。
REG1中包含了CAS延迟CL(REG1[1:0])、RAS到CAS延迟的时钟数RC(REG[3:2])、REFERSH命令持续时间的时钟数RRD(REG1[7:4])及突发长度BL(REG1[12:9])。
REG2是一个16位的寄存器,存储的是DDR控制器向DDR发出刷新命令的间隔时间。
2.4 各功能模块设计
2.4.1 控制接口模块
控制接口模块包含1个命令译码器和1个16位的刷新减计数器及相应的控制电路。命令译码器译码并寄存从MCU来的命令,将译码后的NOP、WRITEA、READA、REFRESH、PRECHARGE和LOAD_MODE等命令及相应的地址转送给命令模块。减计数器和相应的控制电路用来产生刷新命令给命令模块,其值就是由LOAD_REG2命令写入到REG2中的值。当计数器减到0时,控制接口模块就向命令模块发REFRESH_REQ并一直保持到命令模块发REFRESH_ACK来响应该请求。一旦控制接口模块接收到REFRESH_ACK,减计数器就会重新写入REG2中的值。
2.4.2 命令模块
命令模块由1个简单的仲裁器、命令发生器及命令时序器组成。它接收从控制接口模块来的译码后的命令,接收刷新控制逻辑发来的刷新请求命令并产生正确的命令给DDR。仲裁器在控制接口发来的命令(也就是MCU通过控制接口译码后的命令)和刷新控制逻辑发来的刷新请求命令之间进行仲裁。刷新请求命令的优先级高于控制接口来的命令。如果控制接口来的命令和刷新请求命令同时到达,或者同在一个刷新操作期间,则仲裁器就会拖延向MCU发CMDACK命令的时间直到刷新操作完成。如果刷新命令正在进行操作期间发出,则要一直等待到操作全部完成。
在仲裁器收到MCU发来的命令后,该命令就传送到命令发生器,命令时序器即用3个移位寄存器产生正确的命令时序后发给DDR。1个移位寄存器用来控制激活命令时序,1个用来控制READA和WRITEA命令,1个用来计时操作命令的持续时间,为仲裁器确定最后的请求操作是否完成。
2.4.3 数据通路模块
数据通路模块提供了DDR到MCU的数据通路。MCU从DDR设备读出的数据和MCU向DDR设备写入的数据都要经过数据通路模块。在MCU向DDR控制器发WRITEA命令时,数据总线DATA上要写入DDR的数据;在MCU向DDR控制器发READA命令时,数据总线DATA则从DDR读出数据。
数据通路模块在和DDR接口的一方完成了2个转换:一是将DDR过来的数据总线宽度翻倍,二是将DDR在时钟上、下沿送出的数据用200MHz的时钟频率接收。数据通路模块在和MCU接口的一方也相应地做了2个转换:一是将MCU过来的数据宽度减半送给DDR,二是将MCU工作在100MHz频率下的数据以200MHz的频率送给DDR。
DDR送来的数据是在100MHz的时钟频率的上升和下降沿被读出的,而到了数据通路模块则将时钟频率倍频到200MHz,因此只需在时钟的上升沿读出数据即可。其中的时钟倍频可采用数字锁相环技术将输入时钟升频。某些FPGA内部包含了锁相环电路(如Altera公司的FLEX10KA系列的FPGA),可以直接调用。
2.5 初始化过程
在MCU与DDR之间通信必须通过DDR控制器对DDR进行初始化:置DDR的突发长度、CL、突发类型以及操作模式等。在初始化完DDR后,MCU也必须对DDR控制器的2个内部寄存器进行设置,由MCU发LOAD_REG2和LOAD_REG1命令分别完成。整个DDR和DDR控制器的初始化过程为:(1)完成预充电PRECHARGE命令。(2)发LOAD_MODE命令。(3)发LOAD_REG2命令。(4)发LOAD_
REG1命令。
3 结束语
本文给出的通用DDR控制器的设计方法,可以很好地解决DDR在时钟上升和下降沿都能读取数据而不好控制的问题,而且可以直接利用FPGA内部提供的数字锁相环电路,避免了在设计中增加复杂的模拟电路。此外,开发者还可以根据自己的实际需要对该设计方法进行修改,以形成自己专用的DDR控制器。
参考文献
1 DDR SDRAM Specification.http://www.samsung.com,2002.5
2 夏宇闻.复杂数字电路与系统的Verilog HDL设计技术.北京:北京航空航天大学出版社,1998
3 戴梅萼,史嘉权.微型计算机技术及应用(第二版).北京:清华大学出版社,1996
4 常青,陈辉煌,孙广富等.可编程专用集成电路及其应用与设计实践.北京:国防工业出版社,1998