SDRAM读写控制的实现与Modelsim仿真

源代码在线查看: sdram_test_tb.v

软件大小: 2121 K
上传用户: mislrb
关键词: Modelsim SDRAM 读写 控制
下载地址: 免注册下载 普通下载 VIP

相关代码

				`timescale 1ns/1ns
				module sdram_test_tb;
				reg	clk;
				reg	rst;
				reg	start_read;
				initial begin
					clk = 0;
					rst = 0;
					start_read = 0;
					#100 rst = 1;
					#1000 start_read = 1;
					end
				
				always #10 clk = !clk;
				
				reg	[10:0]	cnt;
				
				always @ (posedge clk or negedge start_read)
				if(!start_read)
					cnt 				else
					cnt 				
				wire	r_req = (cnt == 10'd200);	//写sdram申请
				wire	s_req = (cnt == 10'd600);	//读sdram申请
				
				
				
				// State parameters used in MAIN  STATE MACHINE
				parameter 
					IDLE		=21'b0_0000_0000_0000_0000_0001,
					PRECHARGE	=21'b0_0000_0000_0000_0000_0010,
					PRECHARGE_ACK	=21'b0_0000_0000_0000_0000_0100,    
					LOAD_MR		=21'b0_0000_0000_0000_0000_1000,
					LOAD_MR_ACK	=21'b0_0000_0000_0000_0001_0000,
					LOAD_R2		=21'b0_0000_0000_0000_0010_0000,
					LOAD_R2_ACK	=21'b0_0000_0000_0000_0100_0000,
					LOAD_R1		=21'b0_0000_0000_0000_1000_0000,
				                          
					IDLE_WR		=21'b0_0000_0000_0001_0000_0000,    
					PAGE_WRITE	=21'b0_0000_0000_0010_0000_0000,
					BURST_WRITE	=21'b0_0000_0000_0100_0000_0000,
					BT_W		=21'b0_0000_0000_1000_0000_0000,
					WAIT_ACK_W_T	=21'b0_0000_0001_0000_0000_0000,
				                         
					PAGE_READ	=21'b0_0000_0010_0000_0000_0000,
					BURST_READ	=21'b0_0000_0100_0000_0000_0000,
					BT		=21'b0_0000_1000_0000_0000_0000,
					LAST_DATA	=21'b0_0001_0000_0000_0000_0000,
					CLOSE_PAGE_W	=21'b0_0010_0000_0000_0000_0000,
					REFRESH_W       =21'b0_0100_0000_0000_0000_0000,
					CLOSE_PAGE_R    =21'b0_1000_0000_0000_0000_0000,
					REFRESH_R       =21'b1_0000_0000_0000_0000_0000;
					
				parameter RCD='D3,CL='D3,BL='d223;//BL控制每行sdram中有效字数
				
				reg	s_enable,r_enable_1,r_enable_2;
				reg	[20:0]	STATE;
				reg	[11:0]	w_page;
				reg	[7:0]	Burst_cnt;
				reg	[1:0]	RCDCL_CNT;
				
				
				wire	r_enable = r_enable_1|r_enable_2;	//与写入sdram中的有效数据对齐
				
				
				 
				wire	[15:0] datain = r_enable ? {5'd0,cnt}:16'dx; //需要写入到sdram中的数据
				wire	[15:0]	dataout;				//从sdram中读出的数据
				reg	[2:0]	cmd;
				reg	[21:0]	addr;
				
				reg	STATE12_reg,STATE16_reg,STATE8_reg,STATE19_reg;
				
				always @ (posedge clk) begin
					STATE12_reg 					STATE16_reg 					STATE8_reg  					STATE19_reg 					r_enable_2 				end
				
				parameter	NOP  ='b000,
						READA     ='b001,
						WRITEA    ='b010,
						ARF       ='b011,
						PRECHRG   ='b100,
						LOAD_MODE ='b101,
						LOAD_REG1 ='b110,
						LOAD_REG2 ='b111;
						
				//generate the cmd to the sdr_sdram_controller
				always @ (STATE)
				case(STATE)    
					PRECHARGE:	cmd = PRECHRG;
					LOAD_MR:	cmd = LOAD_MODE;
					LOAD_R2:	cmd = LOAD_REG2;
					LOAD_R1:	cmd = LOAD_REG1;
					PAGE_WRITE:	cmd = WRITEA;
					BT_W:		cmd = PRECHRG;
					CLOSE_PAGE_W:	cmd = PRECHRG;
					CLOSE_PAGE_R:	cmd = PRECHRG;
					PAGE_READ:	cmd = READA;
					BT:		cmd = PRECHRG;
					REFRESH_W:	cmd = ARF;
					REFRESH_R:	cmd = ARF;
					default:	cmd = NOP;
				endcase
				//*****************************************************************************//
				//*****************************************************************************//
				always @ (posedge clk or negedge rst)
				if(!rst)
					w_page 				else if(STATE12_reg)
					w_page 				else if(STATE8_reg && (w_page=='d1))// 
					w_page 				
				reg	w_ba0;
				always @ (posedge clk or negedge rst)
				if(!rst)
					w_ba0 				else if(STATE8_reg && (w_page=='d1))// 
					w_ba0 					
				wire	[1:0]	w_ba = {1'b0,w_ba0};
				//****************************************************************************//
				//****************************************************************************//
				wire	cmdack;
				reg	[11:0]	r_page;
				reg	r_ba0;
				always @ (posedge clk or negedge rst)
				if(!rst) begin
					r_ba0 					end
				else if(STATE[20] & cmdack) begin
					r_ba0 					end
					
				always @ (posedge clk or negedge rst)
				if(!rst) begin
					r_page 					end
				else if(STATE16_reg) begin
						r_page 					end
				else if(STATE8_reg) begin
					r_page 					end
				
				wire	[1:0]	r_ba = {1'b0,r_ba0};
				//********************************************************************************//
				//********************************************************************************//				
				//the state machine
				always @(posedge clk or negedge rst)
				begin
				if(!rst) begin
				        STATE					s_enable					r_enable_1				        RCDCL_CNT				        Burst_cnt					end
				else
				     case(STATE)
					IDLE:
					if(start_read)
						STATE					else
						STATE						
					PRECHARGE:
					if(cmdack)
						STATE					else
						STATE						
					PRECHARGE_ACK:
						STATE						
					LOAD_MR:
					if(cmdack)  
						STATE					else
						STATE						
					LOAD_MR_ACK:
						STATE						
					LOAD_R2:
					if(cmdack)
				 		STATE					else
						STATE						
					LOAD_R2_ACK:
						STATE					LOAD_R1:
					if(cmdack)
						STATE					else
						STATE				
				//page write burst
					IDLE_WR: begin                //9
					if(r_req) begin
						STATE						end
					else if( s_req && (w_ba0 != r_ba0)) begin
						STATE						end  
					else
						STATE					end
					
					PAGE_WRITE: //10
					if(cmdack) begin
						STATE						Burst_cnt						r_enable_1						end
					else
						STATE						
					BURST_WRITE: begin
					if(Burst_cnt==(BL-2'd3))
						STATE					else
						STATE					Burst_cnt					
					end  
					
					BT_W:begin         
					if(cmdack)
						STATE					else
						STATE					r_enable_1					end
				
					WAIT_ACK_W_T:begin
					STATE					end        
					 
				//CLOSE CURRENT PAGE                       
					CLOSE_PAGE_W:begin
					if(cmdack)
						STATE					else
						STATE					end
					REFRESH_W: begin
					if(cmdack) begin             
						STATE						end
					else
						STATE					end
					
				//PAGE READ BURST TEST    
					PAGE_READ:begin
						if(cmdack)    
							STATE						else 
							STATE						Burst_cnt						RCDCL_CNT				                end
				                
					BURST_READ:begin
					if(Burst_cnt==('d6))
						s_enable 					else if(Burst_cnt==(BL-2'd3))//+RCD+CL
						STATE					else
						STATE					Burst_cnt					end
					
					BT:
					if(cmdack)
						STATE					else
						STATE					LAST_DATA:
					STATE				
					CLOSE_PAGE_R:begin
					if(cmdack)
						STATE					else
						STATE						
					if(RCDCL_CNT=='d2)
						s_enable					else
						RCDCL_CNT					end
					
					REFRESH_R:begin
					if(cmdack)begin              
						STATE						end
					else
						STATE					end
					
					default:
					STATE				
					endcase
				end
				
				//generate the addr to the sdr_sdram_controller
				always @ (STATE or w_page or r_page or r_ba or w_ba)
				case(STATE)
					PRECHARGE:	addr = 'h1f0000;
					LOAD_MR:	addr = 'h37;
					LOAD_R2:	addr = 'h5F6;
					LOAD_R1:	addr = 'h12F; //'h10f;
					PAGE_WRITE:	addr = {w_ba,w_page,8'b0};//PAGE_WRITE
					PAGE_READ:	addr = {r_ba,r_page,8'b0};
					BT_W:		addr = {w_ba,20'b0};    
					CLOSE_PAGE_W:	addr = {w_ba,20'b0};
					CLOSE_PAGE_R:	addr = {r_ba,20'b0};
					BT:		addr = {r_ba,20'b0};
					default:	addr = 'h0;
				endcase
				
				wire	[11:0]	sa;
				wire	[1:0]	ba;
				wire	[15:0]	dq;
				
				sdr_sdram sdr_sdram0(
				        .CLK(clk),
				        .RESET_N(rst),
				        .ADDR(addr),
				        .CMD(cmd),
				        .CMDACK(cmdack),
				        .DATAIN(datain),
				        .DATAOUT(dataout),
				        .SA(sa),
				        .BA(ba),
				        .CS_N(cs_n),
				        .CKE(cke),
				        .RAS_N(ras_n),
				        .CAS_N(cas_n),
				        .WE_N(we_n),
				        .DQ(dq)
				        );
				//mt48lc8m16a2 (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm);       
				mt48lc8m16a2 sdram2(
				         .Dq    (dq)   , 
				         .Addr  (sa) , 
				         .Ba    (ba)   , 
				         .Clk   (clk)  , 
				         .Cke   (cke)  , 
				         .Cs_n  (cs_n) , 
				         .Ras_n (ras_n), 
				         .Cas_n (cas_n), 
				         .We_n  (we_n) , 
				         .Dqm   (2'b0)
				         );	
				endmodule         
							

相关资源