FPGA实战操作(1) -- SDRAM(操作说明)

SDRAM是做嵌入式系统中,常用是的缓存数据的器件。基本概念如下(注意区分几个主要常见存储器之间的差异):

SDRAM(Synchronous Dynamic Random Access Memory),同步动态随机存储器。同步
是指 Memory工作需要同步时钟,内部的命令的发送与数据的传输都以它为基准;动态是指存储阵
列需要不断的刷新来保证存储的数据不丢失,因为SDRAM中存储数据是通过电容来工作的,大家知道电容在自然放置状态是会有放电的,如果电放完了,也就意味着SDRAM中的数据丢失了,所以SDRAM需要在电容的电量放完之前进行刷新;随机是指数据不是线性依次存储,而是自由指定地址进行数据的读写。

1. 注意事项

以下是我在学习过程中总结的一些容易理解错误的细节,如果对其中有些概念不太明确,建议先学习基本概念。

1.1 突发长度(Burst Length)

突发传输是指:在行地址指定后,只要指定起始列地址与突发长度,内存就会依次地自动对后面相应数量的存储单元进行读/写操作而不再需要控制器连续地提供列地址。

  • 对SDRAM器件的读和写是面向突发的,而突发长度(BL)则是可编程的。
  • 突发长度决定了给定读写命令可以访问的最大的列位置的个数。
  • 不管是顺序(Sequential)还是交叉(Interleaved)突发类型,其突发长度均可为1,2,4,8或连续。对于顺序突发类型,还适用于连续的页面突发。
  • 连续页面突发与BURST TERMINATE命令一起使用以产生任意突发长度。
  • 保留状态不应使用,因为这会导致未知操作或与未来的版本不匹配。
    当读或写命令提交时,一个等于突发长度的列的块被有效选择。所有对该突发的访问发生在本块之内,意味着当遇到边界时,突发会在该块之内循环(wraps within the block)。当BL=2时,该块唯一地被A[8:1]所选择,当BL=4时,A[8:2],BL=8时,A[8:3]。其余的地址位被用于选择块内的起始地址。

1.2 自动刷新AS(Auto Refresh)和自刷新SR(Self Refresh)

刷新操作分为两种:自动刷新(Auto Refresh,简称AR)与自刷新(Self Refresh,简称SR)。不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。

对于AR, SDRAM内部有一个行地址生成器(也称刷新计数器)用来自动的依次生成行地址。由于刷新是针对一行中的所有存储体进行,所以无需列寻址,或者说CAS在RAS之前有效。所以,AR又称CBR(CAS Before RAS,列提前于行定位)式刷新。由于刷新涉及到所有L-Bank,因此在刷新过程中,所有L-Bank都停止工作,而每次刷新所占用的时间为9个时钟周期(PC133标准),之后就可进入正常的工作状态,也就是说在这9 个时钟期间内,所有工作指令只能等待而无法执行。64ms之后则再次对同一行进行刷新,如此周而复始进行循环刷新。显然,刷新操作肯定会对SDRAM的性能造成影响,但这是没办法的事情,也是DRAM相对于SRAM(静态内存,无需刷新仍能保留数据)取得成本优势的同时所付出的代价。

SR则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是STR(Suspend to RAM,休眠挂起于内存)。在发出AR命令时,将CKE置于无效状态,就进入了SR模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在SR期间除了CKE之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使CKE有效才能退出自刷新模式并进入正常操作状态。

2. 操作说明

我们以SDRAM芯片IS42S16320D为例,尽可能详细的说明一下对其实现操作的方法。相关的Verilog代码在后面给出。

2.1 时序

时序图如下图所示,在操作过程中,每个命令的执行或者数据的读写,都要满足相应的时序要求,一定要仔细

为满足命令锁存所需的建立时间tCMS和保持时间tCMH,需要对SD_clk采用与clk反向或者分频机制。
系统时钟clk为100MHz

2.2 刷新时间

SDRAM内部电容保存数据的最长时间是64ms,而我们一个BANK有8K行,64ms/8k~=7.8us,也就是说为了保证SDRAM内部的数据不被丢失,两次刷新之间的最大时间间隔为7.8us,所以为了能让SDRAM有更多的时间进行读或者写,并且留够余量,我们就设定SDRAM刷新的周期为7.7us。

从时序上看,在读写过程中如果需要刷新,则先进入PRECHARGE然后进入IDLE,再进行刷新。

因此我们要保证的是 刷新时间+需要等待的时间<=7.8us.
如果是读,则需要等待的时钟周期为 激活时间(tRCD)+ CAS Latency (tCL)+ 读一页的时间 +预充电的时间(tRP)
如果是写,则需要等待的时钟周期为 激活时间(tRCD)+ 写一页的时间 + 预充电的时间(tRP)

