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 45

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

powered by: WebSVN 2.1.0

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