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

Subversion Repositories sdr_ctrl

[/] [sdr_ctrl/] [trunk/] [rtl/] [core/] [sdrc_req_gen.v] - Blame information for rev 55

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

Line No. Rev Author Line
1 3 dinesha
/*********************************************************************
2
 
3
  SDRAM Controller Request Generation
4
 
5
  This file is part of the sdram controller project
6
  http://www.opencores.org/cores/sdr_ctrl/
7
 
8
  Description: SDRAM Controller Reguest Generation
9 33 dinesha
 
10
  Address Generation Based on cfg_colbits
11
     cfg_colbits= 2'b00
12
            Address[7:0]    - Column Address
13
            Address[9:8]    - Bank Address
14
            Address[21:10]  - Row Address
15
     cfg_colbits= 2'b01
16
            Address[8:0]    - Column Address
17
            Address[10:9]   - Bank Address
18
            Address[22:11]  - Row Address
19
     cfg_colbits= 2'b10
20
            Address[9:0]    - Column Address
21
            Address[11:10]   - Bank Address
22
            Address[23:12]  - Row Address
23
     cfg_colbits= 2'b11
24
            Address[10:0]    - Column Address
25
            Address[12:11]   - Bank Address
26
            Address[24:13]  - Row Address
27
 
28 3 dinesha
  The SDRAMs are operated in 4 beat burst mode.
29 46 dinesha
 
30
  If Wrap = 0;
31 51 dinesha
      If the current burst cross the page boundary, then this block split the request
32
      into two coressponding change in address and request length
33 46 dinesha
 
34
  if the current burst cross the page boundar.
35 33 dinesha
  This module takes requests from the memory controller,
36 3 dinesha
  chops them to page boundaries if wrap=0,
37
  and passes the request to bank_ctl
38 50 dinesha
 
39
  Note: With Wrap = 0, each request from Application layer will be splited into two request,
40
        if the current burst cross the page boundary.
41
 
42 3 dinesha
  To Do:
43
    nothing
44
 
45
  Author(s):
46
      - Dinesh Annayya, dinesha@opencores.org
47 47 dinesha
  Version  : 0.0 - 8th Jan 2012
48
             0.1 - 5th Feb 2012, column/row/bank address are register to improve the timing issue in FPGA synthesis
49 3 dinesha
 
50
 
51
 
52
 Copyright (C) 2000 Authors and OPENCORES.ORG
53
 
54
 This source file may be used and distributed without
55
 restriction provided that this copyright statement is not
56
 removed from the file and that any derivative work contains
57
 the original copyright notice and the associated disclaimer.
58
 
59
 This source file is free software; you can redistribute it
60
 and/or modify it under the terms of the GNU Lesser General
61
 Public License as published by the Free Software Foundation;
62
 either version 2.1 of the License, or (at your option) any
63
later version.
64
 
65
 This source is distributed in the hope that it will be
66
 useful, but WITHOUT ANY WARRANTY; without even the implied
67
 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
68
 PURPOSE.  See the GNU Lesser General Public License for more
69
 details.
70
 
71
 You should have received a copy of the GNU Lesser General
72
 Public License along with this source; if not, download it
73
 from http://www.opencores.org/lgpl.shtml
74
 
75
*******************************************************************/
76
 
