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

📄 sdram_test_tb.v

📁 SDRAM读写控制的实现与Modelsim仿真
💻 V
字号:
`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 <= 1'b0;
else
	cnt <= cnt + 1'b1;

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 <= STATE[12];  //WAIT_ACK_W_T
	STATE16_reg <= STATE[16];  //LAST_DATA
	STATE8_reg  <= STATE[8];   //IDLE_WR
	STATE19_reg <= STATE[19];  //CLOSE_PAGE_R
	r_enable_2 <= r_enable_1;
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 <= 0;
else if(STATE12_reg)
	w_page <= w_page + 1;
else if(STATE8_reg && (w_page=='d1))// 
	w_page <= 0;

reg	w_ba0;
always @ (posedge clk or negedge rst)
if(!rst)
	w_ba0 <= 0;
else if(STATE8_reg && (w_page=='d1))// 
	w_ba0 <= ~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 <= 0;
	end
else if(STATE[20] & cmdack) begin
	r_ba0 <= ~r_ba0;
	end
	
always @ (posedge clk or negedge rst)
if(!rst) begin
	r_page <= 0;
	end
else if(STATE16_reg) begin
		r_page <= r_page + 1;
	end
else if(STATE8_reg) begin
	r_page <= 0;
	end

wire	[1:0]	r_ba = {1'b0,r_ba0};
//********************************************************************************//
//********************************************************************************//				
//the state machine
always @(posedge clk or negedge rst)
begin
if(!rst) begin
        STATE<=IDLE;
	s_enable<=0;
	r_enable_1<=0;
        RCDCL_CNT<=0;
        Burst_cnt<=0;
	end
else
     case(STATE)
	IDLE:
	if(start_read)
		STATE<=PRECHARGE;
	else
		STATE<=IDLE;
		
	PRECHARGE:
	if(cmdack)
		STATE<=PRECHARGE_ACK;
	else
		STATE<=PRECHARGE;
		
	PRECHARGE_ACK:
		STATE<=LOAD_MR;
		
	LOAD_MR:
	if(cmdack)  
		STATE<=LOAD_MR_ACK;
	else
		STATE<=LOAD_MR;
		
	LOAD_MR_ACK:
		STATE<=LOAD_R2;
		
	LOAD_R2:
	if(cmdack)
 		STATE<=LOAD_R2_ACK;
	else
		STATE<=LOAD_R2;
		
	LOAD_R2_ACK:
		STATE<=LOAD_R1;
	LOAD_R1:
	if(cmdack)
		STATE<=IDLE_WR;
	else
		STATE<=LOAD_R1;

//page write burst
	IDLE_WR: begin                //9
	if(r_req) begin
		STATE<=PAGE_WRITE;
		end
	else if( s_req && (w_ba0 != r_ba0)) begin
		STATE<=PAGE_READ;
		end  
	else
		STATE<=IDLE_WR;
	end
	
	PAGE_WRITE: //10
	if(cmdack) begin
		STATE<=BURST_WRITE; 
		Burst_cnt<=0;
		r_enable_1<=1;
		end
	else
		STATE<=PAGE_WRITE;  
		
	BURST_WRITE: begin
	if(Burst_cnt==(BL-2'd3))
		STATE<=BT_W;
	else
		STATE<=BURST_WRITE;
	Burst_cnt<=Burst_cnt+1;
	
	end  
	
	BT_W:begin         
	if(cmdack)
		STATE<=WAIT_ACK_W_T;
	else
		STATE<=BT_W;
	r_enable_1<=0;
	end

	WAIT_ACK_W_T:begin
	STATE<=CLOSE_PAGE_W;
	end        
	 
//CLOSE CURRENT PAGE                       
	CLOSE_PAGE_W:begin
	if(cmdack)
		STATE<=REFRESH_W;
	else
		STATE<=CLOSE_PAGE_W;
	end
	REFRESH_W: begin
	if(cmdack) begin             
		STATE<=IDLE_WR;
		end
	else
		STATE<=REFRESH_W;
	end
	
//PAGE READ BURST TEST    
	PAGE_READ:begin
		if(cmdack)    
			STATE<=BURST_READ;
		else 
			STATE<=PAGE_READ;
		Burst_cnt<=0;
		RCDCL_CNT<=0;
                end
                
	BURST_READ:begin
	if(Burst_cnt==('d6))
		s_enable <= 1; 
	else if(Burst_cnt==(BL-2'd3))//+RCD+CL
		STATE<=BT;
	else
		STATE<=BURST_READ;
	Burst_cnt<=Burst_cnt+1;
	end
	
	BT:
	if(cmdack)
		STATE<=LAST_DATA;                       
	else
		STATE<=BT;                            
	LAST_DATA:
	STATE<=CLOSE_PAGE_R;

	CLOSE_PAGE_R:begin
	if(cmdack)
		STATE<=REFRESH_R;
	else
		STATE<=CLOSE_PAGE_R;
		
	if(RCDCL_CNT=='d2)
		s_enable<=0;
	else
		RCDCL_CNT<=RCDCL_CNT+1;	
	end
	
	REFRESH_R:begin
	if(cmdack)begin              
		STATE<=IDLE_WR;
		end
	else
		STATE<=REFRESH_R;
	end
	
	default:
	STATE<=IDLE;

	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         

⌨️ 快捷键说明

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