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 54

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

powered by: WebSVN 2.1.0

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