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 71

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

powered by: WebSVN 2.1.0

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