77 37 dinesha
`include "sdrc_define.v"
78 3 dinesha
 
79
module sdrc_req_gen (clk,
80
                    reset_n,
81 47 dinesha
                    cfg_colbits,
82
                    sdr_width,
83 3 dinesha
 
84
                    /* Request from app */
85 46 dinesha
                    req,                // Transfer Request
86
                    req_id,             // ID for this transfer
87
                    req_addr,           // SDRAM Address
88
                    req_len,            // Burst Length (in 32 bit words)
89
                    req_wrap,           // Wrap mode request (xfr_len = 4)
90
                    req_wr_n,           // 0 => Write request, 1 => read req
91
                    req_ack,            // Request has been accepted
92 3 dinesha
 
93 47 dinesha
                    /* Req to xfr_ctl */
94
                    r2x_idle,
95
 
96 3 dinesha
                    /* Req to bank_ctl */
97 47 dinesha
                    r2b_req,            // request
98
                    r2b_req_id,         // ID
99
                    r2b_start,          // First chunk of burst
100
                    r2b_last,           // Last chunk of burst
101
                    r2b_wrap,           // Wrap Mode
102
                    r2b_ba,             // bank address
103
                    r2b_raddr,          // row address
104
                    r2b_caddr,          // col address
105
                    r2b_len,            // length
106
                    r2b_write,          // write request
107 3 dinesha
                    b2r_ack,
108 47 dinesha
                    b2r_arb_ok
109
                    );
110 3 dinesha
 
111 55 dinesha
parameter  APP_AW   = 25;  // Application Address Width
112 3 dinesha
parameter  APP_DW   = 32;  // Application Data Width 
113
parameter  APP_BW   = 4;   // Application Byte Width
114
parameter  APP_RW   = 9;   // Application Request Width
115
 
116
parameter  SDR_DW   = 16;  // SDR Data Width 
117
parameter  SDR_BW   = 2;   // SDR Byte Width
118
 
119 51 dinesha
 
120 47 dinesha
input                   clk           ;
121
input                   reset_n       ;
122
input [1:0]             cfg_colbits   ; // 2'b00 - 8 Bit column address, 2'b01 - 9 Bit, 10 - 10 bit, 11 - 11Bits
123 3 dinesha
 
124 47 dinesha
/* Request from app */
125
input                   req           ; // Request 
126
input [`SDR_REQ_ID_W-1:0] req_id      ; // Request ID
127
input [APP_AW-1:0]       req_addr      ; // Request Address
128
input [APP_RW-1:0]       req_len       ; // Request length
129
input                   req_wr_n      ; // 0 -Write, 1 - Read
130
input                   req_wrap      ; // 1 - Wrap the Address on page boundary
131
output                  req_ack       ; // Request Ack
132 3 dinesha
 
133 47 dinesha
/* Req to bank_ctl */
134 50 dinesha
output                  r2x_idle      ;
135
output                  r2b_req       ; // Request
136
output                  r2b_start     ; // First Junk of the Burst Access
137
output                  r2b_last      ; // Last Junk of the Burst Access
138
output                  r2b_write     ; // 1 - Write, 0 - Read
139
output                  r2b_wrap      ; // 1 - Wrap the Address at the page boundary.
140 47 dinesha
output [`SDR_REQ_ID_W-1:0]       r2b_req_id;
141 50 dinesha
output [1:0]             r2b_ba        ; // Bank Address
142
output [11:0]            r2b_raddr     ; // Row Address
143
output [11:0]            r2b_caddr     ; // Column Address
144 54 dinesha
output [`REQ_BW-1:0]     r2b_len       ; // Burst Length
145 50 dinesha
input                   b2r_ack       ; // Request Ack
146
input                   b2r_arb_ok    ; // Bank controller fifo is not full and ready to accept the command
147 3 dinesha
//
148 47 dinesha
input [1:0]              sdr_width; // 2'b00 - 32 Bit, 2'b01 - 16 Bit, 2'b1x - 8Bit
149 16 dinesha
 
150 3 dinesha
 
151
   /****************************************************************************/
152
   // Internal Nets
153
 
154 55 dinesha
   `define REQ_IDLE        2'b00
155
   `define REQ_ACTIVE      2'b01
156
   `define REQ_PAGE_WRAP   2'b10
157 3 dinesha
 
158 55 dinesha
   reg  [1:0]            req_st, next_req_st;
159 47 dinesha
   reg                  r2x_idle, req_ack, r2b_req, r2b_start,
160
                        r2b_write, req_idle, req_ld, lcl_wrap;
161 3 dinesha
   reg [`SDR_REQ_ID_W-1:0]       r2b_req_id;
162 54 dinesha
   reg [`REQ_BW-1:0]     lcl_req_len;
163 3 dinesha
 
164 47 dinesha
   wire                 r2b_last, page_ovflw;
165 55 dinesha
   reg page_ovflw_r;
166 54 dinesha
   wire [`REQ_BW-1:0]    r2b_len, next_req_len;
167 51 dinesha
   wire [12:0]           max_r2b_len;
168
   reg  [12:0]           max_r2b_len_r;
169 3 dinesha
 
170 47 dinesha
   reg [1:0]             r2b_ba;
171
   reg [11:0]            r2b_raddr;
172
   reg [11:0]            r2b_caddr;
173 3 dinesha
 
174 46 dinesha
   reg [APP_AW-1:0]      curr_sdr_addr ;
175
   wire [APP_AW-1:0]     next_sdr_addr ;
176 3 dinesha
 
177 45 dinesha
 
