⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main_fsm.v

📁 sdram 控制器的verilog 实现
💻 V
字号:
/*------------------------------------------------------
注意点:针对本sdram控制器
对于页模式的读burst_len>=3
对于页模式的写burst_len>=2
--------------------------------------------------------*/
`timescale 1ns/100ps
`include "sdr_par.v"
module main_fsm(
				//input
				clk,
				rst_n,
				read_req,
				write_req,
				burst_len,
				refresh_req,
				init_done,
				//output
				read_ack,
				write_ack,
				refresh_ack,
				r_data_valid,
				w_data_valid,
				c_state
				);
//----------------input and output io declare-----------------------
input 			clk;
input 			rst_n;
input 			read_req;
input 			write_req;
input[8:0]		burst_len;
input			refresh_req;
input			init_done;

//此信号给refresh.v模块
output reg		refresh_ack;
//给user模块
output reg		read_ack;
output reg		write_ack;
output reg		r_data_valid;
output reg		w_data_valid;
//给sig物理层模块
output reg[3:0] c_state;
//----------------test port declare--------------------------------



//----------------parameter declare---------------------------------
parameter tCK	= 20;
parameter tRP  	= 40;			//充电命令发出后,tRP延时后才能发下个命令,手册上给最小20ns
parameter tRFC 	= 80;			//刷新命令发出后,延时tRFC后才能发下个命令,手册上给最小63ns
parameter Tp	= 2;	
//把参数转换成对应的时钟数
parameter NUM_CLK_tRP  = tRP /tCK-1;	//1
parameter NUM_CLK_tRFC = tRFC/tCK-1;    //3
//state machine declare
/*
parameter c_IDLE	=	4'b0000;
parameter c_AR		=	4'b0001;
parameter c_tRFC	=	4'b0010;
parameter c_RW_AR	=	4'b0011;
parameter c_RW_tRFC	=	4'b0100;
parameter c_ACTIVE	=	4'b0101;
parameter c_tRCD	=	4'b0110;
parameter c_READ	=	4'b0111;
parameter c_RD_DATA	=	4'b1000;
parameter c_R_PRE 	=	4'b1001;
parameter c_R_tRP 	=	4'b1010;
parameter c_WRITE	=	4'b1011;
parameter c_WR_DATA	=	4'b1100;
parameter c_W_PRE 	=	4'b1101;
parameter c_W_tRP 	=	4'b1110;
*/

//-------------internal variable declare---------------------------------
reg			en_m_clk;
reg[8:0] 	clk_m_cnt;
reg[8:0]    keep_burst_len;	//用于保存burst_len
//-----------main  code--------------------------------------------------
always@(posedge clk)
	begin
		if(!rst_n)
			begin
				//the signal below is active high
				//init output port
				refresh_ack 	<=#Tp	1'b0;
				read_ack		<=#Tp	1'b0;
				write_ack     	<=#Tp	1'b0;
				r_data_valid	<=#Tp	1'b0;	
				w_data_valid	<=#Tp	1'b0;
				c_state			<=#Tp	`c_IDLE;
				//init reg
				en_m_clk		<=#Tp	1'b0;
				clk_m_cnt		<=#Tp	9'd0;
				keep_burst_len	<=#Tp	9'd0;
			end
		else
			begin
				//for timing delay
				if(en_m_clk)
					clk_m_cnt	<=#Tp	clk_m_cnt+1'b1;
				else
					clk_m_cnt	<=#Tp	9'd0;
				//for state machine handle
				case(c_state)
					`c_IDLE:
						begin
							if(init_done && refresh_req)   		//refersh req
								begin
									c_state		<=#Tp	`c_AR;
									refresh_ack <=#Tp	1'b1;	//valid signal
									en_m_clk	<=#Tp	1'b0;
									clk_m_cnt	<=#Tp	9'd0;
								end
							//read or write req	
							else if(init_done && (read_req|write_req))
								begin
									c_state			<=#Tp	`c_RW_AR;
									//sample the burst_len signal
									keep_burst_len	<=#Tp	burst_len;
								end
						end
					`c_AR:	
						begin
							//refresh_ack值保持一个周期的有效时间
							refresh_ack <=#Tp	1'b0;			//invalid signal
							en_m_clk	<=#Tp	1'b1;			//prepare for delay
							clk_m_cnt	<=#Tp	9'd0;
							c_state		<=#Tp	`c_tRFC; 
						end
					`c_tRFC:
						begin
							if(clk_m_cnt == NUM_CLK_tRFC)		//if end of tRF delay
								begin
									en_m_clk	<=#Tp	1'b0;	//clear
									clk_m_cnt	<=#Tp	9'd0;
									c_state		<=#Tp	`c_IDLE; 
								end
						end
					`c_RW_AR:
						begin
							c_state		<=#Tp	`c_RW_tRFC; 
							en_m_clk	<=#Tp	1'b1;			//prepare for delay
							clk_m_cnt	<=#Tp	9'd0;
						end
					`c_RW_tRFC:
						begin
							if(clk_m_cnt == NUM_CLK_tRFC)		//if end of tRF delay
								begin
									en_m_clk	<=#Tp	1'b0;	//clear
									clk_m_cnt	<=#Tp	9'd0;
									c_state		<=#Tp	`c_ACTIVE; 
								end
						end
					`c_ACTIVE:
						begin
							c_state		<=#Tp	`c_tRCD; 
						end
					`c_tRCD:
						begin
							if(read_req)
								begin
									c_state		<=#Tp	`c_READ;
								end 
							else if(write_req)
								begin
									c_state		<=#Tp	`c_WRITE;
									w_data_valid<=#Tp	1'b1;			//通知user可以改变数据了
								end 
						end
