source: XOpenSparcT1/trunk/Xilinx/ddr2_usr_rd.v @ 10

Revision 10, 11.5 KB checked in by pntsvt00, 14 years ago (diff)

versione sintetizzabile

Line 
1//*****************************************************************************
2// DISCLAIMER OF LIABILITY
3//
4// This file contains proprietary and confidential information of
5// Xilinx, Inc. ("Xilinx"), that is distributed under a license
6// from Xilinx, and may be used, copied and/or disclosed only
7// pursuant to the terms of a valid license agreement with Xilinx.
8//
9// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION
10// ("MATERIALS") "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
11// EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING WITHOUT
12// LIMITATION, ANY WARRANTY WITH RESPECT TO NONINFRINGEMENT,
13// MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. Xilinx
14// does not warrant that functions included in the Materials will
15// meet the requirements of Licensee, or that the operation of the
16// Materials will be uninterrupted or error-free, or that defects
17// in the Materials will be corrected. Furthermore, Xilinx does
18// not warrant or make any representations regarding use, or the
19// results of the use, of the Materials in terms of correctness,
20// accuracy, reliability or otherwise.
21//
22// Xilinx products are not designed or intended to be fail-safe,
23// or for use in any application requiring fail-safe performance,
24// such as life-support or safety devices or systems, Class III
25// medical devices, nuclear facilities, applications related to
26// the deployment of airbags, or any other applications that could
27// lead to death, personal injury or severe property or
28// environmental damage (individually and collectively, "critical
29// applications"). Customer assumes the sole risk and liability
30// of any use of Xilinx products in critical applications,
31// subject only to applicable laws and regulations governing
32// limitations on product liability.
33//
34// Copyright 2006, 2007, 2008 Xilinx, Inc.
35// All rights reserved.
36//
37// This disclaimer and copyright notice must be retained as part
38// of this file at all times.
39//*****************************************************************************
40//   ____  ____
41//  /   /\/   /
42// /___/  \  /    Vendor: Xilinx
43// \   \   \/     Version: 3.6
44//  \   \         Application: MIG
45//  /   /         Filename: ddr2_usr_rd.v
46// /___/   /\     Date Last Modified: $Date: 2010/06/29 12:03:43 $
47// \   \  /  \    Date Created: Tue Aug 29 2006
48//  \___\/\___\
49//
50//Device: Virtex-5
51//Design Name: DDR2
52//Purpose:
53//   The delay between the read data with respect to the command issued is
54//   calculted in terms of no. of clocks. This data is then stored into the
55//   FIFOs and then read back and given as the ouput for comparison.
56//Reference:
57//Revision History:
58//*****************************************************************************
59
60`timescale 1ns/1ps
61
62module ddr2_usr_rd #
63  (
64   // Following parameters are for 72-bit RDIMM design (for ML561 Reference
65   // board design). Actual values may be different. Actual parameters values
66   // are passed from design top module dram module. Please refer to
67   // the dram module for actual values.
68   parameter DQ_PER_DQS    = 8,
69   parameter DQS_WIDTH     = 9,
70   parameter APPDATA_WIDTH = 144,
71   parameter ECC_WIDTH     = 72,
72   parameter ECC_ENABLE    = 0
73   )
74  (
75   input                                    clk0,
76   input                                    rst0,
77   input [(DQS_WIDTH*DQ_PER_DQS)-1:0]       rd_data_in_rise,
78   input [(DQS_WIDTH*DQ_PER_DQS)-1:0]       rd_data_in_fall,
79   input [DQS_WIDTH-1:0]                    ctrl_rden,
80   input [DQS_WIDTH-1:0]                    ctrl_rden_sel,
81   output reg [1:0]                         rd_ecc_error,
82   output                                   rd_data_valid,
83   output reg [(APPDATA_WIDTH/2)-1:0]       rd_data_out_rise,
84   output reg [(APPDATA_WIDTH/2)-1:0]       rd_data_out_fall
85   );
86
87  // determine number of FIFO72's to use based on data width
88  localparam RDF_FIFO_NUM = ((APPDATA_WIDTH/2)+63)/64;
89
90  reg [DQS_WIDTH-1:0]               ctrl_rden_r;
91  wire [(DQS_WIDTH*DQ_PER_DQS)-1:0] fall_data;
92  reg [(DQS_WIDTH*DQ_PER_DQS)-1:0]  rd_data_in_fall_r;
93  reg [(DQS_WIDTH*DQ_PER_DQS)-1:0]  rd_data_in_rise_r;
94  wire                              rden;
95  reg [DQS_WIDTH-1:0]               rden_sel_r
96                                    /* synthesis syn_preserve=1 */;
97  wire [DQS_WIDTH-1:0]              rden_sel_mux;
98  wire [(DQS_WIDTH*DQ_PER_DQS)-1:0] rise_data;
99
100  // ECC specific signals
101  wire [((RDF_FIFO_NUM -1) *2)+1:0] db_ecc_error;
102  reg [(DQS_WIDTH*DQ_PER_DQS)-1:0]  fall_data_r;
103  reg                               fifo_rden_r0;
104  reg                               fifo_rden_r1;
105  reg                               fifo_rden_r2;
106  reg                               fifo_rden_r3;
107  reg                               fifo_rden_r4;
108  reg                               fifo_rden_r5;
109  reg                               fifo_rden_r6;
110  wire [(APPDATA_WIDTH/2)-1:0]      rd_data_out_fall_temp;
111  wire [(APPDATA_WIDTH/2)-1:0]      rd_data_out_rise_temp;
112  reg                               rst_r;
113  reg [(DQS_WIDTH*DQ_PER_DQS)-1:0]  rise_data_r;
114  wire [((RDF_FIFO_NUM -1) *2)+1:0] sb_ecc_error;
115
116
117  //***************************************************************************
118
119  always @(posedge clk0) begin
120    rden_sel_r        <= ctrl_rden_sel;
121    ctrl_rden_r       <= ctrl_rden;
122    rd_data_in_rise_r <= rd_data_in_rise;
123    rd_data_in_fall_r <= rd_data_in_fall;
124  end
125
126  // Instantiate primitive to allow this flop to be attached to multicycle
127  // path constraint in UCF. Multicycle path allowed for data from read FIFO.
128  // This is the same signal as RDEN_SEL_R, but is only used to select data
129  // (does not affect control signals)
130  genvar rd_i;
131  generate
132    for (rd_i = 0; rd_i < DQS_WIDTH; rd_i = rd_i+1) begin: gen_rden_sel_mux
133      FDRSE u_ff_rden_sel_mux
134        (
135         .Q   (rden_sel_mux[rd_i]),
136         .C   (clk0),
137         .CE  (1'b1),
138         .D   (ctrl_rden_sel[rd_i]),
139         .R   (1'b0),
140         .S   (1'b0)
141         ) /* synthesis syn_preserve=1 */;
142    end
143  endgenerate
144
145  // determine correct read data valid signal timing
146  assign rden = (rden_sel_r[0]) ? ctrl_rden[0] : ctrl_rden_r[0];
147
148  // assign data based on the skew
149  genvar data_i;
150  generate
151    for(data_i = 0; data_i < DQS_WIDTH; data_i = data_i+1) begin: gen_data
152      assign rise_data[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
153                       (data_i*DQ_PER_DQS)]
154               = (rden_sel_mux[data_i]) ?
155                 rd_data_in_rise[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1) :
156                                 (data_i*DQ_PER_DQS)] :
157                 rd_data_in_rise_r[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
158                                   (data_i*DQ_PER_DQS)];
159       assign fall_data[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
160                        (data_i*DQ_PER_DQS)]
161                = (rden_sel_mux[data_i]) ?
162                  rd_data_in_fall[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
163                                  (data_i*DQ_PER_DQS)] :
164                  rd_data_in_fall_r[(data_i*DQ_PER_DQS)+(DQ_PER_DQS-1):
165                                    (data_i*DQ_PER_DQS)];
166    end
167  endgenerate
168
169  // Generate RST for FIFO reset AND for read/write enable:
170  // ECC FIFO always being read from and written to
171  always @(posedge clk0)
172    rst_r <= rst0;
173
174  genvar rdf_i;
175  generate
176    if (ECC_ENABLE) begin
177      always @(posedge clk0) begin
178        rd_ecc_error[0]   <= (|sb_ecc_error) & fifo_rden_r5;
179        rd_ecc_error[1]   <= (|db_ecc_error) & fifo_rden_r5;
180        rd_data_out_rise  <= rd_data_out_rise_temp;
181        rd_data_out_fall  <= rd_data_out_fall_temp;
182        rise_data_r       <= rise_data;
183        fall_data_r       <= fall_data;
184      end
185
186      // can use any of the read valids, they're all delayed by same amount
187      assign rd_data_valid = fifo_rden_r6;
188
189      // delay read valid to take into account max delay difference btw
190      // the read enable coming from the different DQS groups
191      always @(posedge clk0) begin
192        if (rst0) begin
193          fifo_rden_r0 <= 1'b0;
194          fifo_rden_r1 <= 1'b0;
195          fifo_rden_r2 <= 1'b0;
196          fifo_rden_r3 <= 1'b0;
197          fifo_rden_r4 <= 1'b0;
198          fifo_rden_r5 <= 1'b0;
199          fifo_rden_r6 <= 1'b0;
200        end else begin
201          fifo_rden_r0 <= rden;
202          fifo_rden_r1 <= fifo_rden_r0;
203          fifo_rden_r2 <= fifo_rden_r1;
204          fifo_rden_r3 <= fifo_rden_r2;
205          fifo_rden_r4 <= fifo_rden_r3;
206          fifo_rden_r5 <= fifo_rden_r4;
207          fifo_rden_r6 <= fifo_rden_r5;
208        end
209      end
210
211      for (rdf_i = 0; rdf_i < RDF_FIFO_NUM; rdf_i = rdf_i + 1) begin: gen_rdf
212
213        FIFO36_72  # // rise fifo
214          (
215           .ALMOST_EMPTY_OFFSET     (9'h007),
216           .ALMOST_FULL_OFFSET      (9'h00F),
217           .DO_REG                  (1),          // extra CC output delay
218           .EN_ECC_WRITE            ("FALSE"),
219           .EN_ECC_READ             ("TRUE"),
220           .EN_SYN                  ("FALSE"),
221           .FIRST_WORD_FALL_THROUGH ("FALSE")
222           )
223          u_rdf
224            (
225             .ALMOSTEMPTY (),
226             .ALMOSTFULL  (),
227             .DBITERR     (db_ecc_error[rdf_i + rdf_i]),
228             .DO          (rd_data_out_rise_temp[(64*(rdf_i+1))-1:
229                                                 (64 *rdf_i)]),
230             .DOP         (),
231             .ECCPARITY   (),
232             .EMPTY       (),
233             .FULL        (),
234             .RDCOUNT     (),
235             .RDERR       (),
236             .SBITERR     (sb_ecc_error[rdf_i + rdf_i]),
237             .WRCOUNT     (),
238             .WRERR       (),
239             .DI          (rise_data_r[((64*(rdf_i+1)) + (rdf_i*8))-1:
240                                       (64 *rdf_i)+(rdf_i*8)]),
241             .DIP         (rise_data_r[(72*(rdf_i+1))-1:
242                                       (64*(rdf_i+1))+ (8*rdf_i)]),
243             .RDCLK       (clk0),
244             .RDEN        (~rst_r),
245             .RST         (rst_r),
246             .WRCLK       (clk0),
247             .WREN        (~rst_r)
248             );
249
250        FIFO36_72  # // fall_fifo
251          (
252           .ALMOST_EMPTY_OFFSET     (9'h007),
253           .ALMOST_FULL_OFFSET      (9'h00F),
254           .DO_REG                  (1),          // extra CC output delay
255           .EN_ECC_WRITE            ("FALSE"),
256           .EN_ECC_READ             ("TRUE"),
257           .EN_SYN                  ("FALSE"),
258           .FIRST_WORD_FALL_THROUGH ("FALSE")
259           )
260          u_rdf1
261            (
262             .ALMOSTEMPTY (),
263             .ALMOSTFULL  (),
264             .DBITERR     (db_ecc_error[(rdf_i+1) + rdf_i]),
265             .DO          (rd_data_out_fall_temp[(64*(rdf_i+1))-1:
266                                                 (64 *rdf_i)]),
267             .DOP         (),
268             .ECCPARITY   (),
269             .EMPTY       (),
270             .FULL        (),
271             .RDCOUNT     (),
272             .RDERR       (),
273             .SBITERR     (sb_ecc_error[(rdf_i+1) + rdf_i]),
274             .WRCOUNT     (),
275             .WRERR       (),
276             .DI          (fall_data_r[((64*(rdf_i+1)) + (rdf_i*8))-1:
277                                       (64*rdf_i)+(rdf_i*8)]),
278             .DIP         (fall_data_r[(72*(rdf_i+1))-1:
279                                       (64*(rdf_i+1))+ (8*rdf_i)]),
280             .RDCLK       (clk0),
281             .RDEN        (~rst_r),
282             .RST         (rst_r),          // or can use rst0
283             .WRCLK       (clk0),
284             .WREN        (~rst_r)
285             );
286      end
287    end else begin
288      assign rd_data_valid = fifo_rden_r0;
289      always @(posedge clk0) begin
290        rd_data_out_rise <= rise_data;
291        rd_data_out_fall <= fall_data;
292        fifo_rden_r0 <= rden;
293      end
294    end
295  endgenerate
296
297endmodule
Note: See TracBrowser for help on using the repository browser.