Sdram(三)

SDRAM初始化

在这里插入图片描述

SDRAM 初始化参考流程如下:
(1) 对 SDRAM 上电,加载稳定时钟信号, CKE 设置为高电平;
(2) 等待 T=100us 的时间,此过程中操作命令保持为空操作命令;
(3) 100us 等待结束后,写入预充电命令, A10 设置为高电平,对所有 L-Bank 进
行预充电;

(4) 预充电指令写入后,等待 tRP时间,此过程中操作命令保持为空操作命令;
(5) tRP等待时间结束后,写入自动刷新命令;
(6) 自动刷新命令写入后,等待 tRC时间,此过程中操作命令保持为空操作命令;
(7) tRC等待时间结束后,再次写入自动刷新命令;
(8) 自动刷新命令写入后,等待 tRC时间,此过程中操作命令保持为空操作命令;
(9) tRC 等待时间结束后,写入模式寄存器配置指令,地址总线 A0-A11 参数不同
辅助模式寄存器不同模式的设置;
(10) 模式寄存器配置指令写入后,等待 tMRD 时间,此过程中操作命令保持为空操
作命令;
(11) tMRD等待时间结束后, SDRAM 初始化完成。
初始化过程中,至少进行两次自动刷新,也可适当增加刷新次数

 module sdram_init
 (
 input wire sys_clk , //系统时钟,频率 100MHz
 input wire sys_rst_n , //复位信号,低电平有效

 output reg [3:0] init_cmd , //初始化阶段写入 sdram 的指令(CSN,RAS,CAS,WE)
 output reg [1:0] init_ba , //初始化阶段 Bank 地址
 output reg [12:0] init_addr , //初始化阶段地址数据,辅助预充电和配置模式寄存器操作,A12-A0
 output wire init_end //初始化结束信号
 );
 
//SDRAM 初始化用到的控制信号命令
 parameter P_CHARGE = 4'b0010 , //预充电指令
           AUTO_REF = 4'b0001 , //自动刷新指令
           NOP = 4'b0111 , //空操作指令
           M_REG_SET = 4'b0000 ; //模式寄存器设置指令
 
 
 
 //状态机状态定义
 parameter INIT_IDLE = 3'b000 , //初始状态
           INIT_PRE = 3'b001 , //预充电状态
           INIT_TRP = 3'b011 , //预充电等待 tRP
           INIT_AR = 3'b010 , //自动刷新
           INIT_TRF = 3'b1`00 , //自动刷新等待 tRC
           INIT_MRS = 3'b101 , //模式寄存器设置
		   INIT_TMRD = 3'b111 , //模式寄存器设置等待 tMRD
           INIT_END = 3'b110 ; //初始化完成
 
 //状态结束标志符
reg trp_end;//预充电等待结束标识符
reg trc_end;//自动刷新等待结束标识符
reg tmrd_end;//模式寄存器设置等待结束标识符

