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 11

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

powered by: WebSVN 2.1.0

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