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 53

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 51 dinesha
// 12 bit subtractor is not feasibile for FPGA, so changed to 8 bits
100
parameter  REQ_BW   = (`TARGET_DESIGN == `FPGA) ? 8 : 12;   //  Request Width
101
 
102 4 dinesha
   input                        clk, reset_n;
103
 
104
   /* Req from bank_ctl */
105
   input                        r2b_req, r2b_start, r2b_last,
106
                                r2b_write, r2b_wrap;
107
   input [`SDR_REQ_ID_W-1:0]     r2b_req_id;
108
   input [11:0]          r2b_raddr;
109
   input [11:0]          r2b_caddr;
110 50 dinesha
   input [REQ_BW-1:0]    r2b_len;
111 4 dinesha
   output                       b2r_ack;
112
   input                        sdr_dma_last;
113
 
114
   /* Req to xfr_ctl */
115
   output                       b2x_req, b2x_start, b2x_last,
116
                                tras_ok, b2x_wrap;
117
   output [`SDR_REQ_ID_W-1:0]    b2x_id;
118
   output [11:0]                 b2x_addr;
119 50 dinesha
   output [REQ_BW-1:0]   b2x_len;
120 4 dinesha
   output [1:0]          b2x_cmd;
121
   input                        x2b_ack;
122
 
123
   /* Status from xfr_ctl */
124
   input                        x2b_refresh, x2b_act_ok, x2b_rdok,
125
                                x2b_wrok, x2b_pre_ok, xfr_ok;
126
 
127
   input [3:0]                   tras_delay, trp_delay, trcd_delay;
128
 
129
   output [11:0]                         bank_row;
130
 
131
   /****************************************************************************/
132
   // Internal Nets
133
 
134
   `define BANK_IDLE         3'b000
135
   `define BANK_PRE          3'b001
136
   `define BANK_ACT          3'b010
137
   `define BANK_XFR          3'b011
138
   `define BANK_DMA_LAST_PRE 3'b100
139
 
140
   reg [2:0]                     bank_st, next_bank_st;
141
   wire                         b2x_start, b2x_last;
142
   reg                          l_start, l_last;
143
   reg                          b2x_req, b2r_ack;
144
   wire [`SDR_REQ_ID_W-1:0]      b2x_id;
