基于FPGA的SDRAM控制器设计(二)----------SDRAM的刷新

SDRAM是基于电容存储的,因此需要不断刷新来保证数据不会丢失。 此文总结SDRAM的刷新模块。

数据手册分析(及时序分析)

基于FPGA的SDRAM控制器设计(二)----------SDRAM的刷新_第1张图片
这是刷新模块的时序图。
这里据视频邓堪文老师讲解,AutoRefresh 只需要进行一次即可。

时间间隔

在这里插入图片描述
在这里插入图片描述

描述

在SDRAM内部有刷新计数器,刷新完一次后,计数器会自动加一 。

SDRAM模块工作有三种,1,刷新2,写,3,读,所以需要引入仲裁机制,自身的工作状态进行决定,后文填坑,仲裁以及读写
这里的刷新请求就是给仲裁模块的信号。具体实现思路和上篇很像。

代码实现

module sdram_aref(
	//system singles
	clk,rst_n,
	//communicate with abfer singles
	ref_en,ref_req,flag_ref_end,
	//others singles
	aref_cmd,sdram_addr,flag_init_end
    );
//
input 				clk				;
input 				rst_n			;
input 				ref_en 			;
input 				flag_init_end	;
output 	reg   		ref_req			;
output  	 		flag_ref_end	;
output  reg [3:0 ]	aref_cmd		;
output 		[11:0]	sdram_addr		;
//
//
//*************************************************\
//define parameter and internal singles
//*************************************************/
localparam DELAY_15US = 740		;
localparam CMD_AREF   = 4'b0001	;	
localparam CMD_NOP	  = 4'b0111	;
localparam CMD_PRE    = 4'b0010 ;
reg 	[3:0] 	cmd_cnt	;
reg 	[9:0] 	ref_cnt	;
reg 			flag_ref;
//*************************************************\
//main code
//*************************************************/
always @ (posedge clk or negedge rst_n)
begin
	if(!rst_n)
		ref_cnt <= 'd0;
	else 
		if(ref_cnt == DELAY_15US)
			ref_cnt <= 'd0;
		else 
			if(flag_init_end == 1'b1)						//初始化结束后,直接进行刷新计数
				ref_cnt <= ref_cnt + 1'b1;										
end
// assign ref_req = (ref_cnt == DELAY_15US) ? 1'b1 : 1'b0 	;	//刷新请求信号在15us计数结束后产生
always @ (posedge clk or negedge rst_n)
begin
	if(!rst_n)
		ref_req <= 1'b0;
	else 
		if(ref_en)
			ref_req <= 1'b0;
		else 	
			if(ref_cnt == DELAY_15US)
				ref_req <= 1'b1; 
end

always @ (posedge clk or negedge rst_n)
begin
	if(!rst_n)
		flag_ref <= 1'b0;
	else 
		if(flag_ref_end)
			flag_ref <= 1'b0;
		else 
			if(ref_en)
				flag_ref <= 1'b1;
			else 
				flag_ref <= flag_ref; 

end

always @ (posedge clk or negedge rst_n)
begin
	if(!rst_n)
		cmd_cnt <= 'b0;
	else 
		if(flag_ref)					//只有在刷新模块工作的时候,命令计数器开始计数
			cmd_cnt <= cmd_cnt + 1'b1;
		else 
			cmd_cnt <= 'd0;
end

always @ (posedge clk or negedge rst_n)
begin
	if(!rst_n)
		aref_cmd <= CMD_NOP;
	else 
		case(cmd_cnt)
			2:	aref_cmd <= CMD_AREF;
			default:aref_cmd <= CMD_NOP;
		endcase
end

assign flag_ref_end = (cmd_cnt == 'd4)	? 	1 	:	0 	;//20 + 63 就是不到80ns
assign sdram_addr = 12'b0100_0000_0000					;

endmodule

你可能感兴趣的:(FPGA逻辑篇)