FPGA实现SDRAM接口(2)--初始化

文章来源:FPGA技术联盟微信公众号

1、初始化

     SDRAM 的初始化是芯片上电后必须进行的一项操作,只有进行了初始化操作的 SDRAM 芯片才可被正常使用。SDRAM 的初始化是一套预先定义好的流程,除此之外的其他操作会导致 SDRAM 出现不可预知的后果。

     初始化是对SDRAM芯片使用的第一步,只有学会了控制SDRAM进行初始化,才能正确的执行后续的读、写操作以及刷新操作。接下来,以Mircon公司的SDRAM芯片MT48LC64M4A2的数据手册为例,学习一下SDRAM的初始化时序,并进行仿真验证其正确性。

2、初始化时序

     MT48LC64M4A2的初始化时序如下:

MT48LC64M4A2的初始化时序.png

各信号说明如下:

     CK:工作时钟,具体时钟频率视不同的芯片而不同 

     CKE:时钟使能,在整个初始化过程中都需要拉高

     COMMAND:SDRAM命令,由4根线拼接而成,分别是CS#(片选信号),RAS#(行选通信号),CAS#(列选通信号),WE#(写使能信号),通过这4根命令线,再结合SDRAM的地址、输入输出数据等,就可以对SDRAM进行各种命令操作

     DQM/DQML,DQMU:数据掩码,通过数据掩码可以实现对输入或输出数据的某一字节进行“掩埋”,也就是使某一字节失效

     A[9:0],A[12:11]:数据地址线,同时也可用来设置模式寄存器

     A10:数据地址线,同时也可以用来使能一些具体操作,比如控制自动预充电使能、使能预充电bank数量

     BA[1:0]:bank地址

     DQ数据:在初始化过程中无数据输出,保持高阻态就行

通过对时序图的分析可以总结出初始化过程如下:

     1.上电后需保持时钟稳定状态至少100us(各芯片时间不同),同时CKE需拉高;同时需发送NOP空指令(发送空指令是为了防止对SDRAM进行误操作)

     2.对所有BANK进行预充电操作,A10拉高即是选中所有BANK

     3.进行预充电操作后需要等待一定的时间,即tRP,在此期间同样需要发送NOP空指令(发送空指令是为了防止对SDRAM进行误操作)

     4.等待结束后发送自动刷新指令

     5.进行自动刷新操作后需要等待一定的时间,即tRC,在此期间同样需要发送NOP空指令(发送空指令是为了防止对SDRAM进行误操作)

     6.重复进行发送自动刷新指令与等待tRFC,刷新次数不同的芯片不同

     7.发送模式寄存器设置指令,地址总线 A0-A11 参数不同 辅助模式寄存器不同模式的设置

     8.发送模式寄存器设置指令后需要等待一定的时间、即tMRD,在此期间同样需要发送NOP空指令(发送空指令是为了防止对SDRAM进行误操作)

     9.tMRD等待时间结束后,SDRAM 初始化完成。

3、名词理解

     上面出现了一些专有名词可能不太好理解或印象不深刻,接下来做一个盘点:

3.1、预充电

     SDRAM的寻址具有独占性,所以在进行完读写操作后,如果要对同一个Bank的另一行进行寻址,就要将原来有效(ACTIVE)的行关闭,重新发送行/列地址。Bank关闭当前工作行,准备打开新行的操作就是预充电。 预充电可以通过独立的命令控制,也可以在每次发送读写命令的同时使用“A10”线控制自动进行预充电。实际上,预充电是一种对工作中所有存储阵列进行数据重写,并对行地址进行复位,以准备新行的工作。

     预充电指令除了在初始化过程中用到外,在自动刷新以及读写操作中也都会被用到。

3.2、自动刷新

     SDRAM 内部存储体是利用电容能够保持电荷以及可充放电的特性制成,而电容所存储的电荷会随时间不断流失,会造成存储数据的丢失。为保证 SDRAM 中数据的可靠性,需要对 SDRAM 进行不断刷新。

     刷新操作分两种:“自动刷新”和“自刷新”。发送命令后CKE时钟为有效时(高电平),使用自动刷新操作,否则使用自我刷新操作。不论使用何种刷新方式,都不需要外部提供地址信息,因为这个是内部操作。

      对于“自动刷新”,SDRAM内部有一个行地址生成器(也称刷新计数器)用来自动地依次生成行地址,每收到一次命令刷新一行。在刷新过程中,所有的Bank都停止工作,而每次刷新所占用的时间为N个时钟周期。刷新结束后才可进入正常的工作状态,也就是说在这N个时钟期间内,所有工作指令只能等待而无法执行。一次次的按行刷新,刷新完所有行后,将再一次对第一行重新进行刷新操作,这个对同一行刷新操作的时间间隔,成为SDRAM的刷新周期,通常为64ms。显然,刷新会对SDRAM的性能造成影响,但这是SDRAM的特性决定的,也是SDRAM相对于SRAM取得成本优势的同时所付出的代价。

      “自刷新”则主要用于休眠模式低功耗状态下的数据保存,也就是说即使外部控制器件不工作了,SDRAM都能自己确保数据正常。在发出“自我刷新”命令后,将CKE置于无效状态(低电平),就进入自我刷新模式。此时不再依靠外部时钟工作,而是根据SDRAM内部的时钟进行刷新操作。在自我刷新期间,除了CKE之外的所有外部信号都是无效的,只有重新使CKE有效才能退出自我刷新模式并进入正常操作状态。

