您当前的位置: 首页 > 

刘颜儿

暂无认证

  • 6浏览

    0关注

    99博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

01-SDRAM:初始化模块的代码

刘颜儿 发布时间:2022-07-28 22:52:22 ,浏览量:6

SDRAM初始化模块

使用野火的波形图编程 首先明确各个信号之间的依赖关系

  1. state: 最后来考虑,先把他需要的信号准备好
  2. cnt_200us: 需要根据数据手册给的参数设定,这里等待200us,因此需要一个200us的计数器,这个计数器只完成一个使命,上电计数,计满200us就不管后面的事
  3. wait_end: 计满200us后要给出一个计满信号 (依赖 cnt_200us)
  4. cnt_cmd: 计数器,用来给3个等待时间计数 (依赖 cnt_cmd_reset)
  5. cnt_cmd_reset:上一个计数器的清零信号 (依赖计满信号:trp_end、trfc_end、tmrd_end)
  6. trp_end、trfc_end、tmrd_end: 自家延时结束的信号(依赖 状态)
  7. cnt_ref: 自动刷新的次数,至少需要2次自动刷新(依赖状态 INIT_AR)
//SDRAM初始化模块
// 使用野火的波形图编程
// 首先明确各个信号之间的依赖关系
// 1. state:		最后来考虑,先把他需要的信号准备好
// 2. cnt_200us:	需要根据数据手册给的参数设定,这里等待200us
//					因此需要一个200us的计数器,这个计数器只完成一个使命,上电计数,计满200us就不管后面的事
// 3. wait_end:		计满200us后要给出一个计满信号	 (依赖 cnt_200us)
// 4. cnt_cmd:		计数器,用来给3个等待时间计数	 (依赖 cnt_cmd_reset)
// 5. cnt_cmd_reset:上一个计数器的清零信号			 (依赖计满信号:trp_end、trfc_end、tmrd_end)
// 6. trp_end、trfc_end、tmrd_end: 自家延时结束的信号(依赖 状态)
// 7. cnt_ref:		自动刷新的次数,至少需要2次自动刷新(依赖状态 INIT_AR) 
module sdram_initial(
	input 				    clk,//100M时钟信号
	input 				    rst_n,
	
	output reg 	[3:0]		init_cmd,//SDRAM命令,组成{CS#,RAS#,CAS#,WE#}
	output reg 	[1:0] 		init_bank,//BANK地址,共4个BANK
	output reg 	[12:0]		init_addr,//SDRAM地址总线
	output      			init_end//初始化完成信号,初始化完成后拉高,其他时间保持低电平
);

	//命令指令参数				
	localparam 	PRECHARGE = 4'b0010 , 			//预充电指令
				AT_REF    = 4'b0001 , 			//自动刷新指令
				NOP       = 4'b0111 , 			//空操作指令
				MREG_SET  = 4'b0000 ; 			//模式寄存器设置指令

	// 状态参数
	parameter INIT_IDLE = 8'b0000_0001;
	parameter INIT_PRE  = 8'b0000_0010;//预充电
	parameter INIT_TRP  = 8'b0000_0100;//等待tRP
	parameter INIT_AR   = 8'b0000_1000;//自动刷新
	parameter INIT_TRFC = 8'b0001_0000;//等待tRFC
	parameter INIT_MRS  = 8'b0010_0000;//配置模式寄存器
	parameter INIT_TMRD = 8'b0100_0000;//等待tMRD
	parameter INIT_END  = 8'b1000_0000;
	// 计数器最大参数
	parameter CNT_200 = 8'd20_000;//一个周期10ns,200us要用20_000个时钟周期
	
	//最大刷新次数
	parameter MAX_REF = 4'd8;
	//等待时间参数定义	
	localparam	TRP  = 3'd2			,			//发送预充电指令后进行下一个操作需要等待的时间
				TRFC = 3'd7			,			//发送自动刷新指令后进行下一个操作需要等待的时间
				TMRD = 3'd3			;			//发送设置模式寄存器指令后进行下一个操作需要等待的时间
		
	reg [7:0] state;
	reg [7:0] next_state;
	reg [7:0] cnt_200us;//芯片上电后需要等待 至少100us 的时间(在数据手册Figur18左下角)
	reg [3:0] cnt_cmd;	//计数:2、3、7
	reg [3:0] cnt_ref;	//自动刷新8次
	
	//这些信号要提前准备好,要比状态变化提前一个时钟周期
	wire      wait_end;	
	wire      cnt_cmd_reset;
	wire  	  trp_end;
	wire  	  trfc_end;
	wire  	  tmrd_end;	
	
	assign wait_end 	  =  (cnt_200us == CNT_200 - 1)? 1'd1: 1'd0;
	assign trp_end		  =  ((state == INIT_TRP)  && (cnt_cmd == TRP  - 1)) ? 1'd1:1'd0;
	assign trfc_end		  =  ((state == INIT_TRFC) && (cnt_cmd == TRFC - 1)) ? 1'd1:1'd0;
	assign tmrd_end		  =  ((state == INIT_TMRD) && (cnt_cmd == TMRD - 1)) ? 1'd1:1'd0;
	assign cnt_cmd_reset  =  ((state == INIT_IDLE) || (state == INIT_END) || (trp_end) || (trfc_end) || (tmrd_end))?1'd1:1'd0;
	
	assign init_end = (state == INIT_END)? 1'd1 : 1'd0;
	// 200us计数器
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n )begin
			cnt_200us             
关注
打赏
1659364566
查看更多评论
0.0379s