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

Subversion Repositories sdr_ctrl

[/] [sdr_ctrl/] [trunk/] [rtl/] [core/] [sdrc_bank_fsm.v] - Blame information for rev 4

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

Line No. Rev Author Line
1 4 dinesha
/*********************************************************************
2
 
3
  SDRAM Controller Bank Controller
4
 
5
  This file is part of the sdram controller project
6
  http://www.opencores.org/cores/sdr_ctrl/
7
 
8
  Description:
9
    This module takes requests from sdrc_req_gen, checks for page hit/miss and
10
    issues precharge/activate commands and then passes the request to sdrc_xfr_ctl.
11
 
12
  To Do:
13
    nothing
14
 
15
  Author(s):
16
      - Dinesh Annayya, dinesha@opencores.org
17
  Version  :  1.0  - 8th Jan 2012
18
 
19
 
20
 
21
 Copyright (C) 2000 Authors and OPENCORES.ORG
22
 
23
 This source file may be used and distributed without
24
 restriction provided that this copyright statement is not
25
 removed from the file and that any derivative work contains
26
 the original copyright notice and the associated disclaimer.
27
 
28
 This source file is free software; you can redistribute it
29
 and/or modify it under the terms of the GNU Lesser General
30
 Public License as published by the Free Software Foundation;
31
 either version 2.1 of the License, or (at your option) any
32
later version.
33
 
34
 This source is distributed in the hope that it will be
35
 useful, but WITHOUT ANY WARRANTY; without even the implied
36
 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
37
 PURPOSE.  See the GNU Lesser General Public License for more
38
 details.
39
 
40
 You should have received a copy of the GNU Lesser General
41
 Public License along with this source; if not, download it
42
 from http://www.opencores.org/lgpl.shtml
43
 
44
*******************************************************************/
45
 
46
 
47
`include "sdrc.def"
48
 
49
module sdrc_bank_fsm (clk,
50
                     reset_n,
51
 
52
                     /* Req from req_gen */
53
                     r2b_req,      // request
54
                     r2b_req_id,   // ID
55
                     r2b_start,    // First chunk of burst
56
                     r2b_last,     // Last chunk of burst
57
                     r2b_wrap,
58
                     r2b_raddr,    // row address
59
                     r2b_caddr,    // col address
60
                     r2b_len,      // length
61
                     r2b_write,    // write request
62
                     b2r_ack,
63
                     sdr_dma_last,
64
 
65
                     /* Transfer request to xfr_ctl */
66
                     b2x_req,      // Request to xfr_ctl
67
                     b2x_start,    // first chunk of transfer
68
                     b2x_last,     // last chunk of transfer
69
                     b2x_wrap,
70
                     b2x_id,       // Transfer ID
71
                     b2x_addr,     // row/col address
72
                     b2x_len,      // transfer length
73
                     b2x_cmd,      // transfer command
74
                     x2b_ack,      // command accepted
75
 
76
                     /* Status to/from xfr_ctl */
77
                     tras_ok,      // TRAS OK for this bank
78
                     xfr_ok,
79
                     x2b_refresh,  // We did a refresh
80
                     x2b_pre_ok,   // OK to do a precharge (per bank)
81
                     x2b_act_ok,   // OK to do an activate
82
                     x2b_rdok,     // OK to do a read
83
                     x2b_wrok,     // OK to do a write
84
 
85
                     /* current xfr row address of the bank */
86
                     bank_row,
87
 
88
                     /* SDRAM Timing */
89
                     tras_delay,   // Active to precharge delay
90
                     trp_delay,    // Precharge to active delay
91
                     trcd_delay);  // Active to R/W delay
92
 
93
parameter  APP_AW   = 30;  // Application Address Width
94
parameter  APP_DW   = 32;  // Application Data Width 
95
parameter  APP_BW   = 4;   // Application Byte Width
96
parameter  APP_RW   = 9;   // Application Request Width
97
 
98
parameter  SDR_DW   = 16;  // SDR Data Width 
99
parameter  SDR_BW   = 2;   // SDR Byte Width
100
   input                        clk, reset_n;
101
 
102
   /* Req from bank_ctl */
103
   input                        r2b_req, r2b_start, r2b_last,
104
                                r2b_write, r2b_wrap;
105
   input [`SDR_REQ_ID_W-1:0]     r2b_req_id;
106
   input [11:0]          r2b_raddr;
107
   input [11:0]          r2b_caddr;
108
   input [APP_RW-1:0]    r2b_len;
109
   output                       b2r_ack;
110
   input                        sdr_dma_last;
111
 
112
   /* Req to xfr_ctl */
113
   output                       b2x_req, b2x_start, b2x_last,
114
                                tras_ok, b2x_wrap;
115
   output [`SDR_REQ_ID_W-1:0]    b2x_id;
116
   output [11:0]                 b2x_addr;
117
   output [APP_RW-1:0]   b2x_len;
118
   output [1:0]          b2x_cmd;
119
   input                        x2b_ack;
120
 
121
   /* Status from xfr_ctl */
122
   input                        x2b_refresh, x2b_act_ok, x2b_rdok,
123
                                x2b_wrok, x2b_pre_ok, xfr_ok;
124
 
125
   input [3:0]                   tras_delay, trp_delay, trcd_delay;
126
 
127
   output [11:0]                         bank_row;
128
 
129
   /****************************************************************************/
130
   // Internal Nets
131
 
132
   `define BANK_IDLE         3'b000
133
   `define BANK_PRE          3'b001
134
   `define BANK_ACT          3'b010
135
   `define BANK_XFR          3'b011
136
   `define BANK_DMA_LAST_PRE 3'b100
137
 
138
   reg [2:0]                     bank_st, next_bank_st;
139
   wire                         b2x_start, b2x_last;
140
   reg                          l_start, l_last;
141
   reg                          b2x_req, b2r_ack;
142
   wire [`SDR_REQ_ID_W-1:0]      b2x_id;
143
   reg [`SDR_REQ_ID_W-1:0]       l_id;
144
   reg [11:0]                    b2x_addr;
145
   reg [APP_RW-1:0]      l_len;
146
   wire [APP_RW-1:0]     b2x_len;
147
   reg [1:0]                     b2x_cmd;
148
   reg                          bank_valid;
149
   reg [11:0]                    bank_row;
150
   reg [3:0]                     tras_cntr, timer0;
151
   reg                          l_wrap, l_write;
152
   wire                         b2x_wrap;
153
   reg [11:0]                    l_raddr;
154
   reg [11:0]                    l_caddr;
155
   reg                          l_sdr_dma_last;
156
   reg                          bank_prech_page_closed;
157
 
158
   wire                         tras_ok_internal, tras_ok, activate_bank;
159
 
160
   wire                         page_hit, timer0_tc, ld_trp, ld_trcd;
161
 
162
   always @ (posedge clk)
163
      if (~reset_n) begin
164
         bank_valid <= 1'b0;
165
         tras_cntr <= 4'b0;
166
         timer0 <= 4'b0;
167
         bank_st <= `BANK_IDLE;
168
      end // if (~reset_n)
169
 
170
      else begin
171
 
172
         bank_valid <= (x2b_refresh || bank_prech_page_closed) ? 1'b0 :  // force the bank status to be invalid
173
//       bank_valid <= (x2b_refresh) ? 1'b0 :
174
                       (activate_bank) ? 1'b1 : bank_valid;
175
 
176
         tras_cntr <= (activate_bank) ? tras_delay :
177
                      (~tras_ok_internal) ? tras_cntr - 4'b1 : 4'b0;
178
 
179
         timer0 <= (ld_trp) ? trp_delay :
180
                   (ld_trcd) ? trcd_delay :
181
                   (~timer0_tc) ? timer0 - 4'b1 : timer0;
182
 
183
         bank_st <= next_bank_st;
184
 
185
      end // else: !if(~reset_n)
186
 
187
   always @ (posedge clk) begin
188
 
189
      bank_row <= (activate_bank) ? b2x_addr : bank_row;
190
 
191
      if (~reset_n) begin
192
         l_start <= 1'b0;
193
         l_last <= 1'b0;
194
         l_id <= 1'b0;
195
         l_len <= 1'b0;
196
         l_wrap <= 1'b0;
197
         l_write <= 1'b0;
198
         l_raddr <= 1'b0;
199
         l_caddr <= 1'b0;
200
         l_sdr_dma_last <= 1'b0;
201
      end
202
      else begin
203
        if (b2r_ack) begin
204
           l_start <= r2b_start;
205
           l_last <= r2b_last;
206
           l_id <= r2b_req_id;
207
           l_len <= r2b_len;
208
           l_wrap <= r2b_wrap;
209
           l_write <= r2b_write;
210
           l_raddr <= r2b_raddr;
211
           l_caddr <= r2b_caddr;
212
           l_sdr_dma_last <= sdr_dma_last;
213
        end // if (b2r_ack)
214
      end
215
 
216
   end // always @ (posedge clk)
217
 
218
   assign tras_ok_internal = ~|tras_cntr;
219
   assign tras_ok = tras_ok_internal;
220
 
221
   assign activate_bank = (b2x_cmd == `OP_ACT) & x2b_ack;
222
 
223
   assign page_hit = (r2b_raddr == bank_row) ? bank_valid : 1'b0;    // its a hit only if bank is valid
224
 
225
   assign timer0_tc = ~|timer0;
226
 
227
   assign ld_trp = (b2x_cmd == `OP_PRE) ? x2b_ack : 1'b0;
228
 
229
   assign ld_trcd = (b2x_cmd == `OP_ACT) ? x2b_ack : 1'b0;
230
 
231
   always @ (*) begin
232
 
233
       bank_prech_page_closed = 1'b0;
234
       b2x_req = 1'b0;
235
       b2x_cmd = 2'bx;
236
       b2r_ack = 1'b0;
237
       b2x_addr = 12'bx;
238
       next_bank_st = bank_st;
239
 
240
      case (bank_st)
241
 
242
        `BANK_IDLE : begin
243
 
244
           if (~r2b_req) begin
245
              bank_prech_page_closed = 1'b0;
246
              b2x_req = 1'b0;
247
              b2x_cmd = 2'bx;
248
              b2r_ack = 1'b0;
249
              b2x_addr = 12'bx;
250
              next_bank_st = `BANK_IDLE;
251
           end // if (~r2b_req)
252
           else if (page_hit) begin
253
              b2x_req = (r2b_write) ? x2b_wrok & xfr_ok :
254
                        x2b_rdok & xfr_ok;
255
              b2x_cmd = (r2b_write) ? `OP_WR : `OP_RD;
256
              b2r_ack = 1'b1;
257
              b2x_addr = r2b_caddr;
258
              next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_XFR;  // in case of hit, stay here till xfr sm acks
259
           end // if (page_hit)
260
           else begin  // page_miss
261
              b2x_req = tras_ok_internal & x2b_pre_ok;
262
              b2x_cmd = `OP_PRE;
263
              b2r_ack = 1'b1;
264
              b2x_addr = r2b_raddr & 12'hBFF;      // Dont want to pre all banks!
265
              next_bank_st = (l_sdr_dma_last) ? `BANK_PRE : (x2b_ack) ? `BANK_ACT : `BANK_PRE;  // bank was precharged on l_sdr_dma_last
266
           end // else: !if(page_hit)
267
 
268
        end // case: `BANK_IDLE
269
 
270
        `BANK_PRE : begin
271
           b2x_req = tras_ok_internal & x2b_pre_ok;
272
           b2x_cmd = `OP_PRE;
273
           b2r_ack = 1'b0;
274
           b2x_addr = l_raddr & 12'hBFF;           // Dont want to pre all banks!
275
           bank_prech_page_closed = 1'b0;
276
           next_bank_st = (x2b_ack) ? `BANK_ACT : `BANK_PRE;
277
        end // case: `BANK_PRE
278
 
279
        `BANK_ACT : begin
280
           b2x_req = timer0_tc & x2b_act_ok;
281
           b2x_cmd = `OP_ACT;
282
           b2r_ack = 1'b0;
283
           b2x_addr = l_raddr;
284
           bank_prech_page_closed = 1'b0;
285
           next_bank_st = (x2b_ack) ? `BANK_XFR : `BANK_ACT;
286
        end // case: `BANK_ACT
287
 
288
        `BANK_XFR : begin
289
           b2x_req = (l_write) ? timer0_tc & x2b_wrok & xfr_ok :
290
                     timer0_tc & x2b_rdok & xfr_ok;
291
           b2x_cmd = (l_write) ? `OP_WR : `OP_RD;
292
           b2r_ack = 1'b0;
293
           b2x_addr = l_caddr;
294
           bank_prech_page_closed = 1'b0;
295
           next_bank_st = (x2b_refresh) ? `BANK_ACT :
296
                          (x2b_ack & l_sdr_dma_last) ? `BANK_DMA_LAST_PRE :
297
                          (x2b_ack) ? `BANK_IDLE : `BANK_XFR;
298
        end // case: `BANK_XFR
299
 
300
        `BANK_DMA_LAST_PRE : begin
301
           b2x_req = tras_ok_internal & x2b_pre_ok;
302
           b2x_cmd = `OP_PRE;
303
           b2r_ack = 1'b0;
304
           b2x_addr = l_raddr & 12'hBFF;           // Dont want to pre all banks!
305
           bank_prech_page_closed = 1'b1;
306
           next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_DMA_LAST_PRE;
307
        end // case: `BANK_DMA_LAST_PRE
308
 
309
      endcase // case(bank_st)
310
 
311
   end // always @ (bank_st or ...)
312
 
313
   assign b2x_start = (bank_st == `BANK_IDLE) ? r2b_start : l_start;
314
 
315
   assign b2x_last = (bank_st == `BANK_IDLE) ? r2b_last : l_last;
316
 
317
   assign b2x_id = (bank_st == `BANK_IDLE) ? r2b_req_id : l_id;
318
 
319
   assign b2x_len = (bank_st == `BANK_IDLE) ? r2b_len : l_len;
320
 
321
   assign b2x_wrap = (bank_st == `BANK_IDLE) ? r2b_wrap : l_wrap;
322
 
323
endmodule // sdr_bank_fsm

powered by: WebSVN 2.1.0

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