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 users 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 ECC_WIDTH = 72,
76 parameter ECC_ENABLE = 0
81 input [(DQS_WIDTH*DQ_PER_DQS)-1:0] rd_data_in_rise,
82 input [(DQS_WIDTH*DQ_PER_DQS)-1:0] rd_data_in_fall,
83 input [DQS_WIDTH-1:0] ctrl_rden,
84 input [DQS_WIDTH-1:0] ctrl_rden_sel,
85 output reg [1:0] rd_ecc_error,
87 output reg [(APPDATA_WIDTH/2)-1:0] rd_data_out_rise,
88 output reg [(APPDATA_WIDTH/2)-1:0] rd_data_out_fall
91 // determine number of FIFO72's to use based on data width
92 localparam RDF_FIFO_NUM = ((APPDATA_WIDTH/2)+63)/64;
94 reg [DQS_WIDTH-1:0] ctrl_rden_r;
95 wire [(DQS_WIDTH*DQ_PER_DQS)-1:0] fall_data;
96 reg [(DQS_WIDTH*DQ_PER_DQS)-1:0] rd_data_in_fall_r;
97 reg [(DQS_WIDTH*DQ_PER_DQS)-1:0] rd_data_in_rise_r;
99 reg [DQS_WIDTH-1:0] rden_sel_r
100 /* synthesis syn_preserve=1 */;
101 wire [DQS_WIDTH-1:0] rden_sel_mux;
102 wire [(DQS_WIDTH*DQ_PER_DQS)-1:0] rise_data;
104 // ECC specific signals
105 wire [((RDF_FIFO_NUM -1) *2)+1:0] db_ecc_error;
106 reg [(DQS_WIDTH*DQ_PER_DQS)-1:0] fall_data_r;
114 wire [(APPDATA_WIDTH/2)-1:0] rd_data_out_fall_temp;
115 wire [(APPDATA_WIDTH/2)-1:0] rd_data_out_rise_temp;
117 reg [(DQS_WIDTH*DQ_PER_DQS)-1:0] rise_data_r;
118 wire [((RDF_FIFO_NUM -1) *2)+1:0] sb_ecc_error;
121 //***************************************************************************
123 always @(posedge clk0) begin
124 rden_sel_r <= ctrl_rden_sel;
125 ctrl_rden_r <= ctrl_rden;
126 rd_data_in_rise_r <= rd_data_in_rise;
127 rd_data_in_fall_r <= rd_data_in_fall;
130 // Instantiate primitive to allow this flop to be attached to multicycle
131 // path constraint in UCF. Multicycle path allowed for data from read FIFO.
132 // This is the same signal as RDEN_SEL_R, but is only used to select data
133 // (does not affect control signals)
136 for (rd_i = 0; rd_i < DQS_WIDTH; rd_i = rd_i+1) begin: gen_rden_sel_mux
137 FDRSE u_ff_rden_sel_mux
139 .Q (rden_sel_mux[rd_i]),
142 .D (ctrl_rden_sel[rd_i]),
145 ) /* synthesis syn_preserve=1 */;
149 // determine correct read data valid signal timing
150 assign rden = (rden_sel_r[0]) ? ctrl_rden[0] : ctrl_rden_r[0];
152 // assign data based on the skew
155 for(data_i = 0; data_i < DQS_WIDTH; data_i = data_i+1) begin: gen_data
156 assign rise_data[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
158 = (rden_sel_mux[data_i]) ?
159 rd_data_in_rise[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1) :
160 (data_i*DQ_PER_DQS)] :
161 rd_data_in_rise_r[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
162 (data_i*DQ_PER_DQS)];
163 assign fall_data[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
165 = (rden_sel_mux[data_i]) ?
166 rd_data_in_fall[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
167 (data_i*DQ_PER_DQS)] :
168 rd_data_in_fall_r[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
169 (data_i*DQ_PER_DQS)];
173 // Generate RST for FIFO reset AND for read/write enable:
174 // ECC FIFO always being read from and written to
175 always @(posedge clk0)
180 if (ECC_ENABLE) begin
181 always @(posedge clk0) begin
182 rd_ecc_error[0] <= (|sb_ecc_error) & fifo_rden_r5;
183 rd_ecc_error[1] <= (|db_ecc_error) & fifo_rden_r5;
184 rd_data_out_rise <= rd_data_out_rise_temp;
185 rd_data_out_fall <= rd_data_out_fall_temp;
186 rise_data_r <= rise_data;
187 fall_data_r <= fall_data;
190 // can use any of the read valids, they're all delayed by same amount
191 assign rd_data_valid = fifo_rden_r6;
193 // delay read valid to take into account max delay difference btw
194 // the read enable coming from the different DQS groups
195 always @(posedge clk0) begin
197 fifo_rden_r0 <= 1'b0;
198 fifo_rden_r1 <= 1'b0;
199 fifo_rden_r2 <= 1'b0;
200 fifo_rden_r3 <= 1'b0;
201 fifo_rden_r4 <= 1'b0;
202 fifo_rden_r5 <= 1'b0;
203 fifo_rden_r6 <= 1'b0;
205 fifo_rden_r0 <= rden;
206 fifo_rden_r1 <= fifo_rden_r0;
207 fifo_rden_r2 <= fifo_rden_r1;
208 fifo_rden_r3 <= fifo_rden_r2;
209 fifo_rden_r4 <= fifo_rden_r3;
210 fifo_rden_r5 <= fifo_rden_r4;
211 fifo_rden_r6 <= fifo_rden_r5;
215 for (rdf_i = 0; rdf_i < RDF_FIFO_NUM; rdf_i = rdf_i + 1) begin: gen_rdf
217 FIFO36_72 # // rise fifo
219 .ALMOST_EMPTY_OFFSET (9'h007),
220 .ALMOST_FULL_OFFSET (9'h00F),
221 .DO_REG (1), // extra CC output delay
222 .EN_ECC_WRITE ("FALSE"),
223 .EN_ECC_READ ("TRUE"),
225 .FIRST_WORD_FALL_THROUGH ("FALSE")
231 .DBITERR (db_ecc_error[rdf_i + rdf_i]),
232 .DO (rd_data_out_rise_temp[(64*(rdf_i+1))-1:
240 .SBITERR (sb_ecc_error[rdf_i + rdf_i]),
243 .DI (rise_data_r[((64*(rdf_i+1)) + (rdf_i*8))-1:
244 (64 *rdf_i)+(rdf_i*8)]),
245 .DIP (rise_data_r[(72*(rdf_i+1))-1:
246 (64*(rdf_i+1))+ (8*rdf_i)]),
254 FIFO36_72 # // fall_fifo
256 .ALMOST_EMPTY_OFFSET (9'h007),
257 .ALMOST_FULL_OFFSET (9'h00F),
258 .DO_REG (1), // extra CC output delay
259 .EN_ECC_WRITE ("FALSE"),
260 .EN_ECC_READ ("TRUE"),
262 .FIRST_WORD_FALL_THROUGH ("FALSE")
268 .DBITERR (db_ecc_error[(rdf_i+1) + rdf_i]),
269 .DO (rd_data_out_fall_temp[(64*(rdf_i+1))-1:
277 .SBITERR (sb_ecc_error[(rdf_i+1) + rdf_i]),
280 .DI (fall_data_r[((64*(rdf_i+1)) + (rdf_i*8))-1:
281 (64*rdf_i)+(rdf_i*8)]),
282 .DIP (fall_data_r[(72*(rdf_i+1))-1:
283 (64*(rdf_i+1))+ (8*rdf_i)]),
286 .RST (rst_r), // or can use rst0
292 assign rd_data_valid = fifo_rden_r0;
293 always @(posedge clk0) begin
294 rd_data_out_rise <= rise_data;
295 rd_data_out_fall <= fall_data;
296 fifo_rden_r0 <= rden;