因为我们平常控制SDRAM都是在正常工作状态下使用,所以一般是对SDRAM进行自动刷新操作,这个具体的内容下篇再讲。

3.3、模式寄存器配置

     通过对SDRAM模式寄存器的配置可以实现对其各种工作方式、参数的控制,如突发长度BL、读潜伏期CL等,具体的设置方法可参见图(只需要在发送模式寄存器命令期间使能对应的地址线即可):

模式寄存器配置.png

对寄存器的各位说明如下:

     A12-A10:预留

     A9:读写方式,0:突发读&突发写;1:突发读&单写

     A8,A7:00:标准模式,默认

     A6,A5,A4:CAS潜伏期,分别为1、2、3、保留

     A3:突发传输方式,0:顺序;1:隔行

     A2,A1,A0:突发长度,000:1、2、4、8、全页

3.4、等待时间参数

以下时间参数根据芯片的不同可能存在差异:

     tRP:PRECHARGE  command  period,发送预充电指令后进行下一个操作需要等待的时间

     tRFC:AUTO  REFRESH  period,发送自动刷新指令后进行下一个操作需要等待的时间

   tMRD:LOAD MODE REGISTER command to ACTIVE or REFRESH command,发送设置模式寄存器指令后进行下一个操作需要等待的时间

4、初始化状态机

     根据初始化的时序图,不难绘制出如下状态机:

状态机.png

对各个状态、状态跳转条件、输出进行说明:

  • INIT_WAIT:  上电等待状态,等待时间满足100us要求后,跳转至下一状态INIT_PRE,在此状态发送NOP指令

  • INIT_PRE:    发送预充电指令状态、只维持一个时钟周期、下个时钟就跳转到状态INIT_TRP ,在此状态发送预充电指令

  • INIT_TRP:    预充电指令等待状态、在此状态等待时间满足TRP后就跳转到下一个状态INIT_AR,在此状态发送NOP指令  

  • INIT_AR:      发送自动刷新指令状态、只维持一个时钟周期、下个时钟就跳转到状态INIT_TRFC,在此状态发送自动刷新指令    

  • INIT_TRFC: 自动刷新指令等待状态、在此状态等待时间满足TRFC时进行判断,若自动刷新次数满足要求(2次或其他手册要求)后就跳转到下一个状态INIT_MRS,在此状态发送NOP指令,若不满足自动刷新次数要求就继续进行自动刷新操作,跳转到状态INIT_AR

  • INIT_MRS:   发送模式寄存器设置指令状态、只维持一个时钟周期、下个时钟就跳转到状态INIT_TMRD,在此状态发送模式寄存器设置指令     

  • INIT_TMRD:模式寄存器设置指令等待状态、在此状态等待时间满足TMRD后就跳转到下一个状态INIT_END,在此状态发送NOP指令    

  • INIT_END:   初始化结束状态,完成初始化后一直停留在这个状态;在此状态发送NOP指令,并将初始化完成信号拉高以通知其他模块开始进行工作

5、接口定义与整体设计

        Verilog编写的SDRAM初始化模块的整体框图、输入输出信号如下所示:

输入输出信号.png

 其中信号描述如下表:

信号描述.png

6、Verilog代码

     根据上述状态机描述、整体设计不难编写出模块实现的Verilog代码:

Verilog代码-1.png

Verilog代码-2.png

Verilog代码-3.png

Verilog代码-4.png

Verilog代码-5.png

Verilog代码-6.png

Verilog代码-7.png

Verilog代码-8.png

代码是用三段式状态机写的,其实用线性序列机也可以,只是三段式的可能会规范点。

7、Testbench

     Testbench除了例化了上面编写的SDRAM初始化模块外,还例化了一个PLL模块,分别输出50M、100M和相位偏移-30°的100M时钟信号(PLL模块就不给出了,都看到SDRAM了,不可能PLL都不会吧?)。

     除此之外还例化了一个网上找的SDRAM的仿真模型sdram_model_plus.

SDRAM的仿真模型-1.png

SDRAM的仿真模型-2.png

SDRAM的仿真模型-3.png

SDRAM的仿真模型-4.png

8、仿真结果

     仿真结果较长,分别截取如下:

仿真结果.png

上图:

  • 在计数器cnt_wait计时到19999后状态从等待状态跳转到预充电状态

  • 发送预充电指令后,进行等待,满足2个时钟的TRP时序要求后进行第一次自动刷新操作

  • 发送第一次自动刷新操作指令后,进行等待,满足7个时钟的TRFC时序要求后机型第二次自动刷新操作

  • 因为输出是用的时序逻辑,所以输出会落后条件一个时钟周期

时钟周期.png

上图:

  • 发送第8次(cnt_ar==8)自动刷新指令且满足TRFC时序要求后跳转到模式寄存器设置状态

  • 发送模式寄存器设置指令后,进行等待,满足3个时钟的TMRD时序要求后跳转到初始化完成状态,同时拉高完成标志init_end,以便其他模块开始进行工作

  • 因为输出是用的时序逻辑,所以输出会落后条件一个时钟周期

modlesim命令窗口打印的信息如下:

modlesim命令窗口打印的信息.png

可以看到全部满足状态机设置的要求:

  • 对所有bank进行了预充电

  • 进行了8次自动刷新 

  • 模式寄存器设置:CL为3个周期;全页突发写(通过终止突发写操作,可以达到突发写任意字节),顺序突发写类型;可设置突发长度。


最新文章

最新文章