`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