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 52

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

powered by: WebSVN 2.1.0

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