我的新博客

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 read\write
 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

posted @ 2015-01-28 09:11  Leon#0534  阅读(500)  评论(0编辑  收藏  举报

我的新博客

专注天线学习,欢迎交流 yangli0534@gmail.com - 创建于 2010年

我永远是茫茫EE领域的一名小学生。