sdram读写

源代码在线查看: sdram_ctrl.v

软件大小: 2845 K
上传用户: Whibrafy
关键词: sdram 读写
下载地址: 免注册下载 普通下载 VIP

相关代码

				`timescale 1ns / 1ps
				////////////////////////////////////////////////////////////////////////////////
				// Company		: 
				// Engineer		: 
				// Create Date	: 
				// Design Name	: 
				// Module Name	: sdram_top
				// Project Name	: 
				// Target Device: Cyclone EP1C3T144C8 
				// Tool versions: Quartus II 8.1
				// Description	: SDRAM状态控制模块
				//							SDRAM初始化以及定时刷新、读写控制
				//				
				// Revision		: V1.0
				// Additional Comments	:  
				// 
				////////////////////////////////////////////////////////////////////////////////
				module sdram_ctrl(
								clk,rst_n,
								/*sdram_udqm,sdram_ldqm,*/
								sdwr_byte,sdrd_byte,sys_r_wn,
								sys_en,sdram_wr_ack,sdram_rd_ack,
								sdram_busy,sys_dout_rdy,
								init_state,work_state,cnt_clk
							);
					//系统信号接口
				input clk;				//系统时钟,50MHz
				input rst_n;			//复位信号,低电平有效
					// SDRAM硬件接口
				//output sdram_udqm;	// SDRAM高字节屏蔽
				//output sdram_ldqm;	// SDRAM低字节屏蔽
					// SDRAM封装接口
				//input sdram_wr_req;			//系统写SDRAM请求信号
				//input sdram_rd_req;			//系统读SDRAM请求信号
				input sys_en;
				input sys_r_wn;
				output sdram_wr_ack;		//系统写SDRAM响应信号,作为wrFIFO的输出有效信号
				output sdram_rd_ack;		//系统读SDRAM响应信号	
				//output sdram_ref_w;		// SDRAM自刷新请求信号
				output sdram_busy;		// SDRAM忙标志位,高表示忙
				output sys_dout_rdy;	// SDRAM数据输出完成标志
				input[8:0] sdwr_byte;
				input[8:0] sdrd_byte;
					// SDRAM内部接口
				output[4:0] init_state;	// SDRAM初始化寄存器
				output[3:0] work_state;	// SDRAM工作状态寄存器
				output[8:0] cnt_clk;	//时钟计数
				
				
				wire done_200us;		//上电后200us输入稳定期结束标志位
				wire sdram_init_done;	// SDRAM初始化完成标志,高表示完成
				wire sdram_busy;		// SDRAM忙标志,高表示SDRAM处于工作中
				reg sdram_ref_req;		// SDRAM自刷新请求信号
				wire sdram_ref_ack;		// SDRAM自刷新请求应答信号
				
				`include "sdr_para.v"		// 包含SDRAM参数定义模块
				
					// SDRAM时序延时参数
				parameter		TRP_CLK		= 9'd4,//1,	//TRP=18ns预充电有效周期
								TRFC_CLK	= 9'd6,//3,	//TRC=60ns自动预刷新周期
								TMRD_CLK	= 9'd6,//2,	//模式寄存器设置等待时钟周期
								TRCD_CLK	= 9'd2,//1,	//TRCD=18ns行选通周期
								TCL_CLK		= 9'd3,		//潜伏期TCL_CLK=3个CLK,在初始化模式寄存器中可设置
								TREAD_CLK	= 9'd256,	//突发读数据周期256CLK
								TWRITE_CLK	= 9'd256,  	//突发写数据256CLK
								TDAL_CLK	= 9'd3;	//写入等待
				
				//------------------------------------------------------------------------------
				//assign sdram_udqm = 1'b0;	// SDRAM数据高字节有效
				//assign sdram_ldqm = 1'b0;	// SDRAM数据低字节有效
				
				//------------------------------------------------------------------------------
				//上电后200us计时,计时时间到,则done_200us=1          50MHZ
				//------------------------------------------------------------------------------
				reg[14:0] cnt_200us; 
				always @ (posedge clk or negedge rst_n) 
					if(!rst_n) cnt_200us 					else if(cnt_200us < 15'd20_000) cnt_200us 				
				assign done_200us = (cnt_200us == 15'd20_000);	//条件满足则done_200us=1
				
				//------------------------------------------------------------------------------
				//SDRAM的初始化操作状态机
				//------------------------------------------------------------------------------
				reg[4:0] init_state_r;	// SDRAM初始化状态
				
				always @ (posedge clk or negedge rst_n)
					if(!rst_n) init_state_r 					else //初始化阶段
						case (init_state_r)
								`I_NOP: 	init_state_r 								`I_PRE: 	init_state_r 								`I_TRP: 	init_state_r 								`I_AR1: 	init_state_r 								`I_TRF1:	init_state_r 								`I_AR2: 	init_state_r 								`I_TRF2:	init_state_r 								`I_AR3: 	init_state_r 								`I_TRF3:	init_state_r 								`I_AR4: 	init_state_r 								`I_TRF4:	init_state_r 								`I_AR5: 	init_state_r 								`I_TRF5:	init_state_r 								`I_AR6: 	init_state_r 								`I_TRF6:	init_state_r 								`I_AR7: 	init_state_r 								`I_TRF7: 	init_state_r 								`I_AR8: 	init_state_r 								`I_TRF8:	init_state_r 								`I_MRS:		init_state_r 								`I_TMRD:	init_state_r 								`I_DONE:	init_state_r 								default: init_state_r 								endcase
				
				
				assign init_state = init_state_r;
				assign sdram_init_done = (init_state_r == `I_DONE);		// SDRAM初始化完成标志
				//------------------------------------------------------------------------------
				//15us计时,每60ms全部4096行存储区进行一次自刷新
				// ( 存储体中电容的数据有效保存期上限是64ms )
				//------------------------------------------------------------------------------	 
				reg[10:0] cnt_15us;	//计数寄存器
				
				always @ (posedge clk or negedge rst_n)
					if(!rst_n) cnt_15us 					else if(cnt_15us < 11'd1499) cnt_15us 					else cnt_15us 				
				always @ (posedge clk or negedge rst_n)
					if(!rst_n) sdram_ref_req 					else if(cnt_15us == 11'd1498) sdram_ref_req 					else if(sdram_ref_ack) sdram_ref_req 				
				//------------------------------------------------------------------------------
				//SDRAM的读写以及自刷新操作状态机
				//------------------------------------------------------------------------------
				reg[3:0] work_state_r;	// SDRAM读写状态
				
				always @ (posedge clk or negedge rst_n) begin
					if(!rst_n) work_state_r 					else 
						case (work_state_r)
							//SDRAM空闲,初始化完成并且产生自刷新请求
				 			`W_IDLE:	if(sdram_ref_req && sdram_init_done && !sdram_busy) 
												work_state_r 										else if(sys_en & sdram_init_done) 
											work_state_r 										else 	work_state_r 				
										//行有效状态  判断TRCD=18ns行选通延时是否结束
							`W_ACTIVE: 	if(TRCD_CLK == 0) //时间到行有效
											 if(sys_r_wn) work_state_r 											 else work_state_r 										else work_state_r 										//行有效等待
							`W_TRCD:	 if(`end_trcd)
										 	 if(sys_r_wn) work_state_r 										 	 else work_state_r 										else work_state_r 										// SDRAM读数据状态
							`W_READ:	work_state_r 							`W_CL:		work_state_r 							`W_RD:		work_state_r 							`W_RWAIT:	work_state_r 										// SDRAM写数据状态
							`W_WRITE:	work_state_r 							`W_WD:		work_state_r 							`W_TDAL:		work_state_r 										// SDRAM自动刷新状态
							`W_AR:		work_state_r 							`W_TRFC:	work_state_r 							
							`W_RBST:	work_state_r 							`W_WBST:	work_state_r 							
							default: 	work_state_r 							endcase
				end
				
				assign work_state = work_state_r;		// SDRAM工作状态寄存器
				assign sdram_busy = (sdram_init_done && work_state_r == `W_IDLE) ? 1'b0:1'b1;	// SDRAM忙标志位
				assign sdram_ref_ack = (work_state_r == `W_AR);		// SDRAM自刷新应答信号
				
				assign sdram_wr_ack = ((work_state == `W_TRCD) & ~sys_r_wn) | (work_state == `W_WRITE) | 
										((work_state == `W_WD) & (cnt_clk_r < sdwr_byte-2'd2));		//写SDRAM响应信号,作为wrFIFO的输出有效信号??
				assign sdram_rd_ack = (work_state_r == `W_RD) & (cnt_clk_r > 9'd1) & (cnt_clk_r < sdrd_byte+2'd2);		//读SDRAM响应信号
				assign sys_dout_rdy = (work_state_r == `W_RD && `end_tread);		// SDRAM数据输出完成标志
				//------------------------------------------------------------------------------
				//产生SDRAM时序操作的延时
				//------------------------------------------------------------------------------
				reg[8:0] cnt_clk_r;	//时钟计数
				reg cnt_rst_n;		//时钟计数复位信号	
				
				always @ (posedge clk or negedge rst_n) 
					if(!rst_n) cnt_clk_r 					else if(!cnt_rst_n) cnt_clk_r 					else cnt_clk_r 					
				assign cnt_clk = cnt_clk_r;			//计数寄存器引出,内部`define中使用 
				
					//计数器控制逻辑
				always @ (*) begin
					case (init_state_r)
					    	`I_NOP:	cnt_rst_n 					   		`I_PRE:	cnt_rst_n 					   		`I_TRP:	cnt_rst_n 					    	`I_AR1,`I_AR2,`I_AR3,`I_AR4,`I_AR5,`I_AR6,`I_AR7,`I_AR8:
					         		cnt_rst_n 					    	`I_TRF1,`I_TRF2,`I_TRF3,`I_TRF4,`I_TRF5,`I_TRF6,`I_TRF7,`I_TRF8:
					         		cnt_rst_n 							`I_MRS:	cnt_rst_n 							`I_TMRD:	cnt_rst_n 						   	`I_DONE:
					      		case (work_state_r)
										`W_IDLE:	cnt_rst_n 										`W_ACTIVE: 	cnt_rst_n 										`W_TRCD:	cnt_rst_n 										`W_CL:		cnt_rst_n 										`W_RD:		cnt_rst_n 										`W_RWAIT:	cnt_rst_n 										`W_WD:		cnt_rst_n 										`W_TDAL:	cnt_rst_n 										`W_TRFC:	cnt_rst_n 									default: cnt_rst_n 						         	endcase
						default: cnt_rst_n 						endcase
				end
				
				endmodule
							

相关资源