OpenCores
URL https://opencores.org/ocsvn/sdr_ctrl/sdr_ctrl/trunk

Subversion Repositories sdr_ctrl

[/] [sdr_ctrl/] [trunk/] [rtl/] [core/] [sdrc_xfr_ctl.v] - Blame information for rev 55

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 dinesha
/*********************************************************************
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 37 dinesha
`include "sdrc_define.v"
65 3 dinesha
 
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 45 dinesha
                    a2x_wrdt,
111
                    a2x_wren_n,
112 3 dinesha
                    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
parameter  SDR_DW   = 16;  // SDR Data Width 
133
parameter  SDR_BW   = 2;   // SDR Byte Width
134
 
135
 
136
input            clk, reset_n;
137
 
138
   /* Req from bank_ctl */
139
input                   b2x_req, b2x_start, b2x_last, b2x_tras_ok,
140
                                b2x_wrap, r2x_idle, b2x_idle;
141
input [`SDR_REQ_ID_W-1:0]        b2x_id;
142
input [1:0]                      b2x_ba;
143
input [11:0]             b2x_addr;
144 54 dinesha
input [`REQ_BW-1:0]      b2x_len;
145 3 dinesha
input [1:0]                      b2x_cmd;
146
output                  x2b_ack;
147
 
148
/* Status to bank_ctl */
149
output [3:0]             x2b_pre_ok;
150
output                  x2b_refresh, x2b_act_ok, x2b_rdok,
151
                                x2b_wrok;
152
/* Data Flow to the app */
153
output                  x2a_rdstart, x2a_wrstart, x2a_rdlast, x2a_wrlast;
154
output [`SDR_REQ_ID_W-1:0]       x2a_id;
155
 
156 45 dinesha
input [SDR_DW-1:0]       a2x_wrdt;
157
input [SDR_BW-1:0]       a2x_wren_n;
158 3 dinesha
output [SDR_DW-1:0]      x2a_rddt;
159
output                  x2a_wrnext, x2a_rdok, sdr_init_done;
160
 
161
/* Interface to SDRAMs */
162
output                  sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n,
163
                                sdr_we_n;
164
output [SDR_BW-1:0]      sdr_dqm;
165
output [1:0]             sdr_ba;
166
output [11:0]            sdr_addr;
167
input [SDR_DW-1:0]       sdr_din;
168
output [SDR_DW-1:0]      sdr_dout;
169
output [SDR_BW-1:0]      sdr_den_n;
170
 
171
   output [1:0]                  xfr_bank_sel;
172
 
173
   input                        sdram_enable;
174
   input [11:0]          sdram_mode_reg;
175
   input [2:0]                   cas_latency;
176
   input [3:0]                   trp_delay, trcar_delay, twr_delay;
177
   input [`SDR_RFSH_TIMER_W-1 : 0] rfsh_time;
178
   input [`SDR_RFSH_ROW_CNT_W-1:0] rfsh_rmax;
179
 
180
 
181
   /************************************************************************/
182
   // Internal Nets
183
 
184
   `define XFR_IDLE        2'b00
185
   `define XFR_WRITE       2'b01
186
   `define XFR_READ        2'b10
187
   `define XFR_RDWT        2'b11
188
 
189
   reg [1:0]                     xfr_st, next_xfr_st;
190
   reg [11:0]                    xfr_caddr;
191
   wire                         last_burst;
192
   wire                         x2a_rdstart, x2a_wrstart, x2a_rdlast, x2a_wrlast;
193
   reg                          l_start, l_last, l_wrap;
194
   wire [`SDR_REQ_ID_W-1:0]      x2a_id;
195
   reg [`SDR_REQ_ID_W-1:0]       l_id;
196
   wire [1:0]                    xfr_ba;
197
   reg [1:0]                     l_ba;
198
   wire [11:0]                   xfr_addr;
199 54 dinesha
   wire [`REQ_BW-1:0]    xfr_len, next_xfr_len;
