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 47

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

powered by: WebSVN 2.1.0

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