zoukankan      html  css  js  c++  java
  • SDRAM总结

    使用的流程

    image

    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

    image

    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 image 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

    image

    5 Read and Write Access Modes

    image

    image

    6 Burst Read Command

    image

    7 Burst Write Command

    image

    8 Auto-precharge Command

    9 Precharge Command

    image

    10 Self Refresh Command

    image

    11 NOP

    image

    image

    image

    image

      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=15'd20000,
     53             T_RC=15'd6-15'd1,//60ns Ref/Active to Ref/Active Command Period
     54             T_RCD=15'd3-15'd1,//15ns Active to Read/Write Command Delay Time
     55             T_RP=15'd2-15'd1,//15ns Precharge to Active Command Period
     56             T_RSC=15'd3-15'd1,//////Mode register set cycle time
     57             T_LATENCY=15'd3-15'd2,//column to data valid latency
     58             T_WR=15'd2-15'd1;// Write recovery time
     59 //SDRAM command
     60 localparam  CMD_INIT     =    5'b01111    ,// power on        
     61             CMD_NOP         =    5'b10111    ,// nop command
     62             CMD_ACTIVE     =    5'b10011    ,// active command
     63             CMD_READ     =    5'b10101    ,// read commadn
     64             CMD_WRITE     =    5'b10100    ,// write command
     65             CMD_B_STOP     =    5'b10110    ,// burst    stop
     66             CMD_PRECHARGE=    5'b10010    ,// precharge
     67             //CMD_A_REF     =    5'b10001    ,// aoto refresh
     68             CMD_A_REF     =    5'b10010    ,// aoto refresh
     69             CMD_LMR         =    5'b10000    ;// lode mode register    
     70 //fsm of initialization    
     71 localparam 
     72             INIT_WAIT         =8'b00000001 ,//power on ,and wait 200us
     73             INIT_PRECHARGE    =8'b00000010, //precharge    
     74             INIT_TRP          =8'b00000100, //wait precharge to be done, Trp
     75             INIT_AUTO_REFRESH =8'b00001000,    // Auto Refresh for 8 times
     76             INIT_TRC          =8'b00010000, //Refresh-to-Refresh interval
     77             INIT_MRS          =8'b00100000, //load the Mode Register
     78             INIT_TRSC         =8'b01000000, //wait the MRS
     79             INIT_DONE         =8'b10000000; //initialization done
     80 //fsm of normal operation
     81 localparam     IDLE           =12'b000000000001, //wait to fresh or readwrite
     82             WORK_ACTIVE    =12'b000000000010, //active the ROW
     83             WORK_TRCD      =12'b000000000100, //Row-to-Column delay
     84             WORK_READ      =12'b000000001000 ,//read
     85             WORK_LATENCY   =12'b000000010000, //column latency
     86             WORK_READ_DATA =12'b000000100000, //read data from DQ bus
     87             //WORK_WAIT      =12'b000001000000,
     88             WORK_WRITE     =12'b000010000000, //write
     89             WORK_TWR       =12'b000100000000,//write recovery delay
     90             WORK_TRP       =12'b001000000000,//precharge to active command period
     91             WORK_AUTO_REFRESH=12'b010000000000, //refresh
     92             WORK_TRC       =12'b100000000000;// 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 here
    101 //------------------------------------------------------------------------------     
    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     <= 4'd0;
    108     end
    109     else begin 
    110         init_state_reg <= init_state_next;    
    111         init_timer_reg <= init_timer_next;
    112         ref_cnt_reg     <= ref_cnt_next;
    113         end
    114 
    115 always @* begin
    116     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 != 15'd0)
    120         init_timer_next = init_timer_reg - 15'd1;
    121     
    122     case(init_state_reg)
    123     INIT_WAIT: begin
    124         if(init_timer_reg==15'd0)
    125             init_state_next = INIT_PRECHARGE;
    126     end    
    127     INIT_PRECHARGE: begin
    128         init_state_next = INIT_TRP;
    129         init_timer_next = T_RP;
    130     end
    131     INIT_TRP: begin
    132         if(init_timer_reg==15'd0) begin
    133             init_state_next = INIT_AUTO_REFRESH;
    134             ref_cnt_next     = 4'd8;
    135         end
    136     end
    137     INIT_AUTO_REFRESH: begin
    138         init_state_next = INIT_TRC;
    139         init_timer_next = T_RC;
    140     end
    141     INIT_TRC: begin
    142         if(init_timer_reg == 15'd0) begin
    143             if(ref_cnt_reg == 4'd0) begin
    144                 init_state_next = INIT_MRS;
    145             end
    146             else begin 
    147                 ref_cnt_next = ref_cnt_reg - 4'd1;
    148                 init_state_next = INIT_AUTO_REFRESH;
    149                 end
    150         end
    151     
    152     end
    153     INIT_MRS: begin
    154         init_state_next = INIT_TRSC;
    155         init_timer_next = T_RSC;
    156     end
    157     INIT_TRSC: begin
    158         if(init_timer_reg == 15'd0)
    159             init_state_next = INIT_DONE;
    160     end
    161     INIT_DONE : begin
    162         init_state_next = INIT_DONE;
    163     end
    164 endcase
    165 end    
    166 //SDRAM initialization state  transition end here
    167 reg[15:0] work_timer_reg, work_timer_next;  // delay timer
    168 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 us
    172 //------------------------------------------------------------------------------     
    173 reg sdram_ref_req;        // SDRAM self refresh request
    174 wire sdram_ref_ack;        // SDRAM elf refresh ack
    175 reg[10:0] cnt_7us;    //
    176 
    177 always @ (posedge clk_i or negedge rst_n_i)
    178     if(!rst_n_i) cnt_7us <= 11'd0;
    179     else if(cnt_7us < 11'd700) cnt_7us <= cnt_7us+11'b1;    // 60ms(64ms)/8192=7.9us
    180     else cnt_7us <= 11'd0;    
    181 
    182 always @ (posedge clk_i or negedge rst_n_i)
    183     if(!rst_n_i) sdram_ref_req <= 1'b0;
    184     else if(cnt_7us == 11'd699) sdram_ref_req <= 1'b1;    //refresh request
    185     else if(sdram_ref_ack) sdram_ref_req <= 1'b0;        //request has been acknowledged
    186 
    187 //------------------------------------------------------------------------------
    188 //SDRAM normal operation state transition begin here
    189 //------------------------------------------------------------------------------
    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    <= 1'b0;
    195         work_timer_reg <= 15'd0;
    196     end
    197     else begin 
    198         work_state_reg <= work_state_next;    
    199       wr_ctrl_reg    <= wr_ctrl_next;    
    200         work_timer_reg <= work_timer_next;
    201     end
    202 //SDRAM normal operation state transition end here
    203 
    204  always @* begin
    205     work_state_next = work_state_reg;
    206     wr_ctrl_next    = wr_ctrl_reg;
    207     if(sdram_init_done & work_timer_reg != 15'd0)
    208         work_timer_next = work_timer_reg - 15'd1;
    209     else work_timer_next = work_timer_reg;
    210     case(work_state_reg)
    211     IDLE: begin
    212         if(sdram_init_done & sdram_ref_req) begin
    213             work_state_next = WORK_AUTO_REFRESH;
    214         end
    215         else if(sdram_init_done & wr_req_i) begin
    216             work_state_next = WORK_ACTIVE;
    217             wr_ctrl_next    = 1'b0;//write
    218         end
    219         else if(sdram_init_done & rd_req_i) begin
    220             work_state_next = WORK_ACTIVE;
    221             wr_ctrl_next    = 1'b1;//read
    222         end
    223         else begin
    224             work_state_next = IDLE;
    225             wr_ctrl_next    = 1'b1;
    226         end
    227     end
    228     WORK_ACTIVE: begin
    229         work_state_next = WORK_TRCD;
    230         work_timer_next = T_RCD;
    231     end
    232     WORK_TRCD : begin
    233         if(work_timer_reg == 15'd0) begin
    234             if(wr_ctrl_reg == 1'b0)
    235                 work_state_next = WORK_WRITE;
    236             else 
    237                 work_state_next = WORK_READ;
    238         end
    239         
    240     end
    241     //write
    242     WORK_WRITE: begin
    243         work_state_next = WORK_TWR;
    244         work_timer_next = T_WR;
    245     end
    246     WORK_TWR: begin
    247         if(work_timer_reg==15'd0) begin
    248             work_state_next = WORK_TRP;
    249             work_timer_next = T_RP;
    250         end
    251     end
    252     WORK_TRP: begin
    253         if(work_timer_reg == 15'd0) 
    254             work_state_next = IDLE;
    255     end
    256     
    257     //read
    258     WORK_READ: begin
    259         work_state_next = WORK_LATENCY;
    260         work_timer_next = T_LATENCY;
    261     end
    262     WORK_LATENCY:begin
    263         if(work_timer_reg == 15'd0) 
    264             work_state_next = WORK_READ_DATA;
    265     end
    266     WORK_READ_DATA: begin
    267         work_state_next=WORK_TRP;
    268         work_timer_next= 1'b1;
    269     end
    270     
    271     //refresh
    272     WORK_AUTO_REFRESH: begin
    273         work_state_next = WORK_TRC;
    274         work_timer_next = T_RC;
    275     end
    276     WORK_TRC: begin
    277         if(work_timer_reg==15'd0)
    278             work_state_next = IDLE;
    279     end
    280     endcase
    281  end
    282  
    283  assign busy_sdram_o = (sdram_init_done && work_state_reg == IDLE) ? 1'b0 : 1'b1;
    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 == 1'b1)&(work_timer_reg==15'd0);
    287  assign wr_ack_o = (work_state_reg == WORK_TWR) ;    
    288  
    289 reg[4:0] sdram_cmd_r;    //    SDRAM command
    290 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)? 1'b1 : 1'b0;
    297 assign SDRAM_UDQM = (init_state_reg == INIT_WAIT)? 1'b1 :1'b0;
    298 //-------------------------------------------------------------------------------
    299 //SDRAM command 
    300 always @ (posedge clk_i or negedge rst_n_i) begin
    301     if(!rst_n_i) begin
    302             sdram_cmd_r <= CMD_INIT;
    303             sdram_ba_r <= 2'b11;
    304             sdram_addr_r <= 13'hfff;
    305         end
    306     else
    307         case (init_state_reg)
    308                 INIT_WAIT, INIT_TRP,INIT_TRC,INIT_TRSC: begin
    309                         sdram_cmd_r <= CMD_NOP;
    310                         sdram_ba_r <= 2'b11;
    311                         sdram_addr_r <= 13'h1fff;    
    312                     end
    313                 INIT_PRECHARGE: begin
    314                         sdram_cmd_r <= CMD_PRECHARGE;
    315                         sdram_ba_r <= 2'b11;
    316                         sdram_addr_r <= 13'h1fff;
    317                     end 
    318                 INIT_AUTO_REFRESH: begin
    319                         sdram_cmd_r <= CMD_A_REF;
    320                         sdram_ba_r <= 2'b11;
    321                         sdram_addr_r <= 13'h1fff;                        
    322                     end                  
    323                 INIT_MRS: begin    // 
    324                         sdram_cmd_r <= CMD_LMR;
    325                         sdram_ba_r <= 2'b00;    // Reserved
    326                         sdram_addr_r <= {
    327                             3'b00,            //Reserved
    328                             1'b0,            //Wite Mode Burst Read and Burst Write 
    329                             2'b00,            //
    330                             3'b011,            // CAS Latency,{A6,A5,A4}=011
    331                             1'b0,            //Adressing Mode,A3=b0
    332                             3'b000            //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: begin
    338                                     sdram_cmd_r <= CMD_NOP;
    339                                     sdram_ba_r <= 2'b11;
    340                                     sdram_addr_r <= 13'h1fff;
    341                                 end
    342                             WORK_ACTIVE: begin
    343                                     sdram_cmd_r <= CMD_ACTIVE;
    344                                     if(wr_ctrl_reg==1'b0)begin
    345                                         sdram_ba_r <= wr_addr_i[23:22];    //L-Bank address
    346                                         sdram_addr_r <= wr_addr_i[21:9];    //row address
    347                                     end 
    348                                     else begin
    349                                         sdram_ba_r <= rd_addr_i[23:22];    //L-Bank address
    350                                         sdram_addr_r <= rd_addr_i[21:9];    //row address
    351                                     end
    352                                 end
    353                             WORK_READ: begin
    354                                     sdram_cmd_r <= CMD_READ;
    355                                     sdram_ba_r <= rd_addr_i[23:22];    //L-Bank address
    356                                     sdram_addr_r <= {
    357                                                     4'b0010,        // A10=1,precharge 
    358                                                     rd_addr_i[8:0]    //column address
    359                                                 };
    360                                 end
    361                             WORK_WRITE: begin
    362                                     sdram_cmd_r <= CMD_WRITE;
    363                                     sdram_ba_r <= wr_addr_i[23:22];    //L-Bank address
    364                                     sdram_addr_r <= {
    365                                                     4'b0010,        // A10=1,precharge
    366                                                     wr_addr_i[8:0]    //column address  
    367                                                 };
    368                                 end                            
    369                             WORK_AUTO_REFRESH: begin
    370                                     sdram_cmd_r <= CMD_A_REF;
    371                                     sdram_ba_r <= 2'b11;
    372                                     sdram_addr_r <= 13'h1fff;    
    373                                 end
    374                             default: begin
    375                                     sdram_cmd_r <= CMD_NOP;
    376                                     sdram_ba_r <= 2'b11;
    377                                     sdram_addr_r <= 13'h1fff;    
    378                                 end
    379                         endcase
    380                 default: begin
    381                             sdram_cmd_r <= CMD_NOP;
    382                             sdram_ba_r <= 2'b11;
    383                             sdram_addr_r <= 13'h1fff;    
    384                         end
    385             endcase
    386 end
    387 
    388 
    389 // write data control
    390 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 <= 16'd0;    // 
    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 <= 1'b0;
    397    else if((work_state_reg == WORK_WRITE) | (work_state_reg == WORK_TWR)) sdr_dlink <= 1'b1;
    398     else sdr_dlink <= 1'b0;
    399 assign SDRAM_DQ = sdr_dlink ? sdr_din : 16'hzzzz;
    400 
    401 // read data control
    402 reg[15:0] sdr_dout;    
    403 always @ (posedge clk_i or negedge rst_n_i)
    404     if(!rst_n_i) sdr_dout <= 16'd0;     
    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

    仿真波形:

    初始化状态机:

    tmp

    工作状态机:

    tmp

    OPTIMISM, PASSION & HARDWORK
  • 相关阅读:
    2018.1.10 区块链论文翻译
    2018.1.9 区块链论文翻译
    2019.1.7 区块链论文翻译
    #在蓝懿iOS学习的日子#
    #在蓝懿学习iOSd的日子#
    #在蓝懿iOS学习的日子#2014年10月15日
    #蓝懿iOSi学习的日子#2015年10月14日
    #蓝懿ios学习的日子#2015年 10月13日
    #蓝懿ios学习的日子#2015年10月12鈤
    三种读写XML的方法
  • 原文地址:https://www.cnblogs.com/hiramlee0534/p/4254920.html
Copyright © 2011-2022 走看看