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 69

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

powered by: WebSVN 2.1.0

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