在实现上,可以采用定时和手动控制刷新两种方式结合。7.7us的定时计数器不断地进行,如果没计时到7.7us,有收到刷新请求信号,那么开始刷新,并且计数器重新计数。这样就可以实现,每读/写一次(读写完整时间应该满足上述要求),手动刷新。如果长期等待,则靠计数器定时刷新。

2.3 页操作(full page)

一般而言,要实现快速大数据的读写,可以采用页操作,即突发长度设计为full page。
SDRAM在页操作模式下必须使用突发停止命令停止其操作。这回要发挥页模式的灵活性和高效性,那么就要做成一个由外部输入数据控制其一次性操作的字节数,也就是说,外部在读写数据前事先控制一个寄存器,往寄存器写入需要操作的字节数,而进入读写操作后,SDRAM控制器根据外部给出的字节数在适当的时候发出突发停止命令,这样做到了SDRAM的读写操作的字节可以在1-256范围内灵活调整,增强了通用性。

2.4 状态机

IS42S16320D手册里面给出的状态图,仔细理解每个状态的流程及跳变条件。

3. 详细操作

IS42S16320D的操作主要包括上电初始化、空闲、读、写、刷新等状态。

3.1 初始化

芯片在上电之后有一些固定的操作,手册里面已经明确的说明,如下图。

主要包括以下几个步骤的操作,图表里面代表操作引脚的状态。


  • 上电延迟

上电后,芯片有个100us的延迟(其他RAM一说200us),期间命令指令设置为NOP或者COMMAND INHIBIT。CKE的状态呢(不管还是一直为高),貌似一直为高才行,因为命令依赖于clk的上升沿,而要使clk有效,必须置高CKE?

  • 预充电

电延迟以后,对所有bank进行预充电。Bank关闭现有工作行,准备打开新行的操作就是预充电(Precharge)。

  • 自动刷新

充电完成后,间隔tRP Command Period (PRE to ACT) 最小15ns,进行第一次自动刷新,再过tRC Command Period (REF to REF / ACT to ACT) 最小60ns,进行第二次自动刷新。

  • 模式寄存器配置

第二次自动刷新后,间隔tRC(60ns)再进行模式寄存器设置。注意,具体的模式依赖于A9-A0管脚的高低电平。具体参加下图。

  • 初始化完成

模式寄存器设置完成后,间隔tMRD Mode Register Program Time 14ns后,就可以给ACTIVE命令,即使行地址处于工作状态。


如下图所示,为功能仿真完成上电初始化过程。

3.2 行激活

IDLE状态进入读写前,一定要行激活ROW ACTIVE。行激活命令完成之后,需要经过tRCD Active Command To Read / Write Command Delay Time 15 ns才能进行读或写。同一bank,不同row,激活需要间隔至少6个周期;不同bank,不同row,激活需要间隔至少2个周期,可以提高速度。

3.3 写数据

写入的第一个数据与WRITE命令对齐,写完burs length的长度之后,输入自动变为高阻,不再接收数据。如果全页写入的话,如果不给burst terminate,会从头开始覆盖着写入。

如果采用全页写入的方式,当需要PRECHARGE的时候,需要预留tDPL的时间(14 ns,与最后一个数据的上升沿对齐),写入过程即被中断,然后在第一定时间(tRP)之后开始刷新。一般来说,write被中断时,可以拉高DQM以阻断数据的输入。采用PRECHARGE中断写操作的缺点是需要考虑合适的时间点去配置cmd和address。优点是它可以任何时候去中断写操作,不论是固定长度的写操作还是全页写操作。

注意:在读或写的命令中,A10控制是否自动预充电。

3.4 读数据

在连续读的时候,如果新的命令加入(写、读、预充电),发出时刻x必须满足最后一个期望读出的数据到来前的CAS Latency-1个周期。

在读转写的过程中,写命令发出时刻应在最后一个读出数据所在时刻。但是,在实际系统中,为了避免I/O切换输入输出状态时,出现冲突,所以写指令会延后一个周期。In a given system design, there may be a possibility that the device driving the input data will go Low-Z before the SDRAM DQs go High-Z. In this case, at least a single-cycle delay should occur between the last read data and the WRITE command.
控制DMQ来避免I/O冲突,在WRITE命令来之前三个周期就要把DMQ拉高。注意DMQ并不会直接抑制输出,只是抑制内部的buffer,所以当DMQ拉高时,实际上抑制之前buffer的数据还是照样输出。在WRITE命令来之前,必须把DMQ再拉低,否则输入无效。(For example, if DQM was LOW during T4 in Figure RW2, then the WRITEs at T5 and T7 would be valid, while the WRITE at T6 would be invalid.???)

4. 疑问

  • 周期性刷新的执行过程采用的是:每次在同一bank和同一row中读写完成后先预充电,再刷新2次。可不可以只刷新,而不用预充电???
  • 状态机上,CBR明明自动进入PRECHARGE,这怎么解释。

下一篇博文主要介绍Verilog实现对SDRAM控制的方式。

原文地址:https://www.cnblogs.com/rouwawa/p/7325751.html