FPGA实现的SDRAM驱动

SDRAM的时序分析以及仿真和实测。

一、SDRAM 简介

SDRAM 同步动态随机存储器(Synchronous Dynamic Random Access Memory)。SDRAM 的时钟频率能达到100MHz以上,主要用于程序的运行空间、大数据存储等;Memory工作需要同步时钟,又由于信息存放在电容上,所以需要不断地刷新来维持当前保存的数据。SDRAM 通常有多个逻辑BANK(L-BANK)构成,每个BANK排列有多个存储单元,通过BANK地址以及行、列地址来确定一个存储单元。在这个设计中用到的是海力士(hynix)的一款SDRAM(H57V2562GTR)容量为4BANK*4M*16bit,行地址13位,列地址9位(行列地址复用),一个BANK:2^13行*2^9列=8192*512=4194304。

二、SDRAM时序

1、SDRAM初始化

在使用SDRAM之前要对其进行初始化,初始化时序如下图。

FPGA实现的SDRAM驱动_第1张图片 图1 初始化时序图

从图中可以看到,在初始化的过程中需要用到一些命令和地址总线(地址总线是复用的,A[12:0]是ROW ADDR,A[8:0]是COL ADDR,也就是有13位的行地址,9位的列地址,在读写数据的时候先发送行地址,再发送列地址)。上图中所有的COMMAND或者地址等,都应该保证在时钟的上升沿时有效,且要保证信号的建立时间(tCMS)和保持时间(tCMH),图中所有的时间长度在芯片的datasheet中都能找到,可参考美光SDRAM(MT48LC16M16A2)查找。初始化时COMMAND通过SDRAM的CKEn、CS_n、RAS_n、CAS_n、WE_n、以及BANK[1:0]、ADDR等引脚发送到SDRAM,具体真值表可见图2。

FPGA实现的SDRAM驱动_第2张图片 图2 命令真值表

图1中,系统上电后,首先应该等待一个power-up的时间,这个时间最小是100us,这段时间不需要COMMAND,但在power-up后有一个NOP命令(这里个人觉得可以直接将power-up时间内的COMMAND全设为NOP);然后进入一个预充电时间,这时要发送一个PRECHARGE命令,同时如果对所有BANK预充电那么地址线A10要拉高,对单个BANK预充电那么地址线A10要拉低,PRECHARGE之后要等待一个tRP时间,tRP时间内COMMAND不重要;再然后就是紧接着的两次自动刷新命令,每一次AUTO REFRESH命令都要等待一个tRFC的时间,而且在等待时间内的COMMAND为NOP命令;初始化的最后一步就是加载模式寄存器,在LOAD MODE REGISTER命令后同样要等待一个tMRD时间,tMRD时间内的COMMAND为NOP命令,模式寄存器的值可以在图3找到。

FPGA实现的SDRAM驱动_第3张图片 图3 模式寄存器

 其中A[9]位可配置SDRAM写的模式,为0表示突发读和突发写,为1表示突发读和单个写;A[6:4]位是CAS Latency,表示在读数据的时候,数据在发送COL ADDR之后的多少个时钟数据输出,具体时序在后面图4中可见;A[3]表示选择读写的类型是交错读写还是连续读写(在此设计中设置为0,连续读写);A[2:0]设置突发的模式,可以选择突发读写1/2/4/8个内存单元,在连续读写类型时可以选择整页读写(也就是一行512*16bit)。

 2、读写时序

在读写过程中可以将SDRAM设置为多种方式,下面是在自动预充电下的读写时序。

Read with auto precharge:

FPGA实现的SDRAM驱动_第4张图片 图4 自动预充电读时序

 在SDRAM的初始化之后就可以进行读和写的操作了,在读的时候,要先发送一个ACTIVE命令,与此同时发送行地址和BANK地址,然后等待一个tRCD时间(ROW ADDR 到 COL ADDR 延时);ACTIVE后才是发送READ命令,同时发送列地址、BANK地址并拉高A[10]位使能自动预充电(A[10]是自动预充电的一个标志位),然后就是等待之前MODE REGISTER中的CAS Latency(CL)这么长的时间后,读的数据就有效了;在读出数据的最后其实也同样有一个tRP的时间,由于在前面是能了自动预充电,所以这里就不需要再发送自动预充电的命令了(这里可以对比 read without auto precharge的时序图);在读完一次之后就可以开启下一次的读或者写了。       注:PRECHARGE命令表示结束当前行,准备开启下一行的操作。

Write with auto precharge与读操作有所不同,大致差不多,具体时序如图5。

FPGA实现的SDRAM驱动_第5张图片 图5 自动预充电写时序

3、刷新

SDRAM的工作方式要求在一定时间内对存储的数据进行刷新,不然保存的数据会丢失。电容最大保存时间是64ms,也就是最多每隔64ms就要对所有存储单元进行一次刷新,每一次刷新操作可以刷新所有BANK的同一行,H57V2562GTR一个BANK8192行,也就是要在64ms内刷新完8192行,64ms/8192=7.813us,所以刷新一行的时间应该小于7.813us,这里我设置的是7us。每隔7us就要生成一次刷新请求,发送一个AUTO REFRESH的命令,在刷新过程中,不能进行的读写操作。

三、仿真和实测

个人根据SDRAM控制时序写的一个驱动程序,实测能进行数据读写,肯定有不完整的地方,有需要的可以在https://download.csdn.net/my下载(与下面LED显示功能无关),里面包括QUARTUS工程(verilog)。

FPGA实现的SDRAM驱动_第6张图片 图5 仿真时序图

仿真时序可能看的不太清楚,细节还需要在实际仿真文件中查看。实测的文件是将“5”写入 sdram,然后在读出来通过LED显示,如图6所示,Signal Tap时序采样如图7所示。

FPGA实现的SDRAM驱动_第7张图片 图6
图7

 

图6中左起第三个LED表示显示数据低三位,LED上拉,“0”亮,“1”熄灭,此时显示的是“101”,也就是数据“5”。 程序设计肯定有不足的地方,仅供参考。

备注:

1、不使能自动预充电的情况下,Precharge命令同Burst Stop命令一样,在Burst Read过程中有停止读数据过程的作用,在Precharge/Burst Stop命令后的CAS Latency个时钟停止读过程;而Burst  Write过程在Precharge/Burst Stop命令时立即停止写过程。另外在使能自动预充电的情况下,海力士的资料上说不能通过Precharge/Burst Stop命令来停止读、写过程,如下图,这点我也没能弄明白。

FPGA实现的SDRAM驱动_第8张图片

2、Burst Read和Burst  Write过程只要不停止(Precharge/Burst Stop),它会循环进行读/写。(整页突发模式时,其他情况还未验证过)。

3、注意在AUTO Refresh命令后的等到时间TAR,发送的命令是NOP命令。

你可能感兴趣的:(FPGA设计)