首页 > 代码库 > SDRAM总结

SDRAM总结

使用的流程

技术分享

W9825G6JH winbond sdram 4M words X 4banks X 16bits=.

Accesses to the SDRAM are burst oriented.

Up to 200MHz

CAS Latency 2 and 3

Burst Length 1,2,4,9 and Full page

BUrst Read, Single Writes Mode

8K Refresh Cycles/64mS

技术分享

1 After power up, an initial pause of 200uS is required followed by a precharge of all banks using the precharge commmand.DQM and CKE held high during the pause.

2 Once all banks have been precharged ,the Mode Register Set Command must be issued to initialize the Mode Register.

All banks must be in a precharged state and CKE must be high at least one cycle before the Mode Register Set Command can be issued. ()A delay equals to 技术分享 must be waited when the next command can be issued.

3 An Additional eight Auto Refresh cycles are also requred before or after programming the Mode Register .

4 Bank Active Command

before any read or write command

技术分享

5 Read and Write Access Modes

 

技术分享

技术分享

6 Burst Read Command

技术分享

7 Burst Write Command

技术分享

8 Auto-precharge Command

9 Precharge Command

技术分享

10 Self Refresh Command

技术分享

11 NOP

技术分享

技术分享

 

技术分享

技术分享

  1 `timescale 1ns/1ps  2   3 ////////////////////////////////////////////////////////////////////////////////  4 // Company        :   5 // Engineer        : Yang Li yangli0534@gmail.com  6 // Create Date    : 2015.01.20  7 // Design Name    :   8 // Module Name    : sdram  9 // Project Name    :  10 // Target Device:  Spartan 6 11 // Tool versions:  ISE 14.7 12 // Description    : SDRAM control 13 //    read or write one word a time                          14 //    the sdram is WINBOND W9825G6JH             15 // Revision        : V1.0 created 16 // Additional Comments    :   17 //  18 //////////////////////////////////////////////////////////////////////////////// 19 module sdram( 20     input          clk_i,         //clock 100M , 21     input          rst_n_i,       // reset ,active low 22      23      24     input          wr_req_i,      // write request 25     input          rd_req_i,      // read request 26     output         wr_ack_o,      //write ack 27     output         rd_ack_o,      //read ack 28      29     input   [23:0] wr_addr_i,    // address to write 30     input   [15:0] wr_data_i,    //data to write 31      32     input   [23:0] rd_addr_i,    // read address 33     output  [15:0] rd_data_o,   //  read data 34     output         rd_data_valid_o,// data output valid 35     output         busy_sdram_o,  // sdram is busy , unable to be operated 36  37    // SDRAM interface 38     output [12:0] SDRAM_ADDR,  39     output        SDRAM_BA_0,  40     output        SDRAM_BA_1,  41     output        SDRAM_CAS_N,  42     output        SDRAM_CKE,  43  //  output SDRAM_CLK,  44     output        SDRAM_CS_N,  45     inout [15:0]  SDRAM_DQ,  46     output        SDRAM_LDQM,  47     output        SDRAM_UDQM,  48     output        SDRAM_RAS_N,  49     output        SDRAM_WE_N      50     ); 51 //Timing parameters of SDRAM winbond W9825G6JH 52 localparam    T_200us=15d20000, 53             T_RC=15d6-15d1,//60ns Ref/Active to Ref/Active Command Period 54             T_RCD=15d3-15d1,//15ns Active to Read/Write Command Delay Time 55             T_RP=15d2-15d1,//15ns Precharge to Active Command Period 56             T_RSC=15d3-15d1,//////Mode register set cycle time 57             T_LATENCY=15d3-15d2,//column to data valid latency 58             T_WR=15d2-15d1;// Write recovery time 59 //SDRAM command 60 localparam  CMD_INIT     =    5b01111    ,// power on         61             CMD_NOP         =    5b10111    ,// nop command 62             CMD_ACTIVE     =    5b10011    ,// active command 63             CMD_READ     =    5b10101    ,// read commadn 64             CMD_WRITE     =    5b10100    ,// write command 65             CMD_B_STOP     =    5b10110    ,// burst    stop 66             CMD_PRECHARGE=    5b10010    ,// precharge 67             //CMD_A_REF     =    5‘b10001    ,// aoto refresh 68             CMD_A_REF     =    5b10010    ,// aoto refresh 69             CMD_LMR         =    5b10000    ;// lode mode register     70 //fsm of initialization     71 localparam  72             INIT_WAIT         =8b00000001 ,//power on ,and wait 200us 73             INIT_PRECHARGE    =8b00000010, //precharge     74             INIT_TRP          =8b00000100, //wait precharge to be done, Trp 75             INIT_AUTO_REFRESH =8b00001000,    // Auto Refresh for 8 times 76             INIT_TRC          =8b00010000, //Refresh-to-Refresh interval 77             INIT_MRS          =8b00100000, //load the Mode Register 78             INIT_TRSC         =8b01000000, //wait the MRS 79             INIT_DONE         =8b10000000; //initialization done 80 //fsm of normal operation 81 localparam     IDLE           =12b000000000001, //wait to fresh or read\write 82             WORK_ACTIVE    =12b000000000010, //active the ROW 83             WORK_TRCD      =12b000000000100, //Row-to-Column delay 84             WORK_READ      =12b000000001000 ,//read 85             WORK_LATENCY   =12b000000010000, //column latency 86             WORK_READ_DATA =http://www.mamicode.com/12b000000100000, //read data from DQ bus 87             //WORK_WAIT      =12‘b000001000000, 88             WORK_WRITE     =12b000010000000, //write 89             WORK_TWR       =12b000100000000,//write recovery delay 90             WORK_TRP       =12b001000000000,//precharge to active command period 91             WORK_AUTO_REFRESH=12b010000000000, //refresh 92             WORK_TRC       =12b100000000000;// Ref/Act to Ref/Act delay ,unused 93  94  95 reg[7:0] init_state_reg, init_state_next;    // SDRAM initialization state     96 reg[14:0] init_timer_reg, init_timer_next;  // delay timer 97 reg [3:0]  ref_cnt_reg, ref_cnt_next;         // repeat timer 98  99 //------------------------------------------------------------------------------100 //SDRAM initialization state  transition begin here101 //------------------------------------------------------------------------------     102 103 always @(posedge clk_i or negedge rst_n_i)104     if(!rst_n_i) begin 105         init_state_reg <= INIT_WAIT;106         init_timer_reg <= T_200us;107         ref_cnt_reg     <= 4d0;108     end109     else begin 110         init_state_reg <= init_state_next;    111         init_timer_reg <= init_timer_next;112         ref_cnt_reg     <= ref_cnt_next;113         end114 115 always @* begin116     init_state_next = init_state_reg;117     init_timer_next = init_timer_reg;118     ref_cnt_next     = ref_cnt_reg;119     if(init_timer_reg != 15d0)120         init_timer_next = init_timer_reg - 15d1;121     122     case(init_state_reg)123     INIT_WAIT: begin124         if(init_timer_reg==15d0)125             init_state_next = INIT_PRECHARGE;126     end    127     INIT_PRECHARGE: begin128         init_state_next = INIT_TRP;129         init_timer_next = T_RP;130     end131     INIT_TRP: begin132         if(init_timer_reg==15d0) begin133             init_state_next = INIT_AUTO_REFRESH;134             ref_cnt_next     = 4d8;135         end136     end137     INIT_AUTO_REFRESH: begin138         init_state_next = INIT_TRC;139         init_timer_next = T_RC;140     end141     INIT_TRC: begin142         if(init_timer_reg == 15d0) begin143             if(ref_cnt_reg == 4d0) begin144                 init_state_next = INIT_MRS;145             end146             else begin 147                 ref_cnt_next = ref_cnt_reg - 4d1;148                 init_state_next = INIT_AUTO_REFRESH;149                 end150         end151     152     end153     INIT_MRS: begin154         init_state_next = INIT_TRSC;155         init_timer_next = T_RSC;156     end157     INIT_TRSC: begin158         if(init_timer_reg == 15d0)159             init_state_next = INIT_DONE;160     end161     INIT_DONE : begin162         init_state_next = INIT_DONE;163     end164 endcase165 end    166 //SDRAM initialization state  transition end here167 reg[15:0] work_timer_reg, work_timer_next;  // delay timer168 reg[11:0] work_state_reg, work_state_next;    // SDRAM normal operation state    169 assign sdram_init_done = (init_state_reg == INIT_DONE);170 //------------------------------------------------------------------------------171 //self refresh every 7 us172 //------------------------------------------------------------------------------     173 reg sdram_ref_req;        // SDRAM self refresh request174 wire sdram_ref_ack;        // SDRAM elf refresh ack175 reg[10:0] cnt_7us;    //176 177 always @ (posedge clk_i or negedge rst_n_i)178     if(!rst_n_i) cnt_7us <= 11d0;179     else if(cnt_7us < 11d700) cnt_7us <= cnt_7us+11b1;    // 60ms(64ms)/8192=7.9us180     else cnt_7us <= 11d0;    181 182 always @ (posedge clk_i or negedge rst_n_i)183     if(!rst_n_i) sdram_ref_req <= 1b0;184     else if(cnt_7us == 11d699) sdram_ref_req <= 1b1;    //refresh request185     else if(sdram_ref_ack) sdram_ref_req <= 1b0;        //request has been acknowledged186 187 //------------------------------------------------------------------------------188 //SDRAM normal operation state transition begin here189 //------------------------------------------------------------------------------190 reg wr_ctrl_reg, wr_ctrl_next;191 always @(posedge clk_i or negedge rst_n_i)192     if(!rst_n_i) begin 193         work_state_reg <= IDLE;194         wr_ctrl_reg    <= 1b0;195         work_timer_reg <= 15d0;196     end197     else begin 198         work_state_reg <= work_state_next;    199       wr_ctrl_reg    <= wr_ctrl_next;    200         work_timer_reg <= work_timer_next;201     end202 //SDRAM normal operation state transition end here203 204  always @* begin205     work_state_next = work_state_reg;206     wr_ctrl_next    = wr_ctrl_reg;207     if(sdram_init_done & work_timer_reg != 15d0)208         work_timer_next = work_timer_reg - 15d1;209     else work_timer_next = work_timer_reg;210     case(work_state_reg)211     IDLE: begin212         if(sdram_init_done & sdram_ref_req) begin213             work_state_next = WORK_AUTO_REFRESH;214         end215         else if(sdram_init_done & wr_req_i) begin216             work_state_next = WORK_ACTIVE;217             wr_ctrl_next    = 1b0;//write218         end219         else if(sdram_init_done & rd_req_i) begin220             work_state_next = WORK_ACTIVE;221             wr_ctrl_next    = 1b1;//read222         end223         else begin224             work_state_next = IDLE;225             wr_ctrl_next    = 1b1;226         end227     end228     WORK_ACTIVE: begin229         work_state_next = WORK_TRCD;230         work_timer_next = T_RCD;231     end232     WORK_TRCD : begin233         if(work_timer_reg == 15d0) begin234             if(wr_ctrl_reg == 1b0)235                 work_state_next = WORK_WRITE;236             else 237                 work_state_next = WORK_READ;238         end239         240     end241     //write242     WORK_WRITE: begin243         work_state_next = WORK_TWR;244         work_timer_next = T_WR;245     end246     WORK_TWR: begin247         if(work_timer_reg==15d0) begin248             work_state_next = WORK_TRP;249             work_timer_next = T_RP;250         end251     end252     WORK_TRP: begin253         if(work_timer_reg == 15d0) 254             work_state_next = IDLE;255     end256     257     //read258     WORK_READ: begin259         work_state_next = WORK_LATENCY;260         work_timer_next = T_LATENCY;261     end262     WORK_LATENCY:begin263         if(work_timer_reg == 15d0) 264             work_state_next = WORK_READ_DATA;265     end266     WORK_READ_DATA: begin267         work_state_next=WORK_TRP;268         work_timer_next= 1b1;269     end270     271     //refresh272     WORK_AUTO_REFRESH: begin273         work_state_next = WORK_TRC;274         work_timer_next = T_RC;275     end276     WORK_TRC: begin277         if(work_timer_reg==15d0)278             work_state_next = IDLE;279     end280     endcase281  end282  283  assign busy_sdram_o = (sdram_init_done && work_state_reg == IDLE) ? 1b0 : 1b1;284  assign sdram_ref_ack =(work_state_reg == WORK_AUTO_REFRESH);285  assign rd_ack_o     = (work_state_reg ==WORK_READ_DATA);286  assign rd_data_valid_o = (work_state_reg == WORK_TRP)&(wr_ctrl_reg == 1b1)&(work_timer_reg==15d0);287  assign wr_ack_o = (work_state_reg == WORK_TWR) ;    288  289 reg[4:0] sdram_cmd_r;    //    SDRAM command290 reg[1:0] sdram_ba_r;291 reg[12:0] sdram_addr_r;292 293 assign {SDRAM_CKE,SDRAM_CS_N,SDRAM_RAS_N,SDRAM_CAS_N,SDRAM_WE_N} = sdram_cmd_r;294 assign {SDRAM_BA_1, SDRAM_BA_0} = sdram_ba_r;295 assign SDRAM_ADDR = sdram_addr_r;296 assign SDRAM_LDQM = (init_state_reg == INIT_WAIT)? 1b1 : 1b0;297 assign SDRAM_UDQM = (init_state_reg == INIT_WAIT)? 1b1 :1b0;298 //-------------------------------------------------------------------------------299 //SDRAM command 300 always @ (posedge clk_i or negedge rst_n_i) begin301     if(!rst_n_i) begin302             sdram_cmd_r <= CMD_INIT;303             sdram_ba_r <= 2b11;304             sdram_addr_r <= 13hfff;305         end306     else307         case (init_state_reg)308                 INIT_WAIT, INIT_TRP,INIT_TRC,INIT_TRSC: begin309                         sdram_cmd_r <= CMD_NOP;310                         sdram_ba_r <= 2b11;311                         sdram_addr_r <= 13h1fff;    312                     end313                 INIT_PRECHARGE: begin314                         sdram_cmd_r <= CMD_PRECHARGE;315                         sdram_ba_r <= 2b11;316                         sdram_addr_r <= 13h1fff;317                     end 318                 INIT_AUTO_REFRESH: begin319                         sdram_cmd_r <= CMD_A_REF;320                         sdram_ba_r <= 2b11;321                         sdram_addr_r <= 13h1fff;                        322                     end                  323                 INIT_MRS: begin    // 324                         sdram_cmd_r <= CMD_LMR;325                         sdram_ba_r <= 2b00;    // Reserved326                         sdram_addr_r <= {327                             3b00,            //Reserved328                             1b0,            //Wite Mode Burst Read and Burst Write 329                             2b00,            //330                             3b011,            // CAS Latency,{A6,A5,A4}=011331                             1b0,            //Adressing Mode,A3=b0332                             3b000            //Brust Length(1,{A2,A1,A0}=000)333                                 };334                     end    335                 INIT_DONE:336                     case (work_state_reg)337                             IDLE,WORK_TRCD,WORK_LATENCY,WORK_TRC,WORK_READ_DATA,WORK_TWR,WORK_TRP: begin338                                     sdram_cmd_r <= CMD_NOP;339                                     sdram_ba_r <= 2b11;340                                     sdram_addr_r <= 13h1fff;341                                 end342                             WORK_ACTIVE: begin343                                     sdram_cmd_r <= CMD_ACTIVE;344                                     if(wr_ctrl_reg==1b0)begin345                                         sdram_ba_r <= wr_addr_i[23:22];    //L-Bank address346                                         sdram_addr_r <= wr_addr_i[21:9];    //row address347                                     end 348                                     else begin349                                         sdram_ba_r <= rd_addr_i[23:22];    //L-Bank address350                                         sdram_addr_r <= rd_addr_i[21:9];    //row address351                                     end352                                 end353                             WORK_READ: begin354                                     sdram_cmd_r <= CMD_READ;355                                     sdram_ba_r <= rd_addr_i[23:22];    //L-Bank address356                                     sdram_addr_r <= {357                                                     4b0010,        // A10=1,precharge 358                                                     rd_addr_i[8:0]    //column address359                                                 };360                                 end361                             WORK_WRITE: begin362                                     sdram_cmd_r <= CMD_WRITE;363                                     sdram_ba_r <= wr_addr_i[23:22];    //L-Bank address364                                     sdram_addr_r <= {365                                                     4b0010,        // A10=1,precharge366                                                     wr_addr_i[8:0]    //column address  367                                                 };368                                 end                            369                             WORK_AUTO_REFRESH: begin370                                     sdram_cmd_r <= CMD_A_REF;371                                     sdram_ba_r <= 2b11;372                                     sdram_addr_r <= 13h1fff;    373                                 end374                             default: begin375                                     sdram_cmd_r <= CMD_NOP;376                                     sdram_ba_r <= 2b11;377                                     sdram_addr_r <= 13h1fff;    378                                 end379                         endcase380                 default: begin381                             sdram_cmd_r <= CMD_NOP;382                             sdram_ba_r <= 2b11;383                             sdram_addr_r <= 13h1fff;    384                         end385             endcase386 end387 388 389 // write data control390 reg [15:0] sdr_din;391 reg sdr_dlink;392 always @ (posedge clk_i or negedge rst_n_i) 393     if(!rst_n_i) sdr_din <= 16d0;    // 394     else if((work_state_reg == WORK_WRITE) | (work_state_reg == WORK_TWR)) sdr_din    <=    wr_data_i; 395 always @ (posedge clk_i or negedge rst_n_i) 396     if(!rst_n_i) sdr_dlink <= 1b0;397    else if((work_state_reg == WORK_WRITE) | (work_state_reg == WORK_TWR)) sdr_dlink <= 1b1;398     else sdr_dlink <= 1b0;399 assign SDRAM_DQ = sdr_dlink ? sdr_din : 16hzzzz;400 401 // read data control402 reg[15:0] sdr_dout;    403 always @ (posedge clk_i or negedge rst_n_i)404     if(!rst_n_i) sdr_dout <= 16d0;     405     //else if((work_state_reg == WORK_READ_DATA)| (work_state_reg == WORK_LATENCY)) sdr_dout <= SDRAM_DQ;    406    else if ( (work_state_reg == WORK_READ_DATA)| (work_state_reg == WORK_LATENCY)) sdr_dout <= SDRAM_DQ;    407 assign rd_data_o = sdr_dout;408 409 endmodule

仿真波形:

技术分享

初始化状态机:

技术分享

工作状态机:

技术分享

SDRAM总结