200
   reg [`REQ_BW-1:0]     l_len;
201 3 dinesha
 
202
   reg                          mgmt_idle, mgmt_req;
203
   reg [3:0]                     mgmt_cmd;
204
   reg [11:0]                    mgmt_addr;
205
   reg [1:0]                     mgmt_ba;
206
 
207
   reg                          sel_mgmt, sel_b2x;
208
   reg                          cb_pre_ok, rdok, wrok, wr_next,
209
                                rd_next, sdr_init_done, act_cmd, d_act_cmd;
210
   wire [3:0]                    b2x_sdr_cmd, xfr_cmd;
211
   reg [3:0]                     i_xfr_cmd;
212
   wire                         mgmt_ack, x2b_ack, b2x_read, b2x_write,
213
                                b2x_prechg, d_rd_next, dt_next, xfr_end,
214
                                rd_pipe_mt, ld_xfr, rd_last, d_rd_last,
215
                                wr_last, l_xfr_end, rd_start, d_rd_start,
216
                                wr_start, page_hit, burst_bdry, xfr_wrap,
217
                                b2x_prechg_hit;
218
   reg [4:0]                     l_rd_next, l_rd_start, l_rd_last;
219
 
220
   assign b2x_read = (b2x_cmd == `OP_RD) ? 1'b1 : 1'b0;
221
 
222
   assign b2x_write = (b2x_cmd == `OP_WR) ? 1'b1 : 1'b0;
223
 
224
   assign b2x_prechg = (b2x_cmd == `OP_PRE) ? 1'b1 : 1'b0;
225
 