//------------------cl=2-----read control-----------------------------						
					`c_READ:
						begin
							en_m_clk	<=#Tp	1'b1;	//prepare for delay
							clk_m_cnt	<=#Tp	9'd0;	
							c_state		<=#Tp	`c_RD_DATA;													
						end
					`c_RD_DATA:
						begin
							if(clk_m_cnt==9'd1)
								begin
									r_data_valid	<=#Tp	1'b1;
								end
							if( clk_m_cnt==(keep_burst_len-2))	
								begin
									c_state		<=#Tp	`c_R_PRE;
									en_m_clk	<=#Tp	1'b0;	//clear
									clk_m_cnt	<=#Tp	9'd0;
								end
						end
					`c_R_PRE: 
						begin
							c_state		<=#Tp	`c_R_tRP;
							en_m_clk	<=#Tp	1'b1;
							clk_m_cnt	<=#Tp	9'd0;
						end
					`c_R_tRP:
						begin
						    if(clk_m_cnt== 9'd1)
								begin
									r_data_valid	<=#Tp	1'b0;
									read_ack		<=#Tp	1'b1;
								end
							if(clk_m_cnt== (NUM_CLK_tRP+1) )
								begin
									en_m_clk		<=#Tp	1'b0;
									clk_m_cnt		<=#Tp	9'd0;
									read_ack		<=#Tp	1'b0;
									c_state			<=#Tp	`c_IDLE;
								end	
						end
//---------------------------------write control-----------------------------						
					`c_WRITE:
						begin
							c_state		<=#Tp	`c_WR_DATA;
							en_m_clk	<=#Tp	1'b1;			//prepare for delay
							clk_m_cnt	<=#Tp	9'd0;
							
						end
					`c_WR_DATA:
						begin
							if(clk_m_cnt==(keep_burst_len-2))
								begin
									en_m_clk	<=#Tp	1'b0;	//clear
									clk_m_cnt	<=#Tp	9'd0;
									w_data_valid<=#Tp	1'b0;	//invalid	
									c_state		<=#Tp	`c_W_PRE;							
								end
						end
					`c_W_PRE: //----------to terminate the busrt transmit
						begin
							en_m_clk	<=#Tp	1'b1;			//prepare for delay
							clk_m_cnt	<=#Tp	9'd0;
							write_ack   <=#Tp	1'b1;   		//产生写应答信号 
							c_state		<=#Tp	`c_W_tRP;
						end
					`c_W_tRP:
						begin
							write_ack   <=#Tp	1'b0;   		//清除写应答信号
							if(clk_m_cnt==NUM_CLK_tRP)
								begin
									en_m_clk	<=#Tp	1'b0;	//prepare for delay
									clk_m_cnt	<=#Tp	9'd0;
									c_state		<=#Tp	`c_IDLE;
								end
						end
					default:
						begin
							c_state		<=#Tp	`c_IDLE;
						end
				endcase
			end
	end
		
//-----------test  code--------------------------------------------------			
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -