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 50

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 37 dinesha
`include "sdrc_define.v"
48 4 dinesha
 
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
 
97
parameter  SDR_DW   = 16;  // SDR Data Width 
98
parameter  SDR_BW   = 2;   // SDR Byte Width
99 50 dinesha
parameter  REQ_BW   = 12;   //  Request Width
100 4 dinesha
   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 50 dinesha
   input [REQ_BW-1:0]    r2b_len;
109 4 dinesha
   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 50 dinesha
   output [REQ_BW-1:0]   b2x_len;
118 4 dinesha
   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 50 dinesha
   reg [REQ_BW-1:0]      l_len;
146
   wire [REQ_BW-1:0]     b2x_len;
147 4 dinesha
   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
                       (activate_bank) ? 1'b1 : bank_valid;
174
 
175
         tras_cntr <= (activate_bank) ? tras_delay :
176
                      (~tras_ok_internal) ? tras_cntr - 4'b1 : 4'b0;
177
 
178
         timer0 <= (ld_trp) ? trp_delay :
179
                   (ld_trcd) ? trcd_delay :
180
                   (~timer0_tc) ? timer0 - 4'b1 : timer0;
181
 
182
         bank_st <= next_bank_st;
183
 
184
      end // else: !if(~reset_n)
185
 
186
   always @ (posedge clk) begin
187
 
188
      bank_row <= (activate_bank) ? b2x_addr : bank_row;
189
 
190
      if (~reset_n) begin
191
         l_start <= 1'b0;
192
         l_last <= 1'b0;
193
         l_id <= 1'b0;
194
         l_len <= 1'b0;
195
         l_wrap <= 1'b0;
196
         l_write <= 1'b0;
197
         l_raddr <= 1'b0;
198
         l_caddr <= 1'b0;
199
         l_sdr_dma_last <= 1'b0;
200
      end
201
      else begin
202
        if (b2r_ack) begin
203
           l_start <= r2b_start;
204
           l_last <= r2b_last;
205
           l_id <= r2b_req_id;
206
           l_len <= r2b_len;
207
           l_wrap <= r2b_wrap;
208
           l_write <= r2b_write;
209
           l_raddr <= r2b_raddr;
210
           l_caddr <= r2b_caddr;
211
           l_sdr_dma_last <= sdr_dma_last;
212
        end // if (b2r_ack)
213
      end
214
 
215
   end // always @ (posedge clk)
216
 
217
   assign tras_ok_internal = ~|tras_cntr;
218
   assign tras_ok = tras_ok_internal;
219
 
220
   assign activate_bank = (b2x_cmd == `OP_ACT) & x2b_ack;
221
 
222
   assign page_hit = (r2b_raddr == bank_row) ? bank_valid : 1'b0;    // its a hit only if bank is valid
223
 
224
   assign timer0_tc = ~|timer0;
225
 
226
   assign ld_trp = (b2x_cmd == `OP_PRE) ? x2b_ack : 1'b0;
227
 
228
   assign ld_trcd = (b2x_cmd == `OP_ACT) ? x2b_ack : 1'b0;
229
 
230
   always @ (*) begin
231
 
232
       bank_prech_page_closed = 1'b0;
233
       b2x_req = 1'b0;
234
       b2x_cmd = 2'bx;
235
       b2r_ack = 1'b0;
236
       b2x_addr = 12'bx;
237
       next_bank_st = bank_st;
238
 
239
      case (bank_st)
240
 
241
        `BANK_IDLE : begin
242
 
243
           if (~r2b_req) begin
244
              bank_prech_page_closed = 1'b0;
245
              b2x_req = 1'b0;
246
              b2x_cmd = 2'bx;
247
              b2r_ack = 1'b0;
248
              b2x_addr = 12'bx;
249
              next_bank_st = `BANK_IDLE;
250
           end // if (~r2b_req)
251
           else if (page_hit) begin
252
              b2x_req = (r2b_write) ? x2b_wrok & xfr_ok :
253
                        x2b_rdok & xfr_ok;
254
              b2x_cmd = (r2b_write) ? `OP_WR : `OP_RD;
255
              b2r_ack = 1'b1;
256
              b2x_addr = r2b_caddr;
257
              next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_XFR;  // in case of hit, stay here till xfr sm acks
258
           end // if (page_hit)
259
           else begin  // page_miss
260
              b2x_req = tras_ok_internal & x2b_pre_ok;
261
              b2x_cmd = `OP_PRE;
262
              b2r_ack = 1'b1;
263
              b2x_addr = r2b_raddr & 12'hBFF;      // Dont want to pre all banks!
264
              next_bank_st = (l_sdr_dma_last) ? `BANK_PRE : (x2b_ack) ? `BANK_ACT : `BANK_PRE;  // bank was precharged on l_sdr_dma_last
265
           end // else: !if(page_hit)
266
 
267
        end // case: `BANK_IDLE
268
 
269
        `BANK_PRE : begin
270
           b2x_req = tras_ok_internal & x2b_pre_ok;
271
           b2x_cmd = `OP_PRE;
272
           b2r_ack = 1'b0;
273
           b2x_addr = l_raddr & 12'hBFF;           // Dont want to pre all banks!
274
           bank_prech_page_closed = 1'b0;
275
           next_bank_st = (x2b_ack) ? `BANK_ACT : `BANK_PRE;
276
        end // case: `BANK_PRE
277
 
278
        `BANK_ACT : begin
279
           b2x_req = timer0_tc & x2b_act_ok;
280
           b2x_cmd = `OP_ACT;
281
           b2r_ack = 1'b0;
282
           b2x_addr = l_raddr;
283
           bank_prech_page_closed = 1'b0;
284
           next_bank_st = (x2b_ack) ? `BANK_XFR : `BANK_ACT;
285
        end // case: `BANK_ACT
286
 
287
        `BANK_XFR : begin
288
           b2x_req = (l_write) ? timer0_tc & x2b_wrok & xfr_ok :
289
                     timer0_tc & x2b_rdok & xfr_ok;
290
           b2x_cmd = (l_write) ? `OP_WR : `OP_RD;
291
           b2r_ack = 1'b0;
292
           b2x_addr = l_caddr;
293
           bank_prech_page_closed = 1'b0;
294
           next_bank_st = (x2b_refresh) ? `BANK_ACT :
295
                          (x2b_ack & l_sdr_dma_last) ? `BANK_DMA_LAST_PRE :
296
                          (x2b_ack) ? `BANK_IDLE : `BANK_XFR;
297
        end // case: `BANK_XFR
298
 
299
        `BANK_DMA_LAST_PRE : begin
300
           b2x_req = tras_ok_internal & x2b_pre_ok;
301
           b2x_cmd = `OP_PRE;
302
           b2r_ack = 1'b0;
303
           b2x_addr = l_raddr & 12'hBFF;           // Dont want to pre all banks!
304
           bank_prech_page_closed = 1'b1;
305
           next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_DMA_LAST_PRE;
306
        end // case: `BANK_DMA_LAST_PRE
307
 
308
      endcase // case(bank_st)
309
 
310
   end // always @ (bank_st or ...)
311
 
312
   assign b2x_start = (bank_st == `BANK_IDLE) ? r2b_start : l_start;
313
 
314
   assign b2x_last = (bank_st == `BANK_IDLE) ? r2b_last : l_last;
315
 
316
   assign b2x_id = (bank_st == `BANK_IDLE) ? r2b_req_id : l_id;
317
 
318
   assign b2x_len = (bank_st == `BANK_IDLE) ? r2b_len : l_len;
319
 
320
   assign b2x_wrap = (bank_st == `BANK_IDLE) ? r2b_wrap : l_wrap;
321
 
322
endmodule // sdr_bank_fsm

powered by: WebSVN 2.1.0

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