145
   reg [`SDR_REQ_ID_W-1:0]       l_id;
146
   reg [11:0]                    b2x_addr;
147 50 dinesha
   reg [REQ_BW-1:0]      l_len;
148
   wire [REQ_BW-1:0]     b2x_len;
149 51 dinesha
   reg [1:0]                     b2x_cmd_t;
150 4 dinesha
   reg                          bank_valid;
151
   reg [11:0]                    bank_row;
152
   reg [3:0]                     tras_cntr, timer0;
153
   reg                          l_wrap, l_write;
154
   wire                         b2x_wrap;
155
   reg [11:0]                    l_raddr;
156
   reg [11:0]                    l_caddr;
157
   reg                          l_sdr_dma_last;
158
   reg                          bank_prech_page_closed;
159
 
160
   wire                         tras_ok_internal, tras_ok, activate_bank;
161
 
162 51 dinesha
   wire                         page_hit, timer0_tc_t, ld_trp, ld_trcd;
163 4 dinesha
 
164 51 dinesha
   /*** Timing Break Logic Added for FPGA - Start ****/
165
   reg  x2b_wrok_r, xfr_ok_r , x2b_rdok_r;
166
   reg [1:0] b2x_cmd_r,timer0_tc_r,tras_ok_r,x2b_pre_ok_r,x2b_act_ok_r;
167 4 dinesha
   always @ (posedge clk)
168
      if (~reset_n) begin
169 51 dinesha
         x2b_wrok_r <= 1'b0;
170
         xfr_ok_r   <= 1'b0;
171
         x2b_rdok_r <= 1'b0;
172
         b2x_cmd_r  <= 2'b0;
173
         timer0_tc_r  <= 1'b0;
174
         tras_ok_r    <= 1'b0;
175
         x2b_pre_ok_r <= 1'b0;
176
         x2b_act_ok_r <= 1'b0;
177
      end
178
      else begin
179
         x2b_wrok_r <= x2b_wrok;
180
         xfr_ok_r   <= xfr_ok;
181
         x2b_rdok_r <= x2b_rdok;
182
         b2x_cmd_r  <= b2x_cmd_t;
183
         timer0_tc_r <= (ld_trp | ld_trcd) ? 1'b0 : timer0_tc_t;
184
         tras_ok_r   <= tras_ok_internal;
185
         x2b_pre_ok_r  <= x2b_pre_ok;
186
         x2b_act_ok_r  <= x2b_act_ok;
187
      end
188
 
189
 wire  x2b_wrok_t     = (`TARGET_DESIGN == `FPGA) ? x2b_wrok_r : x2b_wrok;
190
 wire  xfr_ok_t       = (`TARGET_DESIGN == `FPGA) ? xfr_ok_r : xfr_ok;
191
 wire  x2b_rdok_t     = (`TARGET_DESIGN == `FPGA) ? x2b_rdok_r : x2b_rdok;
192
 wire [1:0] b2x_cmd   = (`TARGET_DESIGN == `FPGA) ? b2x_cmd_r : b2x_cmd_t;
193
 wire  timer0_tc      = (`TARGET_DESIGN == `FPGA) ? timer0_tc_r : timer0_tc_t;
194
 assign  tras_ok      = (`TARGET_DESIGN == `FPGA) ? tras_ok_r : tras_ok_internal;
195
 wire  x2b_pre_ok_t   = (`TARGET_DESIGN == `FPGA) ? x2b_pre_ok_r : x2b_pre_ok;
196
 wire  x2b_act_ok_t   = (`TARGET_DESIGN == `FPGA) ? x2b_act_ok_r : x2b_act_ok;
197
 
198
   /*** Timing Break Logic Added for FPGA - End****/
199
 
200
 
201
   always @ (posedge clk)
202
      if (~reset_n) begin
203 4 dinesha
         bank_valid <= 1'b0;
204
         tras_cntr <= 4'b0;
205
         timer0 <= 4'b0;
206
         bank_st <= `BANK_IDLE;
207
      end // if (~reset_n)
208
 
209
      else begin
210
 
211
         bank_valid <= (x2b_refresh || bank_prech_page_closed) ? 1'b0 :  // force the bank status to be invalid
212
                       (activate_bank) ? 1'b1 : bank_valid;
213
 
214
         tras_cntr <= (activate_bank) ? tras_delay :
215
                      (~tras_ok_internal) ? tras_cntr - 4'b1 : 4'b0;
216
 
217
         timer0 <= (ld_trp) ? trp_delay :
218
                   (ld_trcd) ? trcd_delay :
219 51 dinesha
                   (timer0 != 'h0) ? timer0 - 4'b1 : timer0;
220 4 dinesha
 
221
         bank_st <= next_bank_st;
222
 
223
      end // else: !if(~reset_n)
224
 
225
   always @ (posedge clk) begin
226
 
227
      bank_row <= (activate_bank) ? b2x_addr : bank_row;
228
 
229
      if (~reset_n) begin
230
         l_start <= 1'b0;
231
         l_last <= 1'b0;
232
         l_id <= 1'b0;
233
         l_len <= 1'b0;
234
         l_wrap <= 1'b0;
235
         l_write <= 1'b0;
236
         l_raddr <= 1'b0;
237
         l_caddr <= 1'b0;
238
         l_sdr_dma_last <= 1'b0;
239
      end
240
      else begin
241
        if (b2r_ack) begin
242
           l_start <= r2b_start;
243
           l_last <= r2b_last;
244
           l_id <= r2b_req_id;
245
           l_len <= r2b_len;
246
           l_wrap <= r2b_wrap;
247
           l_write <= r2b_write;
248
           l_raddr <= r2b_raddr;
249
           l_caddr <= r2b_caddr;
250
           l_sdr_dma_last <= sdr_dma_last;
251
        end // if (b2r_ack)
252
      end
253
 
254
   end // always @ (posedge clk)
255
 
256
   assign tras_ok_internal = ~|tras_cntr;
257
 
258
   assign activate_bank = (b2x_cmd == `OP_ACT) & x2b_ack;
259
 
260
   assign page_hit = (r2b_raddr == bank_row) ? bank_valid : 1'b0;    // its a hit only if bank is valid
261
 
262 51 dinesha
   assign timer0_tc_t = ~|timer0;
263 4 dinesha
 
264
   assign ld_trp = (b2x_cmd == `OP_PRE) ? x2b_ack : 1'b0;
265
 
266
   assign ld_trcd = (b2x_cmd == `OP_ACT) ? x2b_ack : 1'b0;
267
 
268 51 dinesha
 
269
 
270 4 dinesha
   always @ (*) begin
271
 
272
       bank_prech_page_closed = 1'b0;
273
       b2x_req = 1'b0;
274 51 dinesha
       b2x_cmd_t = 2'bx;
275 4 dinesha
       b2r_ack = 1'b0;
276
       b2x_addr = 12'bx;
277
       next_bank_st = bank_st;
278
 
279
      case (bank_st)
280
 
281
        `BANK_IDLE : begin
282 51 dinesha
                if(`TARGET_DESIGN == `FPGA) begin // To break the timing, b2x request are generated delayed
283
                     if (~r2b_req) begin
284
                        next_bank_st = `BANK_IDLE;
285
                     end // if (~r2b_req)
286
                     else if (page_hit) begin
287
                        b2r_ack = 1'b1;
288
                        b2x_cmd_t = (r2b_write) ? `OP_WR : `OP_RD;
289
                        next_bank_st = `BANK_XFR;
290
                     end // if (page_hit)
291
                     else begin  // page_miss
292
                        b2r_ack = 1'b1;
293
                        b2x_cmd_t = `OP_PRE;
294
                        next_bank_st = `BANK_PRE;  // bank was precharged on l_sdr_dma_last
295
                     end // else: !if(page_hit)
296
                end else begin // ASIC
297
                     if (~r2b_req) begin
298
                        bank_prech_page_closed = 1'b0;
299
                        b2x_req = 1'b0;
300
                        b2x_cmd_t = 2'bx;
301
                        b2r_ack = 1'b0;
302
                        b2x_addr = 12'bx;
303
                        next_bank_st = `BANK_IDLE;
304
                     end // if (~r2b_req)
305
                     else if (page_hit) begin
306
                        b2x_req = (r2b_write) ? x2b_wrok_t & xfr_ok_t :
307
                                               x2b_rdok_t & xfr_ok_t;
308
                        b2x_cmd_t = (r2b_write) ? `OP_WR : `OP_RD;
309
                        b2r_ack = 1'b1;
310
                        b2x_addr = r2b_caddr;
311
                        next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_XFR;  // in case of hit, stay here till xfr sm acks
312
                     end // if (page_hit)
313
                     else begin  // page_miss
314
                        b2x_req = tras_ok & x2b_pre_ok_t;
315
                        b2x_cmd_t = `OP_PRE;
316
                        b2r_ack = 1'b1;
317
                        b2x_addr = r2b_raddr & 12'hBFF;    // Dont want to pre all banks!
318
                        next_bank_st = (l_sdr_dma_last) ? `BANK_PRE : (x2b_ack) ? `BANK_ACT : `BANK_PRE;  // bank was precharged on l_sdr_dma_last
319
                     end // else: !if(page_hit)
320
                end
321 4 dinesha
        end // case: `BANK_IDLE
322
 
323
        `BANK_PRE : begin
324 51 dinesha
           b2x_req = tras_ok & x2b_pre_ok_t;
325
           b2x_cmd_t = `OP_PRE;
326 4 dinesha
           b2r_ack = 1'b0;
327
           b2x_addr = l_raddr & 12'hBFF;           // Dont want to pre all banks!
328
           bank_prech_page_closed = 1'b0;
329
           next_bank_st = (x2b_ack) ? `BANK_ACT : `BANK_PRE;
330
        end // case: `BANK_PRE
331
 
332
        `BANK_ACT : begin
333 51 dinesha
           b2x_req = timer0_tc & x2b_act_ok_t;
334
           b2x_cmd_t = `OP_ACT;
335 4 dinesha
           b2r_ack = 1'b0;
336
           b2x_addr = l_raddr;
337
           bank_prech_page_closed = 1'b0;
338
           next_bank_st = (x2b_ack) ? `BANK_XFR : `BANK_ACT;
339
        end // case: `BANK_ACT
340
 
341
        `BANK_XFR : begin
342 51 dinesha
           b2x_req = (l_write) ? timer0_tc & x2b_wrok_t & xfr_ok_t :
343
                     timer0_tc & x2b_rdok_t & xfr_ok_t;
344
           b2x_cmd_t = (l_write) ? `OP_WR : `OP_RD;
345 4 dinesha
           b2r_ack = 1'b0;
346
           b2x_addr = l_caddr;
347
           bank_prech_page_closed = 1'b0;
348
           next_bank_st = (x2b_refresh) ? `BANK_ACT :
349
                          (x2b_ack & l_sdr_dma_last) ? `BANK_DMA_LAST_PRE :
350
                          (x2b_ack) ? `BANK_IDLE : `BANK_XFR;
351
        end // case: `BANK_XFR
352
 
353
        `BANK_DMA_LAST_PRE : begin
354 51 dinesha
           b2x_req = tras_ok & x2b_pre_ok_t;
355
           b2x_cmd_t = `OP_PRE;
356 4 dinesha
           b2r_ack = 1'b0;
357
           b2x_addr = l_raddr & 12'hBFF;           // Dont want to pre all banks!
358
           bank_prech_page_closed = 1'b1;
359
           next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_DMA_LAST_PRE;
360
        end // case: `BANK_DMA_LAST_PRE
361
 
362
      endcase // case(bank_st)
363
 
364
   end // always @ (bank_st or ...)
365
 
366
   assign b2x_start = (bank_st == `BANK_IDLE) ? r2b_start : l_start;
367
 
368
   assign b2x_last = (bank_st == `BANK_IDLE) ? r2b_last : l_last;
369
 
370
   assign b2x_id = (bank_st == `BANK_IDLE) ? r2b_req_id : l_id;
371
 
372
   assign b2x_len = (bank_st == `BANK_IDLE) ? r2b_len : l_len;
373
 
374
   assign b2x_wrap = (bank_st == `BANK_IDLE) ? r2b_wrap : l_wrap;
375
 
376
endmodule // sdr_bank_fsm

powered by: WebSVN 2.1.0

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