178
//--------------------------------------------------------------------
179
// Generate the internal Adress and Burst length Based on sdram width
180
//--------------------------------------------------------------------
181
reg [APP_AW:0]           req_addr_int;
182
reg [APP_RW-1:0]         req_len_int;
183 47 dinesha
 
184 45 dinesha
always @(*) begin
185 46 dinesha
   if(sdr_width == 2'b00) begin // 32 Bit SDR Mode
186
      req_addr_int     = {1'b0,req_addr};
187
      req_len_int      = req_len;
188
   end else if(sdr_width == 2'b01) begin // 16 Bit SDR Mode
189
      // Changed the address and length to match the 16 bit SDR Mode
190
      req_addr_int     = {req_addr,1'b0};
191
      req_len_int      = {req_len,1'b0};
192
   end else  begin // 8 Bit SDR Mode
193
      // Changed the address and length to match the 16 bit SDR Mode
194
      req_addr_int    = {req_addr,2'b0};
195
      req_len_int     = {req_len,2'b0};
196
   end
197 45 dinesha
end
198
 
199 3 dinesha
   //
200 46 dinesha
   // Identify the page over flow.
201
   // Find the Maximum Burst length allowed from the selected column
202
   // address, If the requested burst length is more than the allowed Maximum
203
   // burst length, then we need to handle the bank cross over case and we
204
   // need to split the reuest.
205 3 dinesha
   //
206 51 dinesha
   assign max_r2b_len = (cfg_colbits == 2'b00) ? (12'h100 - {4'b0, req_addr_int[7:0]}) :
207
                        (cfg_colbits == 2'b01) ? (12'h200 - {3'b0, req_addr_int[8:0]}) :
208
                        (cfg_colbits == 2'b10) ? (12'h400 - {2'b0, req_addr_int[9:0]}) : (12'h800 - {1'b0, req_addr_int[10:0]});
209 3 dinesha
 
210 46 dinesha
 
211
     // If the wrap = 0 and current application burst length is crossing the page boundary, 
212
     // then request will be split into two with corresponding change in request address and request length.
213
     //
214
     // If the wrap = 0 and current burst length is not crossing the page boundary, 
215
     // then request from application layer will be transparently passed on the bank control block.
216
 
217
     //
218
     // if the wrap = 1, then this block will not modify the request address and length. 
219
     // The wrapping functionality will be handle by the bank control module and 
220
     // column address will rewind back as follows XX -> FF ? 00 ? 1
221
     //
222 50 dinesha
     // Note: With Wrap = 0, each request from Application layer will be spilited into two request, 
223
     // if the current burst cross the page boundary. 
224 55 dinesha
   assign page_ovflw = ({1'b0, req_len_int} > max_r2b_len) ? ~r2b_wrap : 1'b0;
225 3 dinesha
 
226 55 dinesha
   assign r2b_len = r2b_start ? ((page_ovflw_r) ? max_r2b_len_r : lcl_req_len) :
227
                      lcl_req_len;
228 3 dinesha
 
229 55 dinesha
   assign next_req_len = lcl_req_len - r2b_len;
230 3 dinesha
 
231 55 dinesha
   assign next_sdr_addr = curr_sdr_addr + r2b_len;
232 3 dinesha
 
233
 
234
   assign r2b_wrap = lcl_wrap;
235
 
236 55 dinesha
   assign r2b_last = (r2b_start & !page_ovflw_r) | (req_st == `REQ_PAGE_WRAP);
237 3 dinesha
//
238
//
239
//
240
   always @ (posedge clk) begin
241
 
242 55 dinesha
      page_ovflw_r   <= (req_ack) ? page_ovflw: 'h0;
243
 
244
      max_r2b_len_r  <= (req_ack) ? max_r2b_len: 'h0;
245 47 dinesha
      r2b_start      <= (req_ack) ? 1'b1 :
246
                        (b2r_ack) ? 1'b0 : r2b_start;
247 3 dinesha
 
248 47 dinesha
      r2b_write      <= (req_ack) ? ~req_wr_n : r2b_write;
249 3 dinesha
 
250 47 dinesha
      r2b_req_id     <= (req_ack) ? req_id : r2b_req_id;
251 3 dinesha
 
252 47 dinesha
      lcl_wrap       <= (req_ack) ? req_wrap : lcl_wrap;
253 3 dinesha
 
254 47 dinesha
      lcl_req_len    <= (req_ack) ? req_len_int  :
255
                        (req_ld) ? next_req_len : lcl_req_len;
256 3 dinesha
 
257 47 dinesha
      curr_sdr_addr  <= (req_ack) ? req_addr_int :
258
                        (req_ld) ? next_sdr_addr : curr_sdr_addr;
259 3 dinesha
 
260
   end // always @ (posedge clk)
261
 
262
   always @ (*) begin
263 55 dinesha
      r2x_idle    = 1'b0;
264
      req_idle    = 1'b0;
265
      req_ack     = 1'b0;
266
      req_ld      = 1'b0;
267
      r2b_req     = 1'b0;
268
      next_req_st = `REQ_IDLE;
269 3 dinesha
 
270
      case (req_st)      // synopsys full_case parallel_case
271
 
272
        `REQ_IDLE : begin
273
           r2x_idle = ~req;
274
           req_idle = 1'b1;
275
           req_ack = req & b2r_arb_ok;
276
           req_ld = 1'b0;
277
           r2b_req = 1'b0;
278
           next_req_st = (req & b2r_arb_ok) ? `REQ_ACTIVE : `REQ_IDLE;
279
        end // case: `REQ_IDLE
280
 
281
        `REQ_ACTIVE : begin
282
           r2x_idle = 1'b0;
283
           req_idle = 1'b0;
284
           req_ack = 1'b0;
285
           req_ld = b2r_ack;
286
           r2b_req = 1'b1;                       // req_gen to bank_req
287 55 dinesha
           next_req_st = (b2r_ack ) ? ((page_ovflw_r) ? `REQ_PAGE_WRAP :`REQ_IDLE) : `REQ_ACTIVE;
288 3 dinesha
        end // case: `REQ_ACTIVE
289 55 dinesha
        `REQ_PAGE_WRAP : begin
290
           r2x_idle = 1'b0;
291
           req_idle = 1'b0;
292
           req_ack  = 1'b0;
293
           req_ld = b2r_ack;
294
           r2b_req = 1'b1;                       // req_gen to bank_req
295
           next_req_st = (b2r_ack) ? `REQ_IDLE : `REQ_PAGE_WRAP;
296
        end // case: `REQ_ACTIVE
297 3 dinesha
 
298
      endcase // case(req_st)
299
 
300
   end // always @ (req_st or ....)
301
 
302
   always @ (posedge clk)
303
      if (~reset_n) begin
304
         req_st <= `REQ_IDLE;
305
      end // if (~reset_n)
306
      else begin
307
         req_st <= next_req_st;
308
      end // else: !if(~reset_n)
309
//
310
// addrs bits for the bank, row and column
311
//
312 47 dinesha
// Register row/column/bank to improve fpga timing issue
313
wire [APP_AW-1:0]        map_address ;
314 3 dinesha
 
315 47 dinesha
assign      map_address  = (req_ack) ? req_addr_int :
316
                           (req_ld)  ? next_sdr_addr : curr_sdr_addr;
317
 
318
always @ (posedge clk) begin
319 13 dinesha
// Bank Bits are always - 2 Bits
320 47 dinesha
    r2b_ba <= (cfg_colbits == 2'b00) ? {map_address[9:8]}   :
321 50 dinesha
              (cfg_colbits == 2'b01) ? {map_address[10:9]}  :
322
              (cfg_colbits == 2'b10) ? {map_address[11:10]} : map_address[12:11];
323 3 dinesha
 
324 46 dinesha
/********************
325
*  Colbits Mapping:
326
*           2'b00 - 8 Bit
327
*           2'b01 - 16 Bit
328
*           2'b10 - 10 Bit
329
*           2'b11 - 11 Bits
330
************************/
331 47 dinesha
    r2b_caddr <= (cfg_colbits == 2'b00) ? {4'b0, map_address[7:0]} :
332 50 dinesha
                 (cfg_colbits == 2'b01) ? {3'b0, map_address[8:0]} :
333
                 (cfg_colbits == 2'b10) ? {2'b0, map_address[9:0]} : {1'b0, map_address[10:0]};
334 3 dinesha
 
335 47 dinesha
    r2b_raddr <= (cfg_colbits == 2'b00)  ? map_address[21:10] :
336 50 dinesha
                 (cfg_colbits == 2'b01)  ? map_address[22:11] :
337
                 (cfg_colbits == 2'b10)  ? map_address[23:12] : map_address[24:13];
338 47 dinesha
end
339 3 dinesha
 
340
endmodule // sdr_req_gen

powered by: WebSVN 2.1.0

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