226
   assign b2x_sdr_cmd = (b2x_cmd == `OP_PRE) ? `SDR_PRECHARGE :
227
                        (b2x_cmd == `OP_ACT) ? `SDR_ACTIVATE :
228
                        (b2x_cmd == `OP_RD) ? `SDR_READ :
229
                        (b2x_cmd == `OP_WR) ? `SDR_WRITE : `SDR_DESEL;
230
 
231
   assign page_hit = (b2x_ba == l_ba) ? 1'b1 : 1'b0;
232
 
233
   assign b2x_prechg_hit = b2x_prechg & page_hit;
234
 
235
   assign xfr_cmd = (sel_mgmt) ? mgmt_cmd :
236
                    (sel_b2x) ? b2x_sdr_cmd : i_xfr_cmd;
237
 
238
   assign xfr_addr = (sel_mgmt) ? mgmt_addr :
239 51 dinesha
                     (sel_b2x) ? b2x_addr : xfr_caddr+1;
240 3 dinesha
 
241
   assign mgmt_ack = sel_mgmt;
242
 
243
   assign x2b_ack = sel_b2x;
244
 
245
   assign ld_xfr = sel_b2x & (b2x_read | b2x_write);
246
 
247
   assign xfr_len = (ld_xfr) ? b2x_len : l_len;
248
 
249 51 dinesha
   //assign next_xfr_len = (l_xfr_end && !ld_xfr) ? l_len : xfr_len - 1;
250
   assign next_xfr_len = (ld_xfr) ? b2x_len :
251
                         (l_xfr_end) ? l_len:  l_len - 1;
252 3 dinesha
 
253
   assign d_rd_next = (cas_latency == 2'b01) ? l_rd_next[2] :
254
                      (cas_latency == 2'b10) ? l_rd_next[3] :
255
                      l_rd_next[4];
256
 
257
   assign d_rd_last = (cas_latency == 2'b01) ? l_rd_last[2] :
258
                      (cas_latency == 2'b10) ? l_rd_last[3] :
259
                      l_rd_last[4];
260
 
261
   assign d_rd_start = (cas_latency == 2'b01) ? l_rd_start[2] :
262
                      (cas_latency == 2'b10) ? l_rd_start[3] :
263
                      l_rd_start[4];
264
 
265
   assign rd_pipe_mt = (cas_latency == 2'b01) ? ~|l_rd_next[1:0] :
266
                       (cas_latency == 2'b10) ? ~|l_rd_next[2:0] :
267
                       ~|l_rd_next[3:0];
268
 
269
   assign dt_next = wr_next | d_rd_next;
270
 
271
   assign xfr_end = ~|xfr_len;
272
 
273 51 dinesha
   assign l_xfr_end = ~|(l_len-1);
274 3 dinesha
 
275
   assign rd_start = ld_xfr & b2x_read & b2x_start;
276
 
277
   assign wr_start = ld_xfr & b2x_write & b2x_start;
278
 
279 54 dinesha
   assign rd_last = rd_next & last_burst & ~|xfr_len[`REQ_BW-1:1];
280 3 dinesha
 
281
   //assign wr_last = wr_next & last_burst & ~|xfr_len[APP_RW-1:1];
282
 
283 54 dinesha
   assign wr_last = last_burst & ~|xfr_len[`REQ_BW-1:1];
284 3 dinesha
 
285
   //assign xfr_ba = (ld_xfr) ? b2x_ba : l_ba;
286
   assign xfr_ba = (sel_mgmt) ? mgmt_ba :
287
                   (sel_b2x) ? b2x_ba : l_ba;
288
 
289
   assign xfr_wrap = (ld_xfr) ? b2x_wrap : l_wrap;
290
 
291
//   assign burst_bdry = ~|xfr_caddr[2:0];
292 51 dinesha
   wire [1:0] xfr_caddr_lsb = (xfr_caddr[1:0]+1);
293
   assign burst_bdry = ~|(xfr_caddr_lsb[1:0]);
294
 
295 3 dinesha
   always @ (posedge clk) begin
296
      if (~reset_n) begin
297
         xfr_caddr <= 12'b0;
298
         l_start <= 1'b0;
299
         l_last <= 1'b0;
300
         l_wrap <= 1'b0;
301
         l_id <= 0;
302
         l_ba <= 0;
303
         l_len <= 0;
304
         l_rd_next <= 5'b0;
305
         l_rd_start <= 5'b0;
306
         l_rd_last <= 5'b0;
307
         act_cmd <= 1'b0;
308
         d_act_cmd <= 1'b0;
309
         xfr_st <= `XFR_IDLE;
310
      end // if (~reset_n)
311
 
312
      else begin
313 51 dinesha
         xfr_caddr <= (ld_xfr) ? b2x_addr :
314
                      (rd_next | wr_next) ? xfr_caddr + 1 : xfr_caddr;
315 3 dinesha
         l_start <= (dt_next) ? 1'b0 :
316
                   (ld_xfr) ? b2x_start : l_start;
317
         l_last <= (ld_xfr) ? b2x_last : l_last;
318
         l_wrap <= (ld_xfr) ? b2x_wrap : l_wrap;
319
         l_id <= (ld_xfr) ? b2x_id : l_id;
320
         l_ba <= (ld_xfr) ? b2x_ba : l_ba;
321
         l_len <= next_xfr_len;
322
         l_rd_next <= {l_rd_next[3:0], rd_next};
323
         l_rd_start <= {l_rd_start[3:0], rd_start};
324
         l_rd_last <= {l_rd_last[3:0], rd_last};
325
         act_cmd <= (xfr_cmd == `SDR_ACTIVATE) ? 1'b1 : 1'b0;
326
         d_act_cmd <= act_cmd;
327
         xfr_st <= next_xfr_st;
328
      end // else: !if(~reset_n)
329
 
330
   end // always @ (posedge clk)
331
 
332
 
333
   always @ (*) begin
334
      case (xfr_st)
335
 
336
        `XFR_IDLE : begin
337
 
338
           sel_mgmt = mgmt_req;
339
           sel_b2x = ~mgmt_req & sdr_init_done & b2x_req;
340
           i_xfr_cmd = `SDR_DESEL;
341
           rd_next = ~mgmt_req & sdr_init_done & b2x_req & b2x_read;
342
           wr_next = ~mgmt_req & sdr_init_done & b2x_req & b2x_write;
343
           rdok = ~mgmt_req;
344
           cb_pre_ok = 1'b1;
345
           wrok = ~mgmt_req;
346
           next_xfr_st = (mgmt_req | ~sdr_init_done) ? `XFR_IDLE :
347
                         (~b2x_req) ? `XFR_IDLE :
348
                         (b2x_read) ? `XFR_READ :
349
                         (b2x_write) ? `XFR_WRITE : `XFR_IDLE;
350
 
351
        end // case: `XFR_IDLE
352
 
353
        `XFR_READ : begin
354
           rd_next = ~l_xfr_end |
355
                     l_xfr_end & ~mgmt_req & b2x_req & b2x_read;
356
           wr_next = 1'b0;
357
           rdok = l_xfr_end & ~mgmt_req;
358 51 dinesha
           // Break the timing path for FPGA Based Design
359
           cb_pre_ok = (`TARGET_DESIGN == `FPGA) ? 1'b0 : l_xfr_end;
360 3 dinesha
           wrok = 1'b0;
361
           sel_mgmt = 1'b0;
362
 
363
           if (l_xfr_end) begin           // end of transfer
364
 
365
              if (~l_wrap) begin
366
                 // Current transfer was not wrap mode, may need BT
367
                 // If next cmd is a R or W or PRE to same bank allow
368
                 // it else issue BT 
369
                 // This is a little pessimistic since BT is issued
370
                 // for non-wrap mode transfers even if the transfer
371
                 // ends on a burst boundary, but is felt to be of
372
                 // minimal performance impact.
373
 
374
                 i_xfr_cmd = `SDR_BT;
375
                 sel_b2x = b2x_req & ~mgmt_req & (b2x_read | b2x_prechg_hit);
376
 
377
              end // if (~l_wrap)
378
 
379
              else begin
380
                 // Wrap mode transfer, by definition is end of burst
381
                 // boundary 
382
 
383
                 i_xfr_cmd = `SDR_DESEL;
384
                 sel_b2x = b2x_req & ~mgmt_req & ~b2x_write;
385
 
386
              end // else: !if(~l_wrap)
387
 
388
              next_xfr_st = (sdr_init_done) ? ((b2x_req & ~mgmt_req & b2x_read) ? `XFR_READ : `XFR_RDWT) : `XFR_IDLE;
389
 
390
           end // if (l_xfr_end)
391
 
392
           else begin
393
              // Not end of transfer
394
              // If current transfer was not wrap mode and we are at
395
              // the start of a burst boundary issue another R cmd to
396
              // step sequemtially thru memory, ELSE,
397
              // issue precharge/activate commands from the bank control
398
 
399
              i_xfr_cmd = (burst_bdry & ~l_wrap) ? `SDR_READ : `SDR_DESEL;
400
              sel_b2x = ~(burst_bdry & ~l_wrap) & b2x_req;
401
              next_xfr_st = `XFR_READ;
402
 
403
           end // else: !if(l_xfr_end)
404
 
405
        end // case: `XFR_READ
406
 
407
        `XFR_RDWT : begin
408
           rd_next = ~mgmt_req & b2x_req & b2x_read;
409
           wr_next = rd_pipe_mt & ~mgmt_req & b2x_req & b2x_write;
410
           rdok = ~mgmt_req;
411
           cb_pre_ok = 1'b1;
412
           wrok = rd_pipe_mt & ~mgmt_req;
413
 
414
           sel_mgmt = mgmt_req;
415
 
416
           sel_b2x = ~mgmt_req & b2x_req;
417
 
418
           i_xfr_cmd = `SDR_DESEL;
419
 
420
           next_xfr_st = (~mgmt_req & b2x_req & b2x_read) ? `XFR_READ :
421
                         (~rd_pipe_mt) ? `XFR_RDWT :
422
                         (~mgmt_req & b2x_req & b2x_write) ? `XFR_WRITE :
423
                         `XFR_IDLE;
424
 
425
        end // case: `XFR_RDWT
426
 
427
        `XFR_WRITE : begin
428
           rd_next = l_xfr_end & ~mgmt_req & b2x_req & b2x_read;
429
           wr_next = ~l_xfr_end |
430
                     l_xfr_end & ~mgmt_req & b2x_req & b2x_write;
431
           rdok = l_xfr_end & ~mgmt_req;
432
           cb_pre_ok = 1'b0;
433
           wrok = l_xfr_end & ~mgmt_req;
434
           sel_mgmt = 1'b0;
435
 
436
           if (l_xfr_end) begin           // End of transfer
437
 
438
              if (~l_wrap) begin
439
                 // Current transfer was not wrap mode, may need BT
440
                 // If next cmd is a R or W allow it else issue BT 
441
                 // This is a little pessimistic since BT is issued
442
                 // for non-wrap mode transfers even if the transfer
443
                 // ends on a burst boundary, but is felt to be of
444
                 // minimal performance impact.
445
 
446
 
447
                 sel_b2x = b2x_req & ~mgmt_req & (b2x_read | b2x_write);
448
                 i_xfr_cmd = `SDR_BT;
449
              end // if (~l_wrap)
450
 
451
              else begin
452
                 // Wrap mode transfer, by definition is end of burst
453
                 // boundary 
454
 
455
                 sel_b2x = b2x_req & ~mgmt_req & ~b2x_prechg_hit;
456
                 i_xfr_cmd = `SDR_DESEL;
457
              end // else: !if(~l_wrap)
458
 
459
              next_xfr_st = (~mgmt_req & b2x_req & b2x_read) ? `XFR_READ :
460
                            (~mgmt_req & b2x_req & b2x_write) ? `XFR_WRITE :
461
                            `XFR_IDLE;
462
 
463
           end // if (l_xfr_end)
464
 
465
           else begin
466
              // Not end of transfer
467
              // If current transfer was not wrap mode and we are at
468
              // the start of a burst boundary issue another R cmd to
469
              // step sequemtially thru memory, ELSE,
470
              // issue precharge/activate commands from the bank control
471
 
472
              if (burst_bdry & ~l_wrap) begin
473
                 sel_b2x = 1'b0;
474
                 i_xfr_cmd = `SDR_WRITE;
475
              end // if (burst_bdry & ~l_wrap)
476
 
477
              else begin
478
                 sel_b2x = b2x_req & ~mgmt_req;
479
                 i_xfr_cmd = `SDR_DESEL;
480
              end // else: !if(burst_bdry & ~l_wrap)
481
 
482
              next_xfr_st = `XFR_WRITE;
483
           end // else: !if(l_xfr_end)
484
 
485
        end // case: `XFR_WRITE
486
 
487
      endcase // case(xfr_st)
488
 
489
   end // always @ (xfr_st or ...)
490
 
491
   // signals to bank_ctl (x2b_refresh, x2b_act_ok, x2b_rdok, x2b_wrok,
492
   // x2b_pre_ok[3:0] 
493
 
494
   assign x2b_refresh = (xfr_cmd == `SDR_REFRESH) ? 1'b1 : 1'b0;
495
 
496
   assign x2b_act_ok = ~act_cmd & ~d_act_cmd;
497
 
498
   assign x2b_rdok = rdok;
499
 
500
   assign x2b_wrok = wrok;
501
 
502 51 dinesha
   //assign x2b_pre_ok[0] = (l_ba == 2'b00) ? cb_pre_ok : 1'b1;
503
   //assign x2b_pre_ok[1] = (l_ba == 2'b01) ? cb_pre_ok : 1'b1;
504
   //assign x2b_pre_ok[2] = (l_ba == 2'b10) ? cb_pre_ok : 1'b1;
505
   //assign x2b_pre_ok[3] = (l_ba == 2'b11) ? cb_pre_ok : 1'b1;
506 3 dinesha
 
507 51 dinesha
   assign x2b_pre_ok[0] = cb_pre_ok;
508
   assign x2b_pre_ok[1] = cb_pre_ok;
509
   assign x2b_pre_ok[2] = cb_pre_ok;
510
   assign x2b_pre_ok[3] = cb_pre_ok;
511 3 dinesha
   assign last_burst = (ld_xfr) ? b2x_last : l_last;
512
 
513
   /************************************************************************/
514
   // APP Data I/F
515
 
516
   wire [SDR_DW-1:0]     x2a_rddt;
517
 
518
   //assign x2a_start = (ld_xfr) ? b2x_start : l_start;
519
   assign x2a_rdstart = d_rd_start;
520
   assign x2a_wrstart = wr_start;
521
 
522
   assign x2a_rdlast = d_rd_last;
523
   assign x2a_wrlast = wr_last;
524
 
525
   assign x2a_id = (ld_xfr) ? b2x_id : l_id;
526
 
527
   assign x2a_rddt = sdr_din;
528
 
529
   assign x2a_wrnext = wr_next;
530
 
531
   assign x2a_rdok = d_rd_next;
532
 
533
   /************************************************************************/
534
   // SDRAM I/F
535
 
536
   reg                          sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n,
537
                                sdr_we_n;
538
   reg [SDR_BW-1:0]      sdr_dqm;
539
   reg [1:0]                     sdr_ba;
540
   reg [11:0]                    sdr_addr;
541
   reg [SDR_DW-1:0]      sdr_dout;
542
   reg [SDR_BW-1:0]      sdr_den_n;
543
 
544
   always @ (posedge clk)
545
      if (~reset_n) begin
546
         sdr_cs_n <= 1'b1;
547
         sdr_cke <= 1'b1;
548
         sdr_ras_n <= 1'b1;
549
         sdr_cas_n <= 1'b1;
550
         sdr_we_n <= 1'b1;
551 36 dinesha
         sdr_dqm   <= {SDR_BW{1'b1}};
552 37 dinesha
         sdr_den_n <= {SDR_BW{1'b1}};
553 3 dinesha
      end // if (~reset_n)
554
      else begin
555
         sdr_cs_n <= xfr_cmd[3];
556
         sdr_ras_n <= xfr_cmd[2];
557
         sdr_cas_n <= xfr_cmd[1];
558
         sdr_we_n <= xfr_cmd[0];
559
         sdr_cke <= (xfr_st != `XFR_IDLE) ? 1'b1 :
560
                    ~(mgmt_idle & b2x_idle & r2x_idle);
561 45 dinesha
         sdr_dqm <= (wr_next) ? a2x_wren_n : {SDR_BW{1'b0}};
562 3 dinesha
         sdr_den_n <= (wr_next) ? {SDR_BW{1'b0}} : {SDR_BW{1'b1}};
563
      end // else: !if(~reset_n)
564
 
565
   always @ (posedge clk) begin
566
 
567
      if (~xfr_cmd[3]) begin
568
         sdr_addr <= xfr_addr;
569
         sdr_ba <= xfr_ba;
570
      end // if (~xfr_cmd[3])
571
 
572 45 dinesha
      sdr_dout <= (wr_next) ? a2x_wrdt : sdr_dout;
573 3 dinesha
 
574
   end // always @ (posedge clk)
575
 
576
   /************************************************************************/
577
   // Refresh and Initialization
578
 
579
   `define MGM_POWERUP         3'b000
580
   `define MGM_PRECHARGE    3'b001
581
   `define MGM_PCHWT        3'b010
582
   `define MGM_REFRESH      3'b011
583
   `define MGM_REFWT        3'b100
584
   `define MGM_MODE_REG     3'b101
585
   `define MGM_MODE_WT      3'b110
586
   `define MGM_ACTIVE       3'b111
587
 
588
   reg [2:0]       mgmt_st, next_mgmt_st;
589
   reg [3:0]        tmr0, tmr0_d;
590
   reg [3:0]        cntr1, cntr1_d;
591
   wire            tmr0_tc, cntr1_tc, rfsh_timer_tc, ref_req, precharge_ok;
592
   reg             ld_tmr0, ld_cntr1, dec_cntr1, set_sdr_init_done;
593
   reg [`SDR_RFSH_TIMER_W-1 : 0]  rfsh_timer;
594
   reg [`SDR_RFSH_ROW_CNT_W-1:0]  rfsh_row_cnt;
595
 
596
   always @ (posedge clk)
597
      if (~reset_n) begin
598
         mgmt_st <= `MGM_POWERUP;
599
         tmr0 <= 4'b0;
600
         cntr1 <= 4'h7;
601
         rfsh_timer <= 0;
602
         rfsh_row_cnt <= 0;
603
         sdr_init_done <= 1'b0;
604
      end // if (~reset_n)
605
      else begin
606
         mgmt_st <= next_mgmt_st;
607
         tmr0 <= (ld_tmr0) ? tmr0_d :
608
                  (~tmr0_tc) ? tmr0 - 1 : tmr0;
609
         cntr1 <= (ld_cntr1) ? cntr1_d :
610
                  (dec_cntr1) ? cntr1 - 1 : cntr1;
611
         sdr_init_done <= (set_sdr_init_done | sdr_init_done) & sdram_enable;
612
         rfsh_timer <= (rfsh_timer_tc) ? 0 : rfsh_timer + 1;
613
         rfsh_row_cnt <= (~set_sdr_init_done) ? 0 :
614
                         (rfsh_timer_tc) ? rfsh_row_cnt + 1 : rfsh_row_cnt;
615
      end // else: !if(~reset_n)
616
 
617
   assign tmr0_tc = ~|tmr0;
618
 
619
   assign cntr1_tc = ~|cntr1;
620
 
621
   assign rfsh_timer_tc = (rfsh_timer == rfsh_time) ? 1'b1 : 1'b0;
622
 
623
   assign ref_req = (rfsh_row_cnt >= rfsh_rmax) ? 1'b1 : 1'b0;
624
 
625
   assign precharge_ok = cb_pre_ok & b2x_tras_ok;
626
 
627
   assign xfr_bank_sel = l_ba;
628
 
629
   always @ (mgmt_st or sdram_enable or mgmt_ack or trp_delay or tmr0_tc or
630
             cntr1_tc or trcar_delay or rfsh_row_cnt or ref_req or sdr_init_done
631
             or precharge_ok or sdram_mode_reg) begin
632
 
633
      case (mgmt_st)          // synopsys full_case parallel_case
634
 
635
        `MGM_POWERUP : begin
636
           mgmt_idle = 1'b0;
637
           mgmt_req = 1'b0;
638
           mgmt_cmd = `SDR_DESEL;
639
           mgmt_ba = 2'b0;
640
           mgmt_addr = 12'h400;    // A10 = 1 => all banks
641
           ld_tmr0 = 1'b0;
642
           tmr0_d = 4'b0;
643
           dec_cntr1 = 1'b0;
644
           ld_cntr1 = 1'b1;
645
           cntr1_d = 4'hf; // changed for sdrams with higher refresh cycles during initialization
646
           set_sdr_init_done = 1'b0;
647
           next_mgmt_st = (sdram_enable) ? `MGM_PRECHARGE : `MGM_POWERUP;
648
        end // case: `MGM_POWERUP
649
 
650
        `MGM_PRECHARGE : begin     // Precharge all banks
651
           mgmt_idle = 1'b0;
652
           mgmt_req = 1'b1;
653
           mgmt_cmd = (precharge_ok) ? `SDR_PRECHARGE : `SDR_DESEL;
654
           mgmt_ba = 2'b0;
655
           mgmt_addr = 12'h400;    // A10 = 1 => all banks
656
           ld_tmr0 = mgmt_ack;
657
           tmr0_d = trp_delay;
658
           ld_cntr1 = 1'b0;
659
           cntr1_d = 4'h7;
660
           dec_cntr1 = 1'b0;
661
           set_sdr_init_done = 1'b0;
662
           next_mgmt_st = (precharge_ok & mgmt_ack) ? `MGM_PCHWT : `MGM_PRECHARGE;
663
        end // case: `MGM_PRECHARGE
664
 
665
        `MGM_PCHWT : begin         // Wait for Trp
666
           mgmt_idle = 1'b0;
667
           mgmt_req = 1'b1;
668
           mgmt_cmd = `SDR_DESEL;
669
           mgmt_ba = 2'b0;
670
           mgmt_addr = 12'h400;    // A10 = 1 => all banks
671
           ld_tmr0 = 1'b0;
672
           tmr0_d = trp_delay;
673
           ld_cntr1 = 1'b0;
674
           cntr1_d = 4'b0;
675
           dec_cntr1 = 1'b0;
676
           set_sdr_init_done = 1'b0;
677
           next_mgmt_st = (tmr0_tc) ? `MGM_REFRESH : `MGM_PCHWT;
678
        end // case: `MGM_PRECHARGE
679
 
680
        `MGM_REFRESH : begin       // Refresh
681
           mgmt_idle = 1'b0;
682
           mgmt_req = 1'b1;
683
           mgmt_cmd = `SDR_REFRESH;
684
           mgmt_ba = 2'b0;
685
           mgmt_addr = 12'h400;    // A10 = 1 => all banks
686
           ld_tmr0 = mgmt_ack;
687
           tmr0_d = trcar_delay;
688
           dec_cntr1 = mgmt_ack;
689
           ld_cntr1 = 1'b0;
690
           cntr1_d = 4'h7;
691
           set_sdr_init_done = 1'b0;
692
           next_mgmt_st = (mgmt_ack) ? `MGM_REFWT : `MGM_REFRESH;
693
        end // case: `MGM_REFRESH
694
 
695
        `MGM_REFWT : begin         // Wait for trcar
696
           mgmt_idle = 1'b0;
697
           mgmt_req = 1'b1;
698
           mgmt_cmd = `SDR_DESEL;
699
           mgmt_ba = 2'b0;
700
           mgmt_addr = 12'h400;    // A10 = 1 => all banks
701
           ld_tmr0 = 1'b0;
702
           tmr0_d = trcar_delay;
703
           dec_cntr1 = 1'b0;
704
           ld_cntr1 = 1'b0;
705
           cntr1_d = 4'h7;
706
           set_sdr_init_done = 1'b0;
707
           next_mgmt_st = (~tmr0_tc) ? `MGM_REFWT :
708
                          (~cntr1_tc) ? `MGM_REFRESH :
709
                          (sdr_init_done) ? `MGM_ACTIVE : `MGM_MODE_REG;
710
        end // case: `MGM_REFWT
711
 
712
        `MGM_MODE_REG : begin      // Program mode Register & wait for 
713
           mgmt_idle = 1'b0;
714
           mgmt_req = 1'b1;
715
           mgmt_cmd = `SDR_MODE;
716
           mgmt_ba = {1'b0, sdram_mode_reg[11]};
717
           mgmt_addr = sdram_mode_reg;
718
           ld_tmr0 = mgmt_ack;
719
           tmr0_d = 4'h7;
720
           dec_cntr1 = 1'b0;
721
           ld_cntr1 = 1'b0;
722
           cntr1_d = 4'h7;
723
           set_sdr_init_done = 1'b0;
724
           next_mgmt_st = (mgmt_ack) ? `MGM_MODE_WT : `MGM_MODE_REG;
725
        end // case: `MGM_MODE_REG
726
 
727
        `MGM_MODE_WT : begin       // Wait for tMRD
728
           mgmt_idle = 1'b0;
729
           mgmt_req = 1'b1;
730
           mgmt_cmd = `SDR_DESEL;
731
           mgmt_ba = 2'bx;
732
           mgmt_addr = 12'bx;
733
           ld_tmr0 = 1'b0;
734
           tmr0_d = 4'h7;
735
           dec_cntr1 = 1'b0;
736
           ld_cntr1 = 1'b0;
737
           cntr1_d = 4'h7;
738
           set_sdr_init_done = 1'b0;
739
           next_mgmt_st = (~tmr0_tc) ? `MGM_MODE_WT : `MGM_ACTIVE;
740
        end // case: `MGM_MODE_WT
741
 
742
        `MGM_ACTIVE : begin        // Wait for ref_req
743
           mgmt_idle = ~ref_req;
744
           mgmt_req = 1'b0;
745
           mgmt_cmd = `SDR_DESEL;
746
           mgmt_ba = 2'bx;
747
           mgmt_addr = 12'bx;
748
           ld_tmr0 = 1'b0;
749
           tmr0_d = 4'h7;
750
           dec_cntr1 = 1'b0;
751
           ld_cntr1 = ref_req;
752
           cntr1_d = rfsh_row_cnt;
753
           set_sdr_init_done = 1'b1;
754
           next_mgmt_st =  (~sdram_enable) ? `MGM_POWERUP :
755
                           (ref_req) ? `MGM_PRECHARGE : `MGM_ACTIVE;
756
        end // case: `MGM_MODE_WT
757
 
758
      endcase // case(mgmt_st)
759
 
760
   end // always @ (mgmt_st or ....)
761
 
762
 
763
 
764
endmodule // sdr_xfr_ctl

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.