//状态时钟周期计数值
parameter TRP_CLK = 3'd2 , //预充电等待周期,20ns
          TRC_CLK = 3'd7 , //自动刷新等待,70ns
          TMRD_CLK = 3'd3 ; //模式寄存器设置等待周期,30ns



 //cnt_200us:SDRAM 上电后 200us 稳定期计数器
 
 parameter T_POWER = 15'd20_000 ; //上电后等待时钟数(200us)
 reg [14:0]cnt_200us;
 wire wait_end;
 
 always@(posedge sys_clk or negedge sys_rst_n)
   if(sys_rst_n == 1'b0)
     cnt_200us <= 15'd0;
   else if(cnt_200us == T_POWER)
     cnt_200us <= T_POWER;
 else
     cnt_200us <= cnt_200us + 1'b1;

 //wait_end:上电后 200us 等待结束标志
 assign wait_end = (cnt_200us == (T_POWER - 1'b1)) ? 1'b1 : 1'b0;
 
 
 //cnt_clk:时钟周期计数,记录初始化各状态等待时间
 
 reg[2:0]cnt_clk;
 
 always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
       cnt_clk <= 3'd0;
    else if(cnt_clk_rst == 1'b1)
       cnt_clk <= 3'd0;
    else
       cnt_clk <= cnt_clk + 1'b1;
	



	   
//cnt_init_aref:初始化过程自动刷新次数计数器

reg [3:0]cnt_init_aref;//为什么是4位的?

 always@(posedge sys_clk or negedge sys_rst_n)
   if(sys_rst_n == 1'b0)
      cnt_init_aref <= 4'd0;
   else if(init_state == INIT_IDLE)
      cnt_init_aref <= 4'd0;
   else if(init_state == INIT_AR)   //到自动刷新状态加1
      cnt_init_aref <= cnt_init_aref + 1'b1;
   else
      cnt_init_aref <= cnt_init_aref;
	  
	  
//trp_end,trc_end,tmrd_end:等待结束标志
assign trp_end = ((init_state == INIT_TRP )&& (cnt_clk == TRP_CLK )) ? 1'b1 : 1'b0;
assign trc_end = ((init_state == INIT_TRF )&& (cnt_clk == TRC_CLK )) ? 1'b1 : 1'b0;	  
assign tmrd_end = ((init_state == INIT_TMRD)&& (cnt_clk == TMRD_CLK)) ? 1'b1 : 1'b0;	  
	  
//SDRAM 的初始化状态机
reg init_state;

 always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
      init_state <= INIT_IDLE;
    else
    case(init_state)
    INIT_IDLE: //系统上电后,在初始状态等待 200us 跳转到预充电状态
       if(wait_end == 1'b1)
         init_state <= INIT_PRE;
       else
         init_state <= init_state;
    INIT_PRE: //预充电状态,直接跳转到预充电等待状态
       init_state <= INIT_TRP;
    INIT_TRP: //预充电等待状态,等待结束,跳转到自动刷新状态
       if(trp_end == 1'b1)
         init_state <= INIT_AR;
       else
         init_state <= init_state;
    INIT_AR : //自动刷新状态,直接跳转到自动刷新等待状态
         init_state <= INIT_TRF;
    INIT_TRF: //自动刷新等待状态,等待结束,自动跳转到模式寄存器设置状态
       if(trc_end == 1'b1)
         if(cnt_init_aref == 4'd8)//刷新8次
            init_state <= INIT_MRS;
          else
            init_state <= INIT_AR;
       else
         init_state <= init_state;
    INIT_MRS: //模式寄存器设置状态,直接跳转到模式寄存器设置等待状态
      init_state <= INIT_TMRD;
    INIT_TMRD: //模式寄存器设置等待状态,等待结束,跳到初始化完成状态
      if(tmrd_end == 1'b1)
         init_state <= INIT_END;
      else
         init_state <= init_state;
    INIT_END: //初始化完成状态,保持此状态
         init_state <= INIT_END;
   default: init_state <= INIT_IDLE;
   endcase
   
  //cnt_clk_rst:时钟周期计数复位标志
reg cnt_clk_rst; 
   always@(*)
  begin
  case (init_state)
  INIT_IDLE: cnt_clk_rst <= 1'b1; //时钟周期计数复位信号
  INIT_TRP: cnt_clk_rst <= (trp_end == 1'b1) ? 1'b1 : 1'b0;//等待结束标志有效,计数器清零
  INIT_TRF: cnt_clk_rst <= (trc_end == 1'b1) ? 1'b1 : 1'b0;//等待结束标志有效,计数器清零
  INIT_TMRD: cnt_clk_rst <= (tmrd_end == 1'b1) ? 1'b1 : 1'b0;//等待结束标志有效,计数器清零
  INIT_END: cnt_clk_rst <= 1'b1; //初始化完成,计数器清零
  default: cnt_clk_rst <= 1'b0;
  endcase
end
	
   
   
   //SDRAM 操作指令控制
 always@(posedge sys_clk or negedge sys_rst_n)
   if(sys_rst_n == 1'b0)
    begin
     init_cmd <= NOP;
     init_ba <= 2'b11;
     init_addr <= 13'h1fff;
    end
   else
    case(init_state)
      INIT_IDLE,INIT_TRP,INIT_TRF,INIT_TMRD: //执行空操作指令
          begin
            init_cmd <= NOP;
            init_ba <= 2'b11;
            init_addr <= 13'h1fff;
          end
      INIT_PRE: //预充电指令
          begin
            init_cmd <= P_CHARGE;
            init_ba <= 2'b11;
            init_addr <= 13'h1fff;
          end
      INIT_AR: //自动刷新指令
          begin
            init_cmd <= AUTO_REF;
            init_ba <= 2'b11;
            init_addr <= 13'h1fff;
          end
      INIT_MRS: //模式寄存器设置指令
          begin
            init_cmd <= M_REG_SET;
            init_ba <= 2'b00;
            init_addr <=
          {       //地址辅助配置模式寄存器,参数不同,配置的模式不同
            3'b000,//A12-A10:预留
            1'b0, //A9=0:读写方式,0:突发读&突发写,1:突发读&单写
            2'b00, //{A8,A7}=00:标准模式,默认
            3'b011,//{A6,A5,A4}=011:CAS 潜伏期,010:2,011:3,其他:保留
            1'b0, //A3=0:突发传输方式,0:顺序,1:隔行
            3'b111 //{A2,A1,A0}=111:突发长度,000:单字节,001:2 字节,010:4 字节,011:8 字节,111:整页,其他:保留
          };
           end
      INIT_END: //SDRAM 初始化完成
           begin
            init_cmd <= NOP;
            init_ba <= 2'b11;
            init_addr <= 13'h1fff;
           end
      default:
           begin
            init_cmd <= NOP;
            init_ba <= 2'b11;
            init_addr <= 13'h1fff;
           end
    endcase
endmodule
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值