首页 > 代码库 > 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=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 =http://www.mamicode.com/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 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 <= 4‘d0;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 != 15‘d0)120 init_timer_next = init_timer_reg - 15‘d1;121 122 case(init_state_reg)123 INIT_WAIT: begin124 if(init_timer_reg==15‘d0)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==15‘d0) begin133 init_state_next = INIT_AUTO_REFRESH;134 ref_cnt_next = 4‘d8;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 == 15‘d0) begin143 if(ref_cnt_reg == 4‘d0) begin144 init_state_next = INIT_MRS;145 end146 else begin 147 ref_cnt_next = ref_cnt_reg - 4‘d1;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 == 15‘d0)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 <= 11‘d0;179 else if(cnt_7us < 11‘d700) cnt_7us <= cnt_7us+11‘b1; // 60ms(64ms)/8192=7.9us180 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 request185 else if(sdram_ref_ack) sdram_ref_req <= 1‘b0; //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 <= 1‘b0;195 work_timer_reg <= 15‘d0;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 != 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: 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 = 1‘b0;//write218 end219 else if(sdram_init_done & rd_req_i) begin220 work_state_next = WORK_ACTIVE;221 wr_ctrl_next = 1‘b1;//read222 end223 else begin224 work_state_next = IDLE;225 wr_ctrl_next = 1‘b1;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 == 15‘d0) begin234 if(wr_ctrl_reg == 1‘b0)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==15‘d0) begin248 work_state_next = WORK_TRP;249 work_timer_next = T_RP;250 end251 end252 WORK_TRP: begin253 if(work_timer_reg == 15‘d0) 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 == 15‘d0) 264 work_state_next = WORK_READ_DATA;265 end266 WORK_READ_DATA: begin267 work_state_next=WORK_TRP;268 work_timer_next= 1‘b1;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==15‘d0)278 work_state_next = IDLE;279 end280 endcase281 end282 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 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)? 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) begin301 if(!rst_n_i) begin302 sdram_cmd_r <= CMD_INIT;303 sdram_ba_r <= 2‘b11;304 sdram_addr_r <= 13‘hfff;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 <= 2‘b11;311 sdram_addr_r <= 13‘h1fff; 312 end313 INIT_PRECHARGE: begin314 sdram_cmd_r <= CMD_PRECHARGE;315 sdram_ba_r <= 2‘b11;316 sdram_addr_r <= 13‘h1fff;317 end 318 INIT_AUTO_REFRESH: begin319 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; // Reserved326 sdram_addr_r <= {327 3‘b00, //Reserved328 1‘b0, //Wite Mode Burst Read and Burst Write 329 2‘b00, //330 3‘b011, // CAS Latency,{A6,A5,A4}=011331 1‘b0, //Adressing Mode,A3=b0332 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: begin338 sdram_cmd_r <= CMD_NOP;339 sdram_ba_r <= 2‘b11;340 sdram_addr_r <= 13‘h1fff;341 end342 WORK_ACTIVE: begin343 sdram_cmd_r <= CMD_ACTIVE;344 if(wr_ctrl_reg==1‘b0)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 4‘b0010, // 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 4‘b0010, // 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 <= 2‘b11;372 sdram_addr_r <= 13‘h1fff; 373 end374 default: begin375 sdram_cmd_r <= CMD_NOP;376 sdram_ba_r <= 2‘b11;377 sdram_addr_r <= 13‘h1fff; 378 end379 endcase380 default: begin381 sdram_cmd_r <= CMD_NOP;382 sdram_ba_r <= 2‘b11;383 sdram_addr_r <= 13‘h1fff; 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 <= 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 control402 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
仿真波形:
初始化状态机:
工作状态机:
SDRAM总结