SDRAM的初始化先引一个图说明一下SDRAM的初始化过程吧,这样来的直观一些:这便是SDRAM在开机时的初始化过程,上电后要有200us的输入稳定期,在这个时间内不可以对SDRAM的接口做任何操作;200us以后就是要对所有L-Bank预充电,再往后给SDRAM8次的刷新命令;最后就是要对SDRAM的模式寄存器进行设置。上面的这些步骤就是SDRAM在上电后的全部初始化过程。在进行完了初始化过程以后就可以正常的对SDRAM进行读写了,当然了,在每隔一段时间后就要对SDRAM进行一次预刷新操作以防止数据丢失。下面就来解析下时序控制模块里的部分关于SDRAM初始化的verilog程序(sdram_ctrl.v)://-------------------------------------------------------------------//上电后200us计时,计时时间到,则done_200us=1//-------------------------------------------------------------------wiredone_200us;//上电后200us输入稳定期结束标志位reg[13:0]cnt_200us;always@(posedgeclkornegedgerst_n)if(!rst_n)cnt_200us=14'd0;elseif(cnt_200us14'd10000)cnt_200us=cnt_200us+1'b1;//计数//200us定时到,则done_200us=1assigndone_200us=(cnt_200us==14'd10000);当200us计时时间结束以后,SDRAM的初始化进入第二步,所有L-Bank预充电状态,如何预充电呢?在这之前我们得先把SDRAM的各个端口的作用搞清楚了。看下图,K4S641632的datasheet中PIN的定义。在我的设计中,吧CKE,CS_n,RAS_n,CAS_n,WE_n这五个信号端口打包作为SDRAM的命令了。如下定义://FPGA与SDRAM硬件接口outputsdram_cke;//SDRAM时钟有效信号outputsdram_cs_n;//SDRAM片选信号outputsdram_ras_n;//SDRAM行地址选通脉冲outputsdram_cas_n;//SDRAM列地址选通脉冲outputsdram_we_n;//SDRAM写允许位reg[4:0]sdram_cmd_r;//SDRAM操作命令assign{sdram_cke,sdram_cs_n,sdram_ras_n,sdram_cas_n,sdram_we_n}=sdram_cmd_r;关于命令部分其实主要是在命令控制模块里赋值的。这里还是回到正题预充电,预充电其实只要给SDRAM的操作命令sdram_cmd_r赋一个相应的命令,只要保持一个时钟周期,然后sdram_cmd_r回到NOP命令,预充电大概需要保持1个时钟周期就行了(根据datasheet里的时间参数)。看看时序图吧:第一根粗黄线是预充电命令,可以看到这时候sdram的cs,cke,ras,cas,we都是和它前一个时钟周期(处于NOP命令)是不同的,只是保持了一个时钟周期,又回到了NOP命令,这样在第二条黄线处就算完成了预充电,往后进行的是预刷新操作。说到这,再补充一下关于SDRAM的时钟问题,SDRAM有一个输入始终引脚sdram_clk,它是SDRAM的工作时钟,而不是FPGA的工作时钟,在我的程序里,sdram_clk=~clk;也就是说它和FPGA的系统时钟是反向的。这样以来,在FPGA时钟的上升沿可以对SDRAM的各个命令端口赋值,然后过了半个时钟周期正好是sdram_clk的上升沿,此时SDRAM锁存相应的数据地址或者命令。反向的时钟如下:预充电完成了就要连续进行八个预刷新,时序如下:从第一根黄线开始到第二根黄线为止,正好是八次的预刷新操作。从图上不难看出预刷新操作需要的等待时间要比预充电长的多,大约需要6个时钟周期(也有的资料说要9个时钟周期,这和系统时钟有关吧,应视具体情况而定)。发送一次预刷新命令,然后回到NOP命令等待完成,前后八次。在往后是模式寄存器设置,看下图:上图直观明了我就不多废话了。和前面不同的是在这一步,不仅要送命令,还要给BA0-BA1以及A0-A11端口送数据,也就是送入设置的信息。这些设置关系到以后正常读写SDRAM的相关时序。模式寄存器设置的时序如下:相应的sdram_ba和sdram_addr都做了赋值,其verilog代码如下:I_MRS:begin//模式寄存器设置,可根据实际需要进行设置sdram_cmd_r=CMD_LMR;sdram_ba_r=2'b00;//操作模式设置sdram_addr_r={2'b00,//操作模式设置1'b0,//操作模式设置(这里设置为A9=0,即突发读/突发写)2'b00,//操作模式设置({A8,A7}=00)3'b011,//CAS潜伏期设置(这里设置为3,{A6,A5,A4}=011)1'b0,//突发传输方式(这里设置为顺序,A3=b0)3'b010//突发长度,(这里设置为4,{A2,A1,A0}=010)};end