文章来源:FPGA技术联盟微信公众号
1、初始化
SDRAM 的初始化是芯片上电后必须进行的一项操作,只有进行了初始化操作的 SDRAM 芯片才可被正常使用。SDRAM 的初始化是一套预先定义好的流程,除此之外的其他操作会导致 SDRAM 出现不可预知的后果。
初始化是对SDRAM芯片使用的第一步,只有学会了控制SDRAM进行初始化,才能正确的执行后续的读、写操作以及刷新操作。接下来,以Mircon公司的SDRAM芯片MT48LC64M4A2的数据手册为例,学习一下SDRAM的初始化时序,并进行仿真验证其正确性。
2、初始化时序
MT48LC64M4A2的初始化时序如下:
各信号说明如下:
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等,具体的设置方法可参见图(只需要在发送模式寄存器命令期间使能对应的地址线即可):
对寄存器的各位说明如下:
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、初始化状态机
根据初始化的时序图,不难绘制出如下状态机:
对各个状态、状态跳转条件、输出进行说明:
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初始化模块的整体框图、输入输出信号如下所示:
其中信号描述如下表:
6、Verilog代码
根据上述状态机描述、整体设计不难编写出模块实现的Verilog代码:
代码是用三段式状态机写的,其实用线性序列机也可以,只是三段式的可能会规范点。
7、Testbench
Testbench除了例化了上面编写的SDRAM初始化模块外,还例化了一个PLL模块,分别输出50M、100M和相位偏移-30°的100M时钟信号(PLL模块就不给出了,都看到SDRAM了,不可能PLL都不会吧?)。
除此之外还例化了一个网上找的SDRAM的仿真模型sdram_model_plus.
8、仿真结果
仿真结果较长,分别截取如下:
上图:
在计数器cnt_wait计时到19999后状态从等待状态跳转到预充电状态
发送预充电指令后,进行等待,满足2个时钟的TRP时序要求后进行第一次自动刷新操作
发送第一次自动刷新操作指令后,进行等待,满足7个时钟的TRFC时序要求后机型第二次自动刷新操作
因为输出是用的时序逻辑,所以输出会落后条件一个时钟周期
上图:
发送第8次(cnt_ar==8)自动刷新指令且满足TRFC时序要求后跳转到模式寄存器设置状态
发送模式寄存器设置指令后,进行等待,满足3个时钟的TMRD时序要求后跳转到初始化完成状态,同时拉高完成标志init_end,以便其他模块开始进行工作
因为输出是用的时序逻辑,所以输出会落后条件一个时钟周期
modlesim命令窗口打印的信息如下:
可以看到全部满足状态机设置的要求:
对所有bank进行了预充电
进行了8次自动刷新
模式寄存器设置:CL为3个周期;全页突发写(通过终止突发写操作,可以达到突发写任意字节),顺序突发写类型;可设置突发长度。