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 54

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

powered by: WebSVN 2.1.0

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