add peripherals
[shakti-peripherals.git] / src / peripherals / sdram / controller / sdrc_xfr_ctl.v
1 /*********************************************************************
2
3 SDRAM Controller Transfer control
4
5 This file is part of the sdram controller project
6 http://www.opencores.org/cores/sdr_ctrl/
7
8 Description: SDRAM Controller Transfer control
9
10 This module takes requests from sdrc_bank_ctl and runs the
11 transfer. The input request is guaranteed to be in a bank that is
12 precharged and activated. This block runs the transfer until a
13 burst boundary is reached, then issues another read/write command
14 to sequentially step thru memory if wrap=0, until the transfer is
15 completed.
16
17 if a read transfer finishes and the caddr is not at a burst boundary
18 a burst terminate command is issued unless another read/write or
19 precharge to the same bank is pending.
20
21 if a write transfer finishes and the caddr is not at a burst boundary
22 a burst terminate command is issued unless a read/write is pending.
23
24 If a refresh request is made, the bank_ctl will be held off until
25 the number of refreshes requested are completed.
26
27 This block also handles SDRAM initialization.
28
29
30 To Do:
31 nothing
32
33 Author(s):
34 - Dinesh Annayya, dinesha@opencores.org
35 Version : 1.0 - 8th Jan 2012
36
37
38
39 Copyright (C) 2000 Authors and OPENCORES.ORG
40
41 This source file may be used and distributed without
42 restriction provided that this copyright statement is not
43 removed from the file and that any derivative work contains
44 the original copyright notice and the associated disclaimer.
45
46 This source file is free software; you can redistribute it
47 and/or modify it under the terms of the GNU Lesser General
48 Public License as published by the Free Software Foundation;
49 either version 2.1 of the License, or (at your option) any
50 later version.
51
52 This source is distributed in the hope that it will be
53 useful, but WITHOUT ANY WARRANTY; without even the implied
54 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
55 PURPOSE. See the GNU Lesser General Public License for more
56 details.
57
58 You should have received a copy of the GNU Lesser General
59 Public License along with this source; if not, download it
60 from http://www.opencores.org/lgpl.shtml
61
62 *******************************************************************/
63
64
65
66 module sdrc_xfr_ctl (clk,
67 reset_n,
68
69 /* Transfer request from bank_ctl */
70 r2x_idle, // Req is idle
71 b2x_idle, // All banks are idle
72 b2x_req, // Req from bank_ctl
73 b2x_start, // first chunk of transfer
74 b2x_last, // last chunk of transfer
75 b2x_id, // Transfer ID
76 b2x_ba, // bank address
77 b2x_addr, // row/col address
78 b2x_len, // transfer length
79 b2x_cmd, // transfer command
80 b2x_wrap, // Wrap mode transfer
81 x2b_ack, // command accepted
82
83 /* Status to bank_ctl, req_gen */
84 b2x_tras_ok, // Tras for all banks expired
85 x2b_refresh, // We did a refresh
86 x2b_pre_ok, // OK to do a precharge (per bank)
87 x2b_act_ok, // OK to do an activate
88 x2b_rdok, // OK to do a read
89 x2b_wrok, // OK to do a write
90
91 /* SDRAM I/O */
92 sdr_cs_n,
93 sdr_cke,
94 sdr_ras_n,
95 sdr_cas_n,
96 sdr_we_n,
97 sdr_dqm,
98 sdr_ba,
99 sdr_addr,
100 sdr_din,
101 sdr_dout,
102 sdr_den_n,
103
104 /* Data Flow to the app */
105 x2a_rdstart,
106 x2a_wrstart,
107 x2a_rdlast,
108 x2a_wrlast,
109 x2a_id,
110 a2x_wrdt,
111 a2x_wren_n,
112 x2a_wrnext,
113 x2a_rddt,
114 x2a_rdok,
115 sdr_init_done,
116
117 /* SDRAM Parameters */
118 sdram_enable,
119 sdram_mode_reg,
120
121 /* output for generate row address of the transfer */
122 xfr_bank_sel,
123
124 /* SDRAM Timing */
125 cas_latency,
126 trp_delay, // Precharge to refresh delay
127 trcar_delay, // Auto-refresh period
128 twr_delay, // Write recovery delay
129 rfsh_time, // time per row (31.25 or 15.6125 uS)
130 rfsh_rmax); // Number of rows to rfsh at a time (<120uS)
131
132
133 `define SDR_REQ_ID_W 4
134
135 `define SDR_RFSH_TIMER_W 12
136 `define SDR_RFSH_ROW_CNT_W 3
137
138 // B2X Command
139
140 `define OP_PRE 2'b00
141 `define OP_ACT 2'b01
142 `define OP_RD 2'b10
143 `define OP_WR 2'b11
144
145 // SDRAM Commands (CS_N, RAS_N, CAS_N, WE_N)
146
147 `define SDR_DESEL 4'b1111
148 `define SDR_NOOP 4'b0111
149 `define SDR_ACTIVATE 4'b0011
150 `define SDR_READ 4'b0101
151 `define SDR_WRITE 4'b0100
152 `define SDR_BT 4'b0110
153 `define SDR_PRECHARGE 4'b0010
154 `define SDR_REFRESH 4'b0001
155 `define SDR_MODE 4'b0000
156
157 `define ASIC 1'b1
158 `define FPGA 1'b0
159 `define TARGET_DESIGN `ASIC
160 // 12 bit subtractor is not feasibile for FPGA, so changed to 6 bits
161 `define REQ_BW (`TARGET_DESIGN == `FPGA) ? 6 : 12 // Request Width
162
163 parameter SDR_DW = 64; // SDR Data Width
164 parameter SDR_BW = 8; // SDR Byte Width
165
166
167 input clk, reset_n;
168
169 /* Req from bank_ctl */
170 input b2x_req, b2x_start, b2x_last, b2x_tras_ok,
171 b2x_wrap, r2x_idle, b2x_idle;
172 input [`SDR_REQ_ID_W-1:0] b2x_id;
173 input [1:0] b2x_ba;
174 input [12:0] b2x_addr;
175 input [`REQ_BW-1:0] b2x_len;
176 input [1:0] b2x_cmd;
177 output x2b_ack;
178
179 /* Status to bank_ctl */
180 output [3:0] x2b_pre_ok;
181 output x2b_refresh, x2b_act_ok, x2b_rdok,
182 x2b_wrok;
183 /* Data Flow to the app */
184 output x2a_rdstart, x2a_wrstart, x2a_rdlast, x2a_wrlast;
185 output [`SDR_REQ_ID_W-1:0] x2a_id;
186
187 input [SDR_DW-1:0] a2x_wrdt;
188 input [SDR_BW-1:0] a2x_wren_n;
189 output [SDR_DW-1:0] x2a_rddt;
190 output x2a_wrnext, x2a_rdok, sdr_init_done;
191
192 /* Interface to SDRAMs */
193 output sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n,
194 sdr_we_n;
195 output [SDR_BW-1:0] sdr_dqm;
196 output [1:0] sdr_ba;
197 output [12:0] sdr_addr;
198 input [SDR_DW-1:0] sdr_din;
199 output [SDR_DW-1:0] sdr_dout;
200 output [SDR_BW-1:0] sdr_den_n;
201
202 output [1:0] xfr_bank_sel;
203
204 input sdram_enable;
205 input [12:0] sdram_mode_reg;
206 input [2:0] cas_latency;
207 input [3:0] trp_delay, trcar_delay, twr_delay;
208 input [`SDR_RFSH_TIMER_W-1 : 0] rfsh_time;
209 input [`SDR_RFSH_ROW_CNT_W-1:0] rfsh_rmax;
210
211 // vish change mode reg ext
212 //reg [12:0] sdram_mode_ext_reg;
213 reg init_delay_done; // winbond initial delay done flag : vish change
214 reg mode_set;
215 reg wr_mode_set;
216
217 /************************************************************************/
218 // Internal Nets
219
220 `define XFR_IDLE 2'b00
221 `define XFR_WRITE 2'b01
222 `define XFR_READ 2'b10
223 `define XFR_RDWT 2'b11
224
225 reg [1:0] xfr_st, next_xfr_st;
226 reg [12:0] xfr_caddr;
227 wire last_burst;
228 wire x2a_rdstart, x2a_wrstart, x2a_rdlast, x2a_wrlast;
229 reg l_start, l_last, l_wrap;
230 wire [`SDR_REQ_ID_W-1:0] x2a_id;
231 reg [`SDR_REQ_ID_W-1:0] l_id;
232 wire [1:0] xfr_ba;
233 reg [1:0] l_ba;
234 wire [12:0] xfr_addr;
235 wire [`REQ_BW-1:0] xfr_len, next_xfr_len;
236 reg [`REQ_BW-1:0] l_len;
237
238 reg mgmt_idle, mgmt_req;
239 reg [3:0] mgmt_cmd;
240 reg [12:0] mgmt_addr;
241 reg [1:0] mgmt_ba;
242
243 reg sel_mgmt, sel_b2x;
244 reg cb_pre_ok, rdok, wrok, wr_next,
245 rd_next, sdr_init_done, act_cmd, d_act_cmd;
246 wire [3:0] b2x_sdr_cmd, xfr_cmd;
247 reg [3:0] i_xfr_cmd;
248 wire mgmt_ack, x2b_ack, b2x_read, b2x_write,
249 b2x_prechg, d_rd_next, dt_next, xfr_end,
250 rd_pipe_mt, ld_xfr, rd_last, d_rd_last,
251 wr_last, l_xfr_end, rd_start, d_rd_start,
252 wr_start, page_hit, burst_bdry, xfr_wrap,
253 b2x_prechg_hit;
254 reg [6:0] l_rd_next, l_rd_start, l_rd_last;
255
256 //vish change
257 reg[11:0] rg_initial_delay;
258
259
260 assign b2x_read = (b2x_cmd == `OP_RD) ? 1'b1 : 1'b0;
261
262 assign b2x_write = (b2x_cmd == `OP_WR) ? 1'b1 : 1'b0;
263
264 assign b2x_prechg = (b2x_cmd == `OP_PRE) ? 1'b1 : 1'b0;
265
266 assign b2x_sdr_cmd = (b2x_cmd == `OP_PRE) ? `SDR_PRECHARGE :
267 (b2x_cmd == `OP_ACT) ? `SDR_ACTIVATE :
268 (b2x_cmd == `OP_RD) ? `SDR_READ :
269 (b2x_cmd == `OP_WR) ? `SDR_WRITE : `SDR_DESEL;
270
271 assign page_hit = (b2x_ba == l_ba) ? 1'b1 : 1'b0;
272
273 assign b2x_prechg_hit = b2x_prechg & page_hit;
274
275 assign xfr_cmd = (sel_mgmt) ? mgmt_cmd :
276 (sel_b2x) ? b2x_sdr_cmd : i_xfr_cmd;
277
278 assign xfr_addr = (sel_mgmt) ? mgmt_addr :
279 (sel_b2x) ? b2x_addr : xfr_caddr+1;
280
281 assign mgmt_ack = sel_mgmt;
282
283 assign x2b_ack = sel_b2x;
284
285 assign ld_xfr = sel_b2x & (b2x_read | b2x_write);
286
287 assign xfr_len = (ld_xfr) ? b2x_len : l_len;
288
289 //assign next_xfr_len = (l_xfr_end && !ld_xfr) ? l_len : xfr_len - 1;
290 assign next_xfr_len = (ld_xfr) ? b2x_len :
291 (l_xfr_end) ? l_len: l_len - 1;
292
293 assign d_rd_next = (cas_latency == 3'b001) ? l_rd_next[2] :
294 (cas_latency == 3'b010) ? l_rd_next[3] :
295 (cas_latency == 3'b011) ? l_rd_next[4] :
296 (cas_latency == 3'b100) ? l_rd_next[5] :
297 l_rd_next[6];
298
299 assign d_rd_last = (cas_latency == 3'b001) ? l_rd_last[2] :
300 (cas_latency == 3'b010) ? l_rd_last[3] :
301 (cas_latency == 3'b011) ? l_rd_last[4] :
302 (cas_latency == 3'b100) ? l_rd_last[5] :
303 l_rd_last[6];
304
305 assign d_rd_start = (cas_latency == 3'b001) ? l_rd_start[2] :
306 (cas_latency == 3'b010) ? l_rd_start[3] :
307 (cas_latency == 3'b011) ? l_rd_start[4] :
308 (cas_latency == 3'b100) ? l_rd_start[5] :
309 l_rd_start[6];
310
311 assign rd_pipe_mt = (cas_latency == 3'b001) ? ~|l_rd_next[1:0] :
312 (cas_latency == 3'b010) ? ~|l_rd_next[2:0] :
313 (cas_latency == 3'b011) ? ~|l_rd_next[3:0] :
314 (cas_latency == 3'b100) ? ~|l_rd_next[4:0] :
315 ~|l_rd_next[5:0];
316
317 assign dt_next = wr_next | d_rd_next;
318
319 assign xfr_end = ~|xfr_len;
320
321 assign l_xfr_end = ~|(l_len-1);
322
323 assign rd_start = ld_xfr & b2x_read & b2x_start;
324
325 assign wr_start = ld_xfr & b2x_write & b2x_start;
326
327 assign rd_last = rd_next & last_burst & ~|xfr_len[`REQ_BW-1:1];
328
329 //assign wr_last = wr_next & last_burst & ~|xfr_len[APP_RW-1:1];
330
331 assign wr_last = last_burst & ~|xfr_len[`REQ_BW-1:1];
332
333 //assign xfr_ba = (ld_xfr) ? b2x_ba : l_ba;
334 assign xfr_ba = (sel_mgmt) ? mgmt_ba :
335 (sel_b2x) ? b2x_ba : l_ba;
336
337 assign xfr_wrap = (ld_xfr) ? b2x_wrap : l_wrap;
338
339 // assign burst_bdry = ~|xfr_caddr[2:0];
340 wire [1:0] xfr_caddr_lsb = (xfr_caddr[1:0]+1);
341 assign burst_bdry = ~|(xfr_caddr_lsb[1:0]);
342
343 always @ (posedge clk) begin
344 if (~reset_n) begin
345 xfr_caddr <= 13'b0;
346 l_start <= 1'b0;
347 l_last <= 1'b0;
348 l_wrap <= 1'b0;
349 l_id <= 0;
350 l_ba <= 0;
351 l_len <= 0;
352 l_rd_next <= 7'b0;
353 l_rd_start <= 7'b0;
354 l_rd_last <= 7'b0;
355 act_cmd <= 1'b0;
356 d_act_cmd <= 1'b0;
357 xfr_st <= `XFR_IDLE;
358 end // if (~reset_n)
359
360 else begin
361 xfr_caddr <= (ld_xfr) ? b2x_addr :
362 (rd_next | wr_next) ? xfr_caddr + 1 : xfr_caddr;
363 l_start <= (dt_next) ? 1'b0 :
364 (ld_xfr) ? b2x_start : l_start;
365 l_last <= (ld_xfr) ? b2x_last : l_last;
366 l_wrap <= (ld_xfr) ? b2x_wrap : l_wrap;
367 l_id <= (ld_xfr) ? b2x_id : l_id;
368 l_ba <= (ld_xfr) ? b2x_ba : l_ba;
369 l_len <= next_xfr_len;
370 l_rd_next <= {l_rd_next[5:0], rd_next};
371 l_rd_start <= {l_rd_start[5:0], rd_start};
372 l_rd_last <= {l_rd_last[5:0], rd_last};
373 act_cmd <= (xfr_cmd == `SDR_ACTIVATE) ? 1'b1 : 1'b0;
374 d_act_cmd <= act_cmd;
375 xfr_st <= next_xfr_st;
376 end // else: !if(~reset_n)
377
378 end // always @ (posedge clk)
379
380
381 always @ (*) begin
382 case (xfr_st)
383
384 `XFR_IDLE : begin
385
386 sel_mgmt = mgmt_req;
387 sel_b2x = ~mgmt_req & sdr_init_done & b2x_req;
388 i_xfr_cmd = `SDR_DESEL;
389 rd_next = ~mgmt_req & sdr_init_done & b2x_req & b2x_read;
390 wr_next = ~mgmt_req & sdr_init_done & b2x_req & b2x_write;
391 rdok = ~mgmt_req;
392 cb_pre_ok = 1'b1;
393 wrok = ~mgmt_req;
394 next_xfr_st = (mgmt_req | ~sdr_init_done) ? `XFR_IDLE :
395 (~b2x_req) ? `XFR_IDLE :
396 (b2x_read) ? `XFR_READ :
397 (b2x_write) ? `XFR_WRITE : `XFR_IDLE;
398
399 end // case: `XFR_IDLE
400
401 `XFR_READ : begin
402 rd_next = ~l_xfr_end |
403 l_xfr_end & ~mgmt_req & b2x_req & b2x_read;
404 wr_next = 1'b0;
405 rdok = l_xfr_end & ~mgmt_req;
406 // Break the timing path for FPGA Based Design
407 cb_pre_ok = (`TARGET_DESIGN == `FPGA) ? 1'b0 : l_xfr_end;
408 wrok = 1'b0;
409 sel_mgmt = 1'b0;
410
411 if (l_xfr_end) begin // end of transfer
412
413 if (~l_wrap) begin
414 // Current transfer was not wrap mode, may need BT
415 // If next cmd is a R or W or PRE to same bank allow
416 // it else issue BT
417 // This is a little pessimistic since BT is issued
418 // for non-wrap mode transfers even if the transfer
419 // ends on a burst boundary, but is felt to be of
420 // minimal performance impact.
421
422 i_xfr_cmd = `SDR_BT;
423 sel_b2x = b2x_req & ~mgmt_req & (b2x_read | b2x_prechg_hit);
424
425 end // if (~l_wrap)
426
427 else begin
428 // Wrap mode transfer, by definition is end of burst
429 // boundary
430
431 i_xfr_cmd = `SDR_DESEL;
432 sel_b2x = b2x_req & ~mgmt_req & ~b2x_write;
433
434 end // else: !if(~l_wrap)
435
436 next_xfr_st = (sdr_init_done) ? ((b2x_req & ~mgmt_req & b2x_read) ? `XFR_READ : `XFR_RDWT) : `XFR_IDLE;
437
438 end // if (l_xfr_end)
439
440 else begin
441 // Not end of transfer
442 // If current transfer was not wrap mode and we are at
443 // the start of a burst boundary issue another R cmd to
444 // step sequemtially thru memory, ELSE,
445 // issue precharge/activate commands from the bank control
446
447 i_xfr_cmd = (burst_bdry & ~l_wrap) ? `SDR_READ : `SDR_DESEL;
448 sel_b2x = ~(burst_bdry & ~l_wrap) & b2x_req;
449 next_xfr_st = `XFR_READ;
450
451 end // else: !if(l_xfr_end)
452
453 end // case: `XFR_READ
454
455 `XFR_RDWT : begin
456 rd_next = ~mgmt_req & b2x_req & b2x_read;
457 wr_next = rd_pipe_mt & ~mgmt_req & b2x_req & b2x_write;
458 rdok = ~mgmt_req;
459 cb_pre_ok = 1'b1;
460 wrok = rd_pipe_mt & ~mgmt_req;
461
462 sel_mgmt = mgmt_req;
463
464 sel_b2x = ~mgmt_req & b2x_req;
465
466 i_xfr_cmd = `SDR_DESEL;
467
468 next_xfr_st = (~mgmt_req & b2x_req & b2x_read) ? `XFR_READ :
469 (~rd_pipe_mt) ? `XFR_RDWT :
470 (~mgmt_req & b2x_req & b2x_write) ? `XFR_WRITE :
471 `XFR_IDLE;
472
473 end // case: `XFR_RDWT
474
475 `XFR_WRITE : begin
476 rd_next = l_xfr_end & ~mgmt_req & b2x_req & b2x_read;
477 wr_next = ~l_xfr_end |
478 l_xfr_end & ~mgmt_req & b2x_req & b2x_write;
479 rdok = l_xfr_end & ~mgmt_req;
480 cb_pre_ok = 1'b0;
481 wrok = l_xfr_end & ~mgmt_req;
482 sel_mgmt = 1'b0;
483
484 if (l_xfr_end) begin // End of transfer
485
486 if (~l_wrap) begin
487 // Current transfer was not wrap mode, may need BT
488 // If next cmd is a R or W allow it else issue BT
489 // This is a little pessimistic since BT is issued
490 // for non-wrap mode transfers even if the transfer
491 // ends on a burst boundary, but is felt to be of
492 // minimal performance impact.
493
494
495 sel_b2x = b2x_req & ~mgmt_req & (b2x_read | b2x_write);
496 i_xfr_cmd = `SDR_BT;
497 end // if (~l_wrap)
498
499 else begin
500 // Wrap mode transfer, by definition is end of burst
501 // boundary
502
503 sel_b2x = b2x_req & ~mgmt_req & ~b2x_prechg_hit;
504 i_xfr_cmd = `SDR_DESEL;
505 end // else: !if(~l_wrap)
506
507 next_xfr_st = (~mgmt_req & b2x_req & b2x_read) ? `XFR_READ :
508 (~mgmt_req & b2x_req & b2x_write) ? `XFR_WRITE :
509 `XFR_IDLE;
510
511 end // if (l_xfr_end)
512
513 else begin
514 // Not end of transfer
515 // If current transfer was not wrap mode and we are at
516 // the start of a burst boundary issue another R cmd to
517 // step sequemtially thru memory, ELSE,
518 // issue precharge/activate commands from the bank control
519
520 if (burst_bdry & ~l_wrap) begin
521 sel_b2x = 1'b0;
522 i_xfr_cmd = `SDR_WRITE;
523 end // if (burst_bdry & ~l_wrap)
524
525 else begin
526 sel_b2x = b2x_req & ~mgmt_req;
527 i_xfr_cmd = `SDR_DESEL;
528 end // else: !if(burst_bdry & ~l_wrap)
529
530 next_xfr_st = `XFR_WRITE;
531 end // else: !if(l_xfr_end)
532
533 end // case: `XFR_WRITE
534
535 endcase // case(xfr_st)
536
537 end // always @ (xfr_st or ...)
538
539 // signals to bank_ctl (x2b_refresh, x2b_act_ok, x2b_rdok, x2b_wrok,
540 // x2b_pre_ok[3:0]
541
542 assign x2b_refresh = (xfr_cmd == `SDR_REFRESH) ? 1'b1 : 1'b0;
543
544 assign x2b_act_ok = ~act_cmd & ~d_act_cmd;
545
546 assign x2b_rdok = rdok;
547
548 assign x2b_wrok = wrok;
549
550 //assign x2b_pre_ok[0] = (l_ba == 2'b00) ? cb_pre_ok : 1'b1;
551 //assign x2b_pre_ok[1] = (l_ba == 2'b01) ? cb_pre_ok : 1'b1;
552 //assign x2b_pre_ok[2] = (l_ba == 2'b10) ? cb_pre_ok : 1'b1;
553 //assign x2b_pre_ok[3] = (l_ba == 2'b11) ? cb_pre_ok : 1'b1;
554
555 assign x2b_pre_ok[0] = cb_pre_ok;
556 assign x2b_pre_ok[1] = cb_pre_ok;
557 assign x2b_pre_ok[2] = cb_pre_ok;
558 assign x2b_pre_ok[3] = cb_pre_ok;
559 assign last_burst = (ld_xfr) ? b2x_last : l_last;
560
561 /************************************************************************/
562 // APP Data I/F
563
564 wire [SDR_DW-1:0] x2a_rddt;
565
566 //assign x2a_start = (ld_xfr) ? b2x_start : l_start;
567 assign x2a_rdstart = d_rd_start;
568 assign x2a_wrstart = wr_start;
569
570 assign x2a_rdlast = d_rd_last;
571 assign x2a_wrlast = wr_last;
572
573 assign x2a_id = (ld_xfr) ? b2x_id : l_id;
574
575 assign x2a_rddt = sdr_din;
576
577 assign x2a_wrnext = wr_next;
578
579 assign x2a_rdok = d_rd_next;
580
581 /************************************************************************/
582 // SDRAM I/F
583
584 reg sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n,
585 sdr_we_n;
586 reg [SDR_BW-1:0] sdr_dqm;
587 reg [1:0] sdr_ba;
588 reg [12:0] sdr_addr;
589 reg [SDR_DW-1:0] sdr_dout;
590 reg [SDR_BW-1:0] sdr_den_n;
591
592 always @ (posedge clk)
593 if (~reset_n) begin
594 sdr_cs_n <= 1'b1;
595 sdr_cke <= 1'b1;
596 sdr_ras_n <= 1'b1;
597 sdr_cas_n <= 1'b1;
598 sdr_we_n <= 1'b1;
599 sdr_dqm <= {SDR_BW{1'b1}};
600 sdr_den_n <= {SDR_BW{1'b1}};
601 end // if (~reset_n)
602 else begin
603 sdr_cs_n <= xfr_cmd[3];
604 sdr_ras_n <= xfr_cmd[2];
605 sdr_cas_n <= xfr_cmd[1];
606 sdr_we_n <= xfr_cmd[0];
607 // vish change: cke is kept high after initialization
608 // sdr_cke <= (xfr_st != `XFR_IDLE) ? 1'b1 :
609 // ~(mgmt_idle & b2x_idle & r2x_idle);
610 //
611 if(init_delay_done) begin
612 sdr_dqm <= (wr_next) ? a2x_wren_n : {SDR_BW{1'b0}};
613 sdr_cke <= 1'b1;
614 end
615 sdr_den_n <= (wr_next) ? {SDR_BW{1'b0}} : {SDR_BW{1'b1}};
616 end // else: !if(~reset_n)
617
618 always @ (posedge clk) begin
619
620 if (~xfr_cmd[3]) begin
621 sdr_addr <= xfr_addr;
622 sdr_ba <= xfr_ba;
623 end // if (~xfr_cmd[3])
624
625 sdr_dout <= (wr_next) ? a2x_wrdt : sdr_dout;
626
627
628 end // always @ (posedge clk)
629
630 /************************************************************************/
631 // Refresh and Initialization
632 //vish change : increased the MGM size and added one more state
633
634 `define MGM_INIT_DELAY 4'b0000
635 `define MGM_INIT_NOOP 4'b0001
636 `define MGM_POWERUP 4'b0010
637 `define MGM_PRECHARGE 4'b0011
638 `define MGM_PCHWT 4'b0100
639 `define MGM_REFRESH 4'b0101
640 `define MGM_REFWT 4'b0110
641 `define MGM_MODE_REG 4'b0111
642 `define MGM_MODE_WT 4'b1000
643 `define MGM_MODE_EXT_REG 4'b1001
644 `define MGM_MODE_EXT_WT 4'b1010
645 `define MGM_ACTIVE 4'b1011
646
647 reg [3:0] mgmt_st, next_mgmt_st;
648 reg [3:0] tmr0, tmr0_d;
649 reg [3:0] cntr1, cntr1_d;
650 wire tmr0_tc, cntr1_tc, rfsh_timer_tc, ref_req, precharge_ok;
651 reg ld_tmr0, ld_cntr1, dec_cntr1, set_sdr_init_done;
652 reg [`SDR_RFSH_TIMER_W-1 : 0] rfsh_timer;
653 reg [`SDR_RFSH_ROW_CNT_W-1:0] rfsh_row_cnt;
654
655 always @ (posedge clk)
656 if (~reset_n) begin
657 mgmt_st <= `MGM_POWERUP;
658 tmr0 <= 4'b0;
659 cntr1 <= 4'h7;
660 rfsh_timer <= 0;
661 rfsh_row_cnt <= 0;
662 sdr_init_done <= 1'b0;
663 end // if (~reset_n)
664 else begin
665 mgmt_st <= next_mgmt_st;
666 tmr0 <= (ld_tmr0) ? tmr0_d :
667 (~tmr0_tc) ? tmr0 - 1 : tmr0;
668 cntr1 <= (ld_cntr1) ? cntr1_d :
669 (dec_cntr1) ? cntr1 - 1 : cntr1;
670 sdr_init_done <= (set_sdr_init_done | sdr_init_done) & sdram_enable;
671 rfsh_timer <= (rfsh_timer_tc) ? 0 : rfsh_timer + 1;
672 rfsh_row_cnt <= (~set_sdr_init_done) ? 0 :
673 (rfsh_timer_tc) ? rfsh_row_cnt + 1 : rfsh_row_cnt;
674 end // else: !if(~reset_n)
675
676 assign tmr0_tc = ~|tmr0;
677
678 assign cntr1_tc = ~|cntr1;
679
680 assign rfsh_timer_tc = (rfsh_timer == rfsh_time) ? 1'b1 : 1'b0;
681
682 assign ref_req = (rfsh_row_cnt >= rfsh_rmax) ? 1'b1 : 1'b0;
683
684 assign precharge_ok = cb_pre_ok & b2x_tras_ok;
685
686 assign xfr_bank_sel = l_ba;
687
688
689 always @ (posedge clk) begin
690 if(~reset_n) begin
691 rg_initial_delay <= 0;
692 init_delay_done <= 0;
693 //sdram_mode_ext_reg <= 0;
694 end
695 else if(rg_initial_delay < 2048) begin
696 rg_initial_delay <= rg_initial_delay + 1;
697 init_delay_done <= 0;
698
699 // sdr_dqm <= {SDR_BW{1'b1}};
700 end
701 else begin
702 init_delay_done <= 1;
703 end
704 end
705
706 always@(posedge clk) begin
707 if(~reset_n) begin
708 mode_set <= 0;
709 end
710 else
711 mode_set <= wr_mode_set;
712 end
713
714 always @ (mgmt_st or sdram_enable or mgmt_ack or trp_delay or tmr0_tc or
715 cntr1_tc or trcar_delay or rfsh_row_cnt or ref_req or sdr_init_done
716 or precharge_ok or sdram_mode_reg or mode_set or init_delay_done) begin //added mode_set and sdram_mode_ext_reg in the sensitivity list. deleted sdram_mode_ext_reg
717
718 // always @ (posedge clk) begin
719 case (mgmt_st) // synopsys full_case parallel_case
720
721
722 `MGM_POWERUP : begin
723 mgmt_idle = 1'b0;
724 mgmt_req = 1'b0;
725 mgmt_cmd = `SDR_DESEL;
726 mgmt_ba = 2'b0;
727 mgmt_addr = 13'h400; // A10 = 1 => all banks
728 ld_tmr0 = 1'b0;
729 tmr0_d = 4'b0;
730 dec_cntr1 = 1'b0;
731 ld_cntr1 = 1'b1;
732 cntr1_d = 4'hf; // changed for sdrams with higher refresh cycles during initialization
733 set_sdr_init_done = 1'b0;
734 wr_mode_set = 1'b0;
735 next_mgmt_st = (sdram_enable) ? `MGM_INIT_DELAY : `MGM_POWERUP;
736 end // case: `MGM_POWERUP
737
738 `MGM_INIT_DELAY : begin // Precharge all banks
739 mgmt_idle = 1'b0;
740 set_sdr_init_done = 1'b0;
741 wr_mode_set = 1'b0;
742 mgmt_req = 0;
743 mgmt_cmd =`SDR_DESEL;
744 mgmt_ba = 2'bx;
745 mgmt_addr = 13'bx;
746 ld_tmr0 = 1'b0;
747 tmr0_d = 4'h0;
748 ld_cntr1 = 1'b0;
749 dec_cntr1 = 1'b0;
750 cntr1_d = 4'b0;
751 next_mgmt_st = (init_delay_done) ? `MGM_INIT_NOOP : `MGM_INIT_DELAY;
752 end // case: `MGM_INIT_DELAY
753
754 `MGM_INIT_NOOP : begin // Precharge all banks
755 mgmt_idle = 1'b0;
756 mgmt_req = 1'b1;
757 mgmt_cmd = `SDR_NOOP;
758 mgmt_ba = 2'b0;
759 mgmt_addr = 13'h400; // A10 = 1 => all banks
760 wr_mode_set = 1'b0;
761 ld_tmr0 = mgmt_ack;
762 tmr0_d = trp_delay;
763 ld_cntr1 = 1'b0;
764 cntr1_d = 4'h7;
765 dec_cntr1 = 1'b0;
766 set_sdr_init_done = 1'b0;
767 next_mgmt_st = (mgmt_ack) ? `MGM_PRECHARGE : `MGM_INIT_NOOP;
768 end // case: `MGM_INIT_DELAY
769
770 `MGM_PRECHARGE : begin // Precharge all banks
771 mgmt_idle = 1'b0;
772 mgmt_req = 1'b1;
773 mgmt_cmd = (precharge_ok) ? `SDR_PRECHARGE : `SDR_DESEL;
774 mgmt_ba = 2'b0;
775 mgmt_addr = 13'h400; // A10 = 1 => all banks
776 ld_tmr0 = mgmt_ack;
777 tmr0_d = trp_delay;
778 ld_cntr1 = 1'b0;
779 cntr1_d = 4'h7;
780 wr_mode_set = 1'b0;
781 dec_cntr1 = 1'b0;
782 set_sdr_init_done = 1'b0;
783 next_mgmt_st = (precharge_ok & mgmt_ack) ? `MGM_PCHWT : `MGM_PRECHARGE;
784 end // case: `MGM_PRECHARGE
785
786 `MGM_PCHWT : begin // Wait for Trp
787 mgmt_idle = 1'b0;
788 mgmt_req = 1'b1;
789 mgmt_cmd = `SDR_DESEL;
790 mgmt_ba = 2'b0;
791 mgmt_addr = 13'h400; // A10 = 1 => all banks
792 ld_tmr0 = 1'b0;
793 tmr0_d = trp_delay;
794 ld_cntr1 = 1'b0;
795 cntr1_d = 4'b0;
796 wr_mode_set = 1'b0;
797 dec_cntr1 = 1'b0;
798 set_sdr_init_done = 1'b0;
799 next_mgmt_st = (tmr0_tc) ? `MGM_REFRESH : `MGM_PCHWT;
800 end // case: `MGM_PRECHARGE
801
802 `MGM_REFRESH : begin // Refresh
803 mgmt_idle = 1'b0;
804 mgmt_req = 1'b1;
805 mgmt_cmd = `SDR_REFRESH;
806 mgmt_ba = 2'b0;
807 mgmt_addr = 13'h400; // A10 = 1 => all banks
808 ld_tmr0 = mgmt_ack;
809 tmr0_d = trcar_delay;
810 dec_cntr1 = mgmt_ack;
811 ld_cntr1 = 1'b0;
812 cntr1_d = 4'h7;
813 wr_mode_set = mode_set;
814 set_sdr_init_done = 1'b0;
815 next_mgmt_st = (mgmt_ack) ? `MGM_REFWT : `MGM_REFRESH;
816 end // case: `MGM_REFRESH
817
818 `MGM_REFWT : begin // Wait for trcar
819 mgmt_idle = 1'b0;
820 mgmt_req = 1'b1;
821 mgmt_cmd = `SDR_DESEL;
822 mgmt_ba = 2'b0;
823 mgmt_addr = 13'h400; // A10 = 1 => all banks
824 ld_tmr0 = 1'b0;
825 tmr0_d = trcar_delay;
826 dec_cntr1 = 1'b0;
827 ld_cntr1 = 1'b0;
828 wr_mode_set = mode_set;
829 cntr1_d = 4'h7;
830 set_sdr_init_done = 1'b0;
831 next_mgmt_st = (~tmr0_tc) ? `MGM_REFWT :
832 (~cntr1_tc) ? `MGM_REFRESH :
833 (sdr_init_done) ? `MGM_ACTIVE : (mode_set) ? `MGM_ACTIVE : `MGM_MODE_REG;
834 end // case: `MGM_REFWT
835
836 `MGM_MODE_REG : begin // Program mode Register & wait for
837 mgmt_idle = 1'b0;
838 mgmt_req = 1'b1;
839 mgmt_cmd = `SDR_MODE;
840 mgmt_ba = {1'b0, sdram_mode_reg[11]};
841 mgmt_addr = sdram_mode_reg;
842 ld_tmr0 = mgmt_ack;
843 tmr0_d = 4'h7;
844 dec_cntr1 = 1'b0;
845 ld_cntr1 = 1'b0;
846 wr_mode_set = 1'b0;
847 cntr1_d = 4'h7;
848 set_sdr_init_done = 1'b0;
849 next_mgmt_st = (mgmt_ack) ? `MGM_MODE_WT : `MGM_MODE_REG;
850 end // case: `MGM_MODE_REG
851
852 `MGM_MODE_WT : begin // Wait for tMRD
853 mgmt_idle = 1'b0;
854 mgmt_req = 1'b1;
855 mgmt_cmd = `SDR_DESEL;
856 mgmt_ba = 2'bx;
857 mgmt_addr = 13'bx;
858 ld_tmr0 = 1'b0;
859 tmr0_d = 4'h7;
860 dec_cntr1 = 1'b0;
861 ld_cntr1 = 1'b0;
862 cntr1_d = 4'h7;
863 wr_mode_set = 1'b0;
864 set_sdr_init_done = 1'b0;
865 next_mgmt_st = (~tmr0_tc) ? `MGM_MODE_WT : `MGM_MODE_EXT_REG;
866 end // case: `MGM_MODE_WT
867
868 `MGM_MODE_EXT_REG : begin // Program mode Register & wait for
869 mgmt_idle = 1'b0;
870 mgmt_req = 1'b1;
871 mgmt_cmd = `SDR_MODE;
872 mgmt_ba = 2'b10;
873 mgmt_addr = 0;//sdram_mode_ext_reg;
874 ld_tmr0 = mgmt_ack;
875 tmr0_d = 4'h7;
876 dec_cntr1 = 1'b0;
877 ld_cntr1 = 1'b0;
878 wr_mode_set = 1'b0;
879 cntr1_d = 4'h7;
880 set_sdr_init_done = 1'b0;
881 next_mgmt_st = (mgmt_ack) ? `MGM_MODE_EXT_WT : `MGM_MODE_EXT_REG;
882 end // case: `MGM_MODE_EXT_REG
883
884 `MGM_MODE_EXT_WT : begin // Wait for tMRD
885 mgmt_idle = 1'b0;
886 mgmt_req = 1'b1;
887 mgmt_cmd = `SDR_DESEL;
888 mgmt_ba = 2'bx;
889 mgmt_addr = 13'bx;
890 ld_tmr0 = 1'b0;
891 tmr0_d = 4'h7;
892 dec_cntr1 = 1'b0;
893 ld_cntr1 = 1'b0;
894 cntr1_d = 4'h7;
895 wr_mode_set = 1'b1;
896 set_sdr_init_done = 1'b0;
897 next_mgmt_st = (~tmr0_tc) ? `MGM_MODE_EXT_WT : `MGM_REFRESH;
898 end // case: `MGM_MODE_WT
899
900 `MGM_ACTIVE : begin // Wait for ref_req
901 mgmt_idle = ~ref_req;
902 mgmt_req = 1'b0;
903 mgmt_cmd = `SDR_DESEL;
904 mgmt_ba = 2'bx;
905 mgmt_addr = 13'bx;
906 ld_tmr0 = 1'b0;
907 tmr0_d = 4'h7;
908 dec_cntr1 = 1'b0;
909 ld_cntr1 = ref_req;
910 wr_mode_set = 1'b0;
911 cntr1_d = rfsh_row_cnt;
912 set_sdr_init_done = 1'b1;
913 next_mgmt_st = (~sdram_enable) ? `MGM_POWERUP :
914 (ref_req) ? `MGM_PRECHARGE : `MGM_ACTIVE;
915 end // case: `MGM_MODE_WT
916 default: begin
917 mgmt_idle = 0;
918 mgmt_req = 0;
919 mgmt_cmd =`SDR_DESEL;
920 mgmt_ba = 2'bx;
921 mgmt_addr = 13'bx;
922 ld_tmr0 = 1'b0;
923 tmr0_d = 4'h0;
924 wr_mode_set = 0;
925 ld_cntr1 = 1'b0;
926 dec_cntr1 = 1'b0;
927 cntr1_d = 4'b0;
928 set_sdr_init_done = 1'b0;
929 next_mgmt_st = `MGM_POWERUP;
930
931 end // case: default
932
933 endcase // case(mgmt_st)
934
935 end // always @ (mgmt_st or ....)
936
937
938
939 endmodule // sdr_xfr_ctl