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 46

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

powered by: WebSVN 2.1.0

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