1 //*****************************************************************************
2 // DISCLAIMER OF LIABILITY
4 // This text/file contains proprietary, confidential
5 // information of Xilinx, Inc., is distributed under license
6 // from Xilinx, Inc., and may be used, copied and/or
7 // disclosed only pursuant to the terms of a valid license
8 // agreement with Xilinx, Inc. Xilinx hereby grants you a
9 // license to use this text/file solely for design, simulation,
10 // implementation and creation of design files limited
11 // to Xilinx devices or technologies. Use with non-Xilinx
12 // devices or technologies is expressly prohibited and
13 // immediately terminates your license unless covered by
14 // a separate agreement.
16 // Xilinx is providing this design, code, or information
17 // "as-is" solely for use in developing programs and
18 // solutions for Xilinx devices, with no obligation on the
19 // part of Xilinx to provide support. By providing this design,
20 // code, or information as one possible implementation of
21 // this feature, application or standard, Xilinx is making no
22 // representation that this implementation is free from any
23 // claims of infringement. You are responsible for
24 // obtaining any rights you may require for your implementation.
25 // Xilinx expressly disclaims any warranty whatsoever with
26 // respect to the adequacy of the implementation, including
27 // but not limited to any warranties or representations that this
28 // implementation is free from claims of infringement, implied
29 // warranties of merchantability or fitness for a particular
32 // Xilinx products are not intended for use in life support
33 // appliances, devices, or systems. Use in such applications is
34 // expressly prohibited.
36 // Any modifications that are made to the Source Code are
37 // done at the user�s sole risk and will be unsupported.
39 // Copyright (c) 2006-2007 Xilinx, Inc. All rights reserved.
41 // This copyright and support notice must be retained as part
42 // of this text at all times.
43 //*****************************************************************************
46 // /___/ \ / Vendor: Xilinx
47 // \ \ \/ Version: 2.3
48 // \ \ Application: MIG
49 // / / Filename: ddr2_usr_rd.v
50 // /___/ /\ Date Last Modified: $Date: 2008/07/02 14:03:08 $
51 // \ \ / \ Date Created: Tue Aug 29 2006
57 // The delay between the read data with respect to the command issued is
58 // calculted in terms of no. of clocks. This data is then stored into the
59 // FIFOs and then read back and given as the ouput for comparison.
62 //*****************************************************************************
68 // Following parameters are for 72-bit RDIMM design (for ML561 Reference
69 // board design). Actual values may be different. Actual parameters values
70 // are passed from design top module ddr2_sdram module. Please refer to
71 // the ddr2_sdram module for actual values.
72 parameter DQ_PER_DQS = 8,
73 parameter DQS_WIDTH = 9,
74 parameter APPDATA_WIDTH = 144,
75 parameter APPDATA_BURST_LEN = 2,
76 parameter APPDATA_BURST_BITS = 1,
77 parameter ECC_WIDTH = 72,
78 parameter ECC_ENABLE = 0,
79 parameter EN_SYN = "FALSE"
82 input clk0, //read buffer write clock
84 //new ports by xtan & gdgib
85 input rb_clk, //read buffer read clock
86 input rb_rst, //read buffer read reset
87 output rb_full, //read buffer is full (error)
88 //end new signals by xtan & gdgib
89 input [(DQS_WIDTH*DQ_PER_DQS)-1:0] rd_data_in_rise,
90 input [(DQS_WIDTH*DQ_PER_DQS)-1:0] rd_data_in_fall,
91 input [DQS_WIDTH-1:0] ctrl_rden,
92 input [DQS_WIDTH-1:0] ctrl_rden_sel,
93 output reg [1:0] rd_ecc_error,
94 output reg rd_data_valid,
96 output reg [(APPDATA_WIDTH/2)-1:0] rd_data_out_rise,
97 output reg [(APPDATA_WIDTH/2)-1:0] rd_data_out_fall,
101 // determine number of FIFO72's to use based on data width
102 localparam RDF_FIFO_NUM = ((APPDATA_WIDTH/2)+63)/64;
104 reg [DQS_WIDTH-1:0] ctrl_rden_r;
105 wire [(DQS_WIDTH*DQ_PER_DQS)-1:0] fall_data;
106 reg [(DQS_WIDTH*DQ_PER_DQS)-1:0] rd_data_in_fall_r;
107 reg [(DQS_WIDTH*DQ_PER_DQS)-1:0] rd_data_in_rise_r;
109 reg [DQS_WIDTH-1:0] rden_sel_r
110 /* synthesis syn_preserve=1 */;
111 wire [DQS_WIDTH-1:0] rden_sel_mux;
112 wire [(DQS_WIDTH*DQ_PER_DQS)-1:0] rise_data;
114 // ECC specific signals
115 wire [((RDF_FIFO_NUM -1) *2)+1:0] db_ecc_error;
116 reg [(DQS_WIDTH*DQ_PER_DQS)-1:0] fall_data_r;
118 wire [(APPDATA_WIDTH/2)-1:0] rd_data_out_fall_temp;
119 wire [(APPDATA_WIDTH/2)-1:0] rd_data_out_rise_temp;
121 reg [(DQS_WIDTH*DQ_PER_DQS)-1:0] rise_data_r;
122 wire [((RDF_FIFO_NUM -1) *2)+1:0] sb_ecc_error;
123 wire [RDF_FIFO_NUM-1:0] rdf_empty;
124 wire fifo_read, fifo_preread;
126 reg [1:0] rd_data_valid_pre;
127 wire [RDF_FIFO_NUM-1:0] w_rb_full; //added by xtan
129 //***************************************************************************
131 reg [APPDATA_BURST_BITS-1:0] blfifo_readcount, blfifo_writecount;
132 wire blfifo_readterminal, blfifo_writeterminal;
133 wire blfifo_read, blfifo_write;
134 wire blfifo_empty, blfifo_full;
136 asyncfifo_dmem_1b blfifo (
140 .rst(rst_r | rb_rst),
142 .wr_en(blfifo_write),
144 .empty(blfifo_empty),
146 assign rd_fifo_clear = ~blfifo_full;
148 always @ (posedge rb_clk) begin
149 if (rb_rst) blfifo_readcount <= 0;
150 else if (fifo_read & ~rdf_empty[0]) begin
151 if (blfifo_readterminal) blfifo_readcount <= 0;
152 else blfifo_readcount <= blfifo_readcount + 1;
156 always @ (posedge clk0) begin
157 if (rst_r | rst0) blfifo_writecount <= 0;
158 else if (rden_r) begin
159 if (blfifo_writeterminal) blfifo_writecount <= 0;
160 else blfifo_writecount <= blfifo_writecount + 1;
164 assign blfifo_readterminal = (blfifo_readcount == (APPDATA_BURST_LEN - 1));
165 assign blfifo_writeterminal = (blfifo_writecount == (APPDATA_BURST_LEN - 1));
166 assign blfifo_read = (~|blfifo_readcount) & (fifo_read & rd_data_valid);
167 assign blfifo_write = blfifo_writeterminal & rden_r;
169 //***************************************************************************
171 always @(posedge clk0) begin
172 rden_sel_r <= ctrl_rden_sel;
173 ctrl_rden_r <= ctrl_rden;
174 rd_data_in_rise_r <= rd_data_in_rise;
175 rd_data_in_fall_r <= rd_data_in_fall;
178 // Instantiate primitive to allow this flop to be attached to multicycle
179 // path constraint in UCF. Multicycle path allowed for data from read FIFO.
180 // This is the same signal as RDEN_SEL_R, but is only used to select data
181 // (does not affect control signals)
184 for (rd_i = 0; rd_i < DQS_WIDTH; rd_i = rd_i+1) begin: gen_rden_sel_mux
185 FDRSE u_ff_rden_sel_mux
187 .Q (rden_sel_mux[rd_i]),
190 .D (ctrl_rden_sel[rd_i]),
193 ) /* synthesis syn_preserve=1 */;
197 // determine correct read data valid signal timing
198 assign rden = (rden_sel_r[0]) ? ctrl_rden[0] : ctrl_rden_r[0];
200 // assign data based on the skew
203 for(data_i = 0; data_i < DQS_WIDTH; data_i = data_i+1) begin: gen_data
204 assign rise_data[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
206 = (rden_sel_mux[data_i]) ?
207 rd_data_in_rise[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1) :
208 (data_i*DQ_PER_DQS)] :
209 rd_data_in_rise_r[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
210 (data_i*DQ_PER_DQS)];
211 assign fall_data[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
213 = (rden_sel_mux[data_i]) ?
214 rd_data_in_fall[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
215 (data_i*DQ_PER_DQS)] :
216 rd_data_in_fall_r[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
217 (data_i*DQ_PER_DQS)];
221 assign rb_full = w_rb_full[0];
223 // Generate RST for FIFO reset AND for read/write enable:
224 // ECC FIFO always being read from and written to
225 always @(posedge clk0)
228 always @(posedge clk0) begin
229 rise_data_r <= rise_data;
230 fall_data_r <= fall_data;
233 // delay read valid to take into account max delay difference btw
234 // the read enable coming from the different DQS groups
235 always @(posedge clk0) begin
236 if (rst0) rden_r <= 1'b0;
240 always @(posedge rb_clk) begin
242 rd_data_out_rise <= rd_data_out_rise_temp;
243 rd_data_out_fall <= rd_data_out_fall_temp;
246 if (rb_rst) rd_data_valid <= 1'b0;
247 else if (fifo_read) rd_data_valid <= rd_data_valid_pre[1];
250 rd_data_valid_pre <= 2'b00;
252 rd_data_valid_pre[0] <= fifo_preread & ~rdf_empty[0];
253 rd_data_valid_pre[1] <= rd_data_valid_pre[0] | (fifo_preread ? 1'b0 : rd_data_valid_pre[1]);
257 assign fifo_preread = (~|rd_data_valid_pre | (fifo_read & ^rd_data_valid_pre)) & ~(rst0 | rst_r | rb_rst);
258 assign fifo_read = (~rd_data_valid | rd_data_rden) & ~(rst0 | rst_r | rb_rst);
262 if (ECC_ENABLE) begin
263 always @(posedge rb_clk) begin
264 if (fifo_preread) begin
265 rd_ecc_error[0] <= |sb_ecc_error;
266 rd_ecc_error[1] <= |db_ecc_error;
270 for (rdf_i = 0; rdf_i < RDF_FIFO_NUM; rdf_i = rdf_i + 1) begin: gen_rdf
272 FIFO36_72 # // rise fifo
274 .ALMOST_EMPTY_OFFSET (9'h007),
275 .ALMOST_FULL_OFFSET (9'h00F),
276 .DO_REG (1), // extra CC output delay
277 .EN_ECC_WRITE ("FALSE"),
278 .EN_ECC_READ ("TRUE"),
280 .FIRST_WORD_FALL_THROUGH ("FALSE")
286 .DBITERR (db_ecc_error[rdf_i + rdf_i]),
287 .DO (rd_data_out_rise_temp[(64*(rdf_i+1))-1:
291 .EMPTY (rdf_empty[rdf_i]),
292 .FULL (w_rb_full[rdf_i]),
295 .SBITERR (sb_ecc_error[rdf_i + rdf_i]),
298 .DI (rise_data_r[((64*(rdf_i+1)) + (rdf_i*8))-1:
299 (64 *rdf_i)+(rdf_i*8)]),
300 .DIP (rise_data_r[(72*(rdf_i+1))-1:
301 (64*(rdf_i+1))+ (8*rdf_i)]),
303 .RDEN (fifo_preread),
304 .RST (rst_r | rb_rst),
309 FIFO36_72 # // fall_fifo
311 .ALMOST_EMPTY_OFFSET (9'h007),
312 .ALMOST_FULL_OFFSET (9'h00F),
313 .DO_REG (1), // extra CC output delay
314 .EN_ECC_WRITE ("FALSE"),
315 .EN_ECC_READ ("TRUE"),
317 .FIRST_WORD_FALL_THROUGH ("FALSE")
323 .DBITERR (db_ecc_error[(rdf_i+1) + rdf_i]),
324 .DO (rd_data_out_fall_temp[(64*(rdf_i+1))-1:
332 .SBITERR (sb_ecc_error[(rdf_i+1) + rdf_i]),
335 .DI (fall_data_r[((64*(rdf_i+1)) + (rdf_i*8))-1:
336 (64*rdf_i)+(rdf_i*8)]),
337 .DIP (fall_data_r[(72*(rdf_i+1))-1:
338 (64*(rdf_i+1))+ (8*rdf_i)]),
340 .RDEN (fifo_preread),
341 .RST (rst_r | rb_rst), // or can use rst0
347 for (rdf_i = 0; rdf_i < RDF_FIFO_NUM; rdf_i = rdf_i + 1) begin: gen_rdf
349 FIFO36_72 # // rise fifo
351 .ALMOST_EMPTY_OFFSET (9'h007),
352 .ALMOST_FULL_OFFSET (9'h00F),
353 .DO_REG (1), // extra CC output delay
354 .EN_ECC_WRITE ("FALSE"),
355 .EN_ECC_READ ("FALSE"),
357 .FIRST_WORD_FALL_THROUGH ("FALSE")
364 .DO (rd_data_out_rise_temp[(64*(rdf_i+1))-1:
368 .EMPTY (rdf_empty[rdf_i]),
369 .FULL (w_rb_full[rdf_i]),
375 .DI (rise_data_r[((64*(rdf_i+1)) + (rdf_i*8))-1:
376 (64 *rdf_i)+(rdf_i*8)]),
379 .RDEN (fifo_preread),
380 .RST (rst_r | rb_rst),
385 FIFO36_72 # // fall_fifo
387 .ALMOST_EMPTY_OFFSET (9'h007),
388 .ALMOST_FULL_OFFSET (9'h00F),
389 .DO_REG (1), // extra CC output delay
390 .EN_ECC_WRITE ("FALSE"),
391 .EN_ECC_READ ("FALSE"),
393 .FIRST_WORD_FALL_THROUGH ("FALSE")
400 .DO (rd_data_out_fall_temp[(64*(rdf_i+1))-1:
411 .DI (fall_data_r[((64*(rdf_i+1)) + (rdf_i*8))-1:
412 (64*rdf_i)+(rdf_i*8)]),
415 .RDEN (fifo_preread),
416 .RST (rst_r | rb_rst), // or can use rst0