1 /*********************************************************************
3 SDRAM Controller Request Generation
5 This file is part of the sdram controller project
6 http://www.opencores.org/cores/sdr_ctrl/
8 Description: SDRAM Controller Reguest Generation
10 Address Generation Based on cfg_colbits
12 Address[7:0] - Column Address
13 Address[9:8] - Bank Address
14 Address[22:10] - Row Address
16 Address[8:0] - Column Address
17 Address[10:9] - Bank Address
18 Address[23:11] - Row Address
20 Address[9:0] - Column Address
21 Address[11:10] - Bank Address
22 Address[24:12] - Row Address
24 Address[10:0] - Column Address
25 Address[12:11] - Bank Address
26 Address[25:13] - Row Address
28 The SDRAMs are operated in 4 beat burst mode.
31 If the current burst cross the page boundary, then this block split the request
32 into two coressponding change in address and request length
34 if the current burst cross the page boundar.
35 This module takes requests from the memory controller,
36 chops them to page boundaries if wrap=0,
37 and passes the request to bank_ctl
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.
46 - Dinesh Annayya, dinesha@opencores.org
47 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
52 Copyright (C) 2000 Authors and OPENCORES.ORG
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.
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
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
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
75 *******************************************************************/
79 module sdrc_req_gen (clk,
84 /* Request from app */
85 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
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
106 r2b_write, // write request
112 `define SDR_REQ_ID_W 4
114 `define SDR_RFSH_TIMER_W 12
115 `define SDR_RFSH_ROW_CNT_W 3
124 // SDRAM Commands (CS_N, RAS_N, CAS_N, WE_N)
126 `define SDR_DESEL 4'b1111
127 `define SDR_NOOP 4'b0111
128 `define SDR_ACTIVATE 4'b0011
129 `define SDR_READ 4'b0101
130 `define SDR_WRITE 4'b0100
131 `define SDR_BT 4'b0110
132 `define SDR_PRECHARGE 4'b0010
133 `define SDR_REFRESH 4'b0001
134 `define SDR_MODE 4'b0000
138 `define TARGET_DESIGN `ASIC
139 // 12 bit subtractor is not feasibile for FPGA, so changed to 6 bits
140 `define REQ_BW (`TARGET_DESIGN == `FPGA) ? 6 : 12 // Request Width
142 parameter APP_AW = 26; // Application Address Width
143 parameter APP_DW = 64; // Application Data Width
144 parameter APP_BW = 8; // Application Byte Width
145 parameter APP_RW = 9; // Application Request Width
147 parameter SDR_DW = 64; // SDR Data Width
148 parameter SDR_BW = 8; // SDR Byte Width
153 input [1:0] cfg_colbits ; // 2'b00 - 8 Bit column address, 2'b01 - 9 Bit, 10 - 10 bit, 11 - 11Bits
155 /* Request from app */
156 input req ; // Request
157 input [`SDR_REQ_ID_W-1:0] req_id ; // Request ID
158 input [APP_AW-1:0] req_addr ; // Request Address
159 input [APP_RW-1:0] req_len ; // Request length
160 input req_wr_n ; // 0 -Write, 1 - Read
161 input req_wrap ; // 1 - Wrap the Address on page boundary
162 output req_ack ; // Request Ack
164 /* Req to bank_ctl */
166 output r2b_req ; // Request
167 output r2b_start ; // First Junk of the Burst Access
168 output r2b_last ; // Last Junk of the Burst Access
169 output r2b_write ; // 1 - Write, 0 - Read
170 output r2b_wrap ; // 1 - Wrap the Address at the page boundary.
171 output [`SDR_REQ_ID_W-1:0] r2b_req_id;
172 output [1:0] r2b_ba ; // Bank Address
173 output [12:0] r2b_raddr ; // Row Address
174 output [12:0] r2b_caddr ; // Column Address
175 output [`REQ_BW-1:0] r2b_len ; // Burst Length
176 input b2r_ack ; // Request Ack
177 input b2r_arb_ok ; // Bank controller fifo is not full and ready to accept the command
179 input [1:0] sdr_width; // 2'b00 - 32 Bit, 2'b01 - 16 Bit, 2'b1x - 8Bit
182 /****************************************************************************/
185 `define REQ_IDLE 2'b00
186 `define REQ_ACTIVE 2'b01
187 `define REQ_PAGE_WRAP 2'b10
189 reg [1:0] req_st, next_req_st;
190 reg r2x_idle, req_ack, r2b_req, r2b_start,
191 r2b_write, req_idle, req_ld, lcl_wrap;
192 reg [`SDR_REQ_ID_W-1:0] r2b_req_id;
193 reg [`REQ_BW-1:0] lcl_req_len;
195 wire r2b_last, page_ovflw;
197 wire [`REQ_BW-1:0] r2b_len, next_req_len;
198 wire [12:0] max_r2b_len;
199 reg [12:0] max_r2b_len_r;
202 reg [12:0] r2b_raddr;
203 reg [12:0] r2b_caddr;
205 reg [APP_AW-1:0] curr_sdr_addr ;
206 wire [APP_AW-1:0] next_sdr_addr ;
209 //--------------------------------------------------------------------
210 // Generate the internal Adress and Burst length Based on sdram width
211 //--------------------------------------------------------------------
212 reg [APP_AW:0] req_addr_int;
213 reg [APP_RW-1:0] req_len_int;
216 if(sdr_width == 2'b00) begin // 32 Bit SDR Mode
217 req_addr_int = {1'b0,req_addr};
218 req_len_int = req_len;
219 end else if(sdr_width == 2'b01) begin // 16 Bit SDR Mode
220 // Changed the address and length to match the 16 bit SDR Mode
221 req_addr_int = {req_addr,1'b0};
222 req_len_int = {req_len,1'b0};
223 end else begin // 8 Bit SDR Mode
224 // Changed the address and length to match the 16 bit SDR Mode
225 req_addr_int = {req_addr,2'b0};
226 req_len_int = {req_len,2'b0};
231 // Identify the page over flow.
232 // Find the Maximum Burst length allowed from the selected column
233 // address, If the requested burst length is more than the allowed Maximum
234 // burst length, then we need to handle the bank cross over case and we
235 // need to split the reuest.
237 assign max_r2b_len = (cfg_colbits == 2'b00) ? (12'h100 - {4'b0, req_addr_int[7:0]}) :
238 (cfg_colbits == 2'b01) ? (12'h200 - {3'b0, req_addr_int[8:0]}) :
239 (cfg_colbits == 2'b10) ? (12'h400 - {2'b0, req_addr_int[9:0]}) : (12'h800 - {1'b0, req_addr_int[10:0]});
242 // If the wrap = 0 and current application burst length is crossing the page boundary,
243 // then request will be split into two with corresponding change in request address and request length.
245 // If the wrap = 0 and current burst length is not crossing the page boundary,
246 // then request from application layer will be transparently passed on the bank control block.
249 // if the wrap = 1, then this block will not modify the request address and length.
250 // The wrapping functionality will be handle by the bank control module and
251 // column address will rewind back as follows XX -> FF ? 00 ? 1
253 // Note: With Wrap = 0, each request from Application layer will be spilited into two request,
254 // if the current burst cross the page boundary.
255 assign page_ovflw = ({1'b0, req_len_int} > max_r2b_len) ? (req_ack && ~req_wrap) : 1'b0; // vish change
257 assign r2b_len = r2b_start ? ((page_ovflw_r) ? max_r2b_len_r : lcl_req_len) :
260 assign next_req_len = lcl_req_len - r2b_len;
262 assign next_sdr_addr = curr_sdr_addr + r2b_len;
265 assign r2b_wrap = lcl_wrap;
267 assign r2b_last = (r2b_start & !page_ovflw_r) | (req_st == `REQ_PAGE_WRAP);
271 always @ (posedge clk) begin
273 page_ovflw_r <= (req_ack) ? page_ovflw: 'h0;
275 max_r2b_len_r <= (req_ack) ? max_r2b_len: 'h0;
276 r2b_start <= (req_ack) ? 1'b1 :
277 (b2r_ack) ? 1'b0 : r2b_start;
279 r2b_write <= (req_ack) ? ~req_wr_n : r2b_write;
281 r2b_req_id <= (req_ack) ? req_id : r2b_req_id;
283 lcl_wrap <= (req_ack) ? req_wrap : lcl_wrap;
285 lcl_req_len <= (req_ack) ? req_len_int :
286 (req_ld) ? next_req_len : lcl_req_len;
288 curr_sdr_addr <= (req_ack) ? req_addr_int :
289 (req_ld) ? next_sdr_addr : curr_sdr_addr;
291 end // always @ (posedge clk)
299 next_req_st = `REQ_IDLE;
301 case (req_st) // synopsys full_case parallel_case
306 req_ack = req & b2r_arb_ok;
309 next_req_st = (req & b2r_arb_ok) ? `REQ_ACTIVE : `REQ_IDLE;
310 end // case: `REQ_IDLE
317 r2b_req = 1'b1; // req_gen to bank_req
318 next_req_st = (b2r_ack ) ? ((page_ovflw_r) ? `REQ_PAGE_WRAP :`REQ_IDLE) : `REQ_ACTIVE;
319 end // case: `REQ_ACTIVE
320 `REQ_PAGE_WRAP : begin
325 r2b_req = 1'b1; // req_gen to bank_req
326 next_req_st = (b2r_ack) ? `REQ_IDLE : `REQ_PAGE_WRAP;
327 end // case: `REQ_ACTIVE
329 endcase // case(req_st)
331 end // always @ (req_st or ....)
333 always @ (posedge clk)
338 req_st <= next_req_st;
339 end // else: !if(~reset_n)
341 // addrs bits for the bank, row and column
343 // Register row/column/bank to improve fpga timing issue
344 wire [APP_AW-1:0] map_address ;
346 assign map_address = (req_ack) ? req_addr_int :
347 (req_ld) ? next_sdr_addr : curr_sdr_addr;
349 always @ (posedge clk) begin
350 // Bank Bits are always - 2 Bits
351 r2b_ba <= (cfg_colbits == 2'b00) ? {map_address[9:8]} :
352 (cfg_colbits == 2'b01) ? {map_address[10:9]} :
353 (cfg_colbits == 2'b10) ? {map_address[11:10]} : map_address[12:11];
355 /********************
361 ************************/
362 r2b_caddr <= (cfg_colbits == 2'b00) ? {5'b0, map_address[7:0]} :
363 (cfg_colbits == 2'b01) ? {4'b0, map_address[8:0]} :
364 (cfg_colbits == 2'b10) ? {3'b0, map_address[9:0]} : {2'b0, map_address[10:0]};
366 r2b_raddr <= (cfg_colbits == 2'b00) ? map_address[22:10] :
367 (cfg_colbits == 2'b01) ? map_address[23:11] :
368 (cfg_colbits == 2'b10) ? map_address[24:12] : map_address[25:13];
371 endmodule // sdr_req_gen