使用的流程
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 [email protected] 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
仿真波形:
初始化状态机:
工作状态机: