FPGA(Field-Programmable Gate Array),即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。
FPGA工作原理
FPGA采用了逻辑单元阵列LCA(LogicCell Array)这样一个概念,内部包括可配置逻辑模块CLB(Configurable Logic Block)、输出输入模块IOB(InputOutputBlock)和内部连线(Interconnect)三个部分。 现场可编程门阵列(FPGA)是可编程器件。与传统逻辑电路和门阵列(如PAL,GAL及CPLD器件)相比,FPGA具有不同的结构,FPGA利用小型查找表(16×1RAM)来实现组合逻辑,每个查找表连接到一个D触发器的输入端,触发器再来驱动其他逻辑电路或驱动I/O,由此构成了即可实现组合逻辑功能又可实现时序逻辑功能的基本逻辑单元模块,这些模块间利用金属连线互相连接或连接到I/O模块。FPGA的逻辑是通过向内部静态存储单元加载编程数据来实现的,存储在存储器单元中的值决定了逻辑单元的逻辑功能以及个模块之间或模块与I/O间的连接方式,并最终决定了逻辑单元的逻辑功能以及各模块之间或模块与I/O间的联接方式,并最终决定了FPGA所能实现的功能, FPGA允许无限次的编程。
SDRAM是具有同步接口的高速动态随机访问存储器。它由于具有大容量、读写速度较快、支持突发式读写及价格低廉而得到了广泛的应用。但是近几年来,市面上出现了一种从SDRAM技术发展而来的DDR(Double DataRate)SDRAM新型存储器。该存储器除了具有SDRAM的所有优点外,还由于采用了双时钟差分信号等技术,使其在时钟触发沿的上、下沿都能进行数据传输(传输速率是普通SDRAM的2倍),且在价格上也低于SDRAM。但由于它在时钟的上升沿和下降沿均能读取数据,这就使得DDR SDRAM控制器较普通的SDRAM控制器更难于设计。为此,本文给出了一种通用DDR SDRAM控制器的一般设计方法,并利用数字锁相环技术解决了DDR SDRAM特有的读写方式难于控制的问题。
1 DDR SDRAM的基本操作和命令
掌握DDR SDRAM(以下简称DDR)的操作是成功设计一个DDR SDRAM控制器的前提条件。
DDR支持的常用命令有:空操作(Nop)、激活操作(Active)、突发读(Burst Read)、突发写(Burst Write)、自动刷新(Autorefresh)、预充电(Precharge)、模式寄存器配置(Mode Register Set)等。所有的操作命令都通过信号线RAS_N、CAS_N、WE_N共同控制。
在进行读、写操作之前必须激活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期间处理数据交换。
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内部包含了锁相环电路,可以直接调用。
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控制器。