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_phy_dq_iob.v |
---|
46 | // /___/ /\ Date Last Modified: $Date: 2010/06/29 12:03:43 $ |
---|
47 | // \ \ / \ Date Created: Wed Aug 16 2006 |
---|
48 | // \___\/\___\ |
---|
49 | // |
---|
50 | //Device: Virtex-5 |
---|
51 | //Design Name: DDR2 |
---|
52 | //Purpose: |
---|
53 | // This module places the data in the IOBs. |
---|
54 | //Reference: |
---|
55 | //Revision History: |
---|
56 | // Rev 1.1 - Parameter HIGH_PERFORMANCE_MODE added. PK. 7/10/08 |
---|
57 | // Rev 1.2 - DIRT strings removed and modified the code. PK. 11/13/08 |
---|
58 | // Rev 1.3 - Parameter IODELAY_GRP added and constraint IODELAY_GROUP added |
---|
59 | // on IODELAY primitive. PK. 11/27/08 |
---|
60 | //***************************************************************************** |
---|
61 | |
---|
62 | `timescale 1ns/1ps |
---|
63 | |
---|
64 | module ddr2_phy_dq_iob # |
---|
65 | ( |
---|
66 | // Following parameters are for 72-bit RDIMM design (for ML561 Reference |
---|
67 | // board design). Actual values may be different. Actual parameters values |
---|
68 | // are passed from design top module dram module. Please refer to |
---|
69 | // the dram module for actual values. |
---|
70 | parameter HIGH_PERFORMANCE_MODE = "TRUE", |
---|
71 | parameter IODELAY_GRP = "IODELAY_MIG", |
---|
72 | parameter FPGA_SPEED_GRADE = 2 |
---|
73 | ) |
---|
74 | ( |
---|
75 | input clk0, |
---|
76 | input clk90, |
---|
77 | input clkdiv0, |
---|
78 | input rst90, |
---|
79 | input dlyinc, |
---|
80 | input dlyce, |
---|
81 | input dlyrst, |
---|
82 | input [1:0] dq_oe_n, |
---|
83 | input dqs, |
---|
84 | input ce, |
---|
85 | input rd_data_sel, |
---|
86 | input wr_data_rise, |
---|
87 | input wr_data_fall, |
---|
88 | output rd_data_rise, |
---|
89 | output rd_data_fall, |
---|
90 | inout ddr_dq |
---|
91 | ); |
---|
92 | |
---|
93 | wire dq_iddr_clk; |
---|
94 | wire dq_idelay; |
---|
95 | wire dq_in; |
---|
96 | wire dq_oe_n_r; |
---|
97 | wire dq_out; |
---|
98 | wire stg2a_out_fall; |
---|
99 | wire stg2a_out_rise; |
---|
100 | (* XIL_PAR_DELAY = "0 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *) |
---|
101 | wire stg2b_out_fall; |
---|
102 | (* XIL_PAR_DELAY = "0 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *) |
---|
103 | wire stg2b_out_rise; |
---|
104 | wire stg3a_out_fall; |
---|
105 | wire stg3a_out_rise; |
---|
106 | wire stg3b_out_fall; |
---|
107 | wire stg3b_out_rise; |
---|
108 | |
---|
109 | //*************************************************************************** |
---|
110 | // Directed routing constraints for route between IDDR and stage 2 capture |
---|
111 | // in fabric. |
---|
112 | // Only 2 out of the 12 wire declarations will be used for any given |
---|
113 | // instantiation of this module. |
---|
114 | // Varies according: |
---|
115 | // (1) I/O column (left, center, right) used |
---|
116 | // (2) Which I/O in I/O pair (master, slave) used |
---|
117 | // Nomenclature: _Xy, X = column (0 = left, 1 = center, 2 = right), |
---|
118 | // y = master or slave |
---|
119 | //*************************************************************************** |
---|
120 | |
---|
121 | // MODIFIED, RC, 06/13/08: Remove all references to DIRT, master/slave |
---|
122 | |
---|
123 | (* XIL_PAR_DELAY = "515 ps", XIL_PAR_SKEW = "55 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *) |
---|
124 | wire stg1_out_rise_sg3; |
---|
125 | (* XIL_PAR_DELAY = "515 ps", XIL_PAR_SKEW = "55 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *) |
---|
126 | wire stg1_out_fall_sg3; |
---|
127 | (* XIL_PAR_DELAY = "575 ps", XIL_PAR_SKEW = "65 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *) |
---|
128 | wire stg1_out_rise_sg2; |
---|
129 | (* XIL_PAR_DELAY = "575 ps", XIL_PAR_SKEW = "65 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *) |
---|
130 | wire stg1_out_fall_sg2; |
---|
131 | (* XIL_PAR_DELAY = "650 ps", XIL_PAR_SKEW = "70 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *) |
---|
132 | wire stg1_out_rise_sg1; |
---|
133 | (* XIL_PAR_DELAY = "650 ps", XIL_PAR_SKEW = "70 ps", XIL_PAR_IP_NAME = "MIG", syn_keep = "1", keep = "TRUE" *) |
---|
134 | wire stg1_out_fall_sg1; |
---|
135 | |
---|
136 | //*************************************************************************** |
---|
137 | // Bidirectional I/O |
---|
138 | //*************************************************************************** |
---|
139 | |
---|
140 | IOBUF u_iobuf_dq |
---|
141 | ( |
---|
142 | .I (dq_out), |
---|
143 | .T (dq_oe_n_r), |
---|
144 | .IO (ddr_dq), |
---|
145 | .O (dq_in) |
---|
146 | ); |
---|
147 | |
---|
148 | //*************************************************************************** |
---|
149 | // Write (output) path |
---|
150 | //*************************************************************************** |
---|
151 | |
---|
152 | // on a write, rising edge of DQS corresponds to rising edge of CLK180 |
---|
153 | // (aka falling edge of CLK0 -> rising edge DQS). We also know: |
---|
154 | // 1. data must be driven 1/4 clk cycle before corresponding DQS edge |
---|
155 | // 2. first rising DQS edge driven on falling edge of CLK0 |
---|
156 | // 3. rising data must be driven 1/4 cycle before falling edge of CLK0 |
---|
157 | // 4. therefore, rising data driven on rising edge of CLK |
---|
158 | ODDR # |
---|
159 | ( |
---|
160 | .SRTYPE("SYNC"), |
---|
161 | .DDR_CLK_EDGE("SAME_EDGE") |
---|
162 | ) |
---|
163 | u_oddr_dq |
---|
164 | ( |
---|
165 | .Q (dq_out), |
---|
166 | .C (clk90), |
---|
167 | .CE (1'b1), |
---|
168 | .D1 (wr_data_rise), |
---|
169 | .D2 (wr_data_fall), |
---|
170 | .R (1'b0), |
---|
171 | .S (1'b0) |
---|
172 | ); |
---|
173 | |
---|
174 | // make sure output is tri-state during reset (DQ_OE_N_R = 1) |
---|
175 | ODDR # |
---|
176 | ( |
---|
177 | .SRTYPE("ASYNC"), |
---|
178 | .DDR_CLK_EDGE("SAME_EDGE") |
---|
179 | ) |
---|
180 | u_tri_state_dq |
---|
181 | ( |
---|
182 | .Q (dq_oe_n_r), |
---|
183 | .C (clk90), |
---|
184 | .CE (1'b1), |
---|
185 | .D1 (dq_oe_n[0]), |
---|
186 | .D2 (dq_oe_n[1]), |
---|
187 | .R (1'b0), |
---|
188 | .S (rst90) |
---|
189 | ); |
---|
190 | |
---|
191 | //*************************************************************************** |
---|
192 | // Read data capture scheme description: |
---|
193 | // Data capture consists of 3 ranks of flops, and a MUX |
---|
194 | // 1. Rank 1 ("Stage 1"): IDDR captures delayed DDR DQ from memory using |
---|
195 | // delayed DQS. |
---|
196 | // - Data is split into 2 SDR streams, one each for rise and fall data. |
---|
197 | // - BUFIO (DQS) input inverted to IDDR. IDDR configured in SAME_EDGE |
---|
198 | // mode. This means that: (1) Q1 = fall data, Q2 = rise data, |
---|
199 | // (2) Both rise and fall data are output on falling edge of DQS - |
---|
200 | // rather than rise output being output on one edge of DQS, and fall |
---|
201 | // data on the other edge if the IDDR were configured in OPPOSITE_EDGE |
---|
202 | // mode. This simplifies Stage 2 capture (only one core clock edge |
---|
203 | // used, removing effects of duty-cycle-distortion), and saves one |
---|
204 | // fabric flop in Rank 3. |
---|
205 | // 2. Rank 2 ("Stage 2"): Fabric flops are used to capture output of first |
---|
206 | // rank into FPGA clock (CLK) domain. Each rising/falling SDR stream |
---|
207 | // from IDDR is feed into two flops, one clocked off rising and one off |
---|
208 | // falling edge of CLK. One of these flops is chosen, with the choice |
---|
209 | // being the one that reduces # of DQ/DQS taps necessary to align Stage |
---|
210 | // 1 and Stage 2. Same edge is used to capture both rise and fall SDR |
---|
211 | // streams. |
---|
212 | // 3. Rank 3 ("Stage 3"): Removes half-cycle paths in CLK domain from |
---|
213 | // output of Rank 2. This stage, like Stage 2, is clocked by CLK. Note |
---|
214 | // that Stage 3 can be expanded to also support SERDES functionality |
---|
215 | // 4. Output MUX: Selects whether Stage 1 output is aligned to rising or |
---|
216 | // falling edge of CLK (i.e. specifically this selects whether IDDR |
---|
217 | // rise/fall output is transfered to rising or falling edge of CLK). |
---|
218 | // Implementation: |
---|
219 | // 1. Rank 1 is implemented using an IDDR primitive |
---|
220 | // 2. Rank 2 is implemented using: |
---|
221 | // - An RPM to fix the location of the capture flops near the DQ I/O. |
---|
222 | // The exact RPM used depends on which I/O column (left, center, |
---|
223 | // right) the DQ I/O is placed at - this affects the optimal location |
---|
224 | // of the slice flops (or does it - can we always choose the two |
---|
225 | // columns to slices to the immediate right of the I/O to use, no |
---|
226 | // matter what the column?). The origin of the RPM must be set in the |
---|
227 | // UCF file using the RLOC_ORIGIN constraint (where the original is |
---|
228 | // based on the DQ I/O location). |
---|
229 | // - Directed Routing Constraints ("DIRT strings") to fix the routing |
---|
230 | // to the rank 2 fabric flops. This is done to minimize: (1) total |
---|
231 | // route delay (and therefore minimize voltage/temperature-related |
---|
232 | // variations), and (2) minimize skew both within each rising and |
---|
233 | // falling data net, as well as between the rising and falling nets. |
---|
234 | // The exact DIRT string used depends on: (1) which I/O column the |
---|
235 | // DQ I/O is placed, and (2) whether the DQ I/O is placed on the |
---|
236 | // "Master" or "Slave" I/O of a diff pair (DQ is not differential, but |
---|
237 | // the routing will be affected by which of each I/O pair is used) |
---|
238 | // 3. Rank 3 is implemented using fabric flops. No LOC or DIRT contraints |
---|
239 | // are used, tools are expected to place these and meet PERIOD timing |
---|
240 | // without constraints (constraints may be necessary for "full" designs, |
---|
241 | // in this case, user may need to add LOC constraints - if this is the |
---|
242 | // case, there are no constraints - other than meeting PERIOD timing - |
---|
243 | // for rank 3 flops. |
---|
244 | //*************************************************************************** |
---|
245 | |
---|
246 | //*************************************************************************** |
---|
247 | // MIG 2.2: Define AREA_GROUP = "DDR_CAPTURE_FFS" contain all RPM flops in |
---|
248 | // design. In UCF file, add constraint: |
---|
249 | // AREA_GROUP "DDR_CAPTURE_FFS" GROUP = CLOSED; |
---|
250 | // This is done to prevent MAP from packing unrelated logic into |
---|
251 | // the slices used by the RPMs. Doing so may cause the DIRT strings |
---|
252 | // that define the IDDR -> fabric flop routing to later become |
---|
253 | // unroutable during PAR because the unrelated logic placed by MAP |
---|
254 | // may use routing resources required by the DIRT strings. MAP |
---|
255 | // does not currently take into account DIRT strings when placing |
---|
256 | // logic |
---|
257 | //*************************************************************************** |
---|
258 | |
---|
259 | // IDELAY to delay incoming data for synchronization purposes |
---|
260 | (* IODELAY_GROUP = IODELAY_GRP *) IODELAY # |
---|
261 | ( |
---|
262 | .DELAY_SRC ("I"), |
---|
263 | .IDELAY_TYPE ("VARIABLE"), |
---|
264 | .HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE), |
---|
265 | .IDELAY_VALUE (0), |
---|
266 | .ODELAY_VALUE (0) |
---|
267 | ) |
---|
268 | u_idelay_dq |
---|
269 | ( |
---|
270 | .DATAOUT (dq_idelay), |
---|
271 | .C (clkdiv0), |
---|
272 | .CE (dlyce), |
---|
273 | .DATAIN (), |
---|
274 | .IDATAIN (dq_in), |
---|
275 | .INC (dlyinc), |
---|
276 | .ODATAIN (), |
---|
277 | .RST (dlyrst), |
---|
278 | .T () |
---|
279 | ); |
---|
280 | |
---|
281 | //*************************************************************************** |
---|
282 | // Rank 1 capture: Use IDDR to generate two SDR outputs |
---|
283 | //*************************************************************************** |
---|
284 | |
---|
285 | // invert clock to IDDR in order to use SAME_EDGE mode (otherwise, we "run |
---|
286 | // out of clocks" because DQS is not continuous |
---|
287 | assign dq_iddr_clk = ~dqs; |
---|
288 | |
---|
289 | //*************************************************************************** |
---|
290 | // Rank 2 capture: Use fabric flops to capture Rank 1 output. Use RPM and |
---|
291 | // DIRT strings here. |
---|
292 | // BEL ("Basic Element of Logic") and relative location constraints for |
---|
293 | // second stage capture. C |
---|
294 | // Varies according: |
---|
295 | // (1) I/O column (left, center, right) used |
---|
296 | // (2) Which I/O in I/O pair (master, slave) used |
---|
297 | //*************************************************************************** |
---|
298 | |
---|
299 | // MODIFIED, RC, 06/13/08: Remove all references to DIRT, master/slave |
---|
300 | // Take out generate statements - collapses to a single case |
---|
301 | |
---|
302 | generate |
---|
303 | if (FPGA_SPEED_GRADE == 3) begin: gen_stg2_sg3 |
---|
304 | IDDR # |
---|
305 | ( |
---|
306 | .DDR_CLK_EDGE ("SAME_EDGE") |
---|
307 | ) |
---|
308 | u_iddr_dq |
---|
309 | ( |
---|
310 | .Q1 (stg1_out_fall_sg3), |
---|
311 | .Q2 (stg1_out_rise_sg3), |
---|
312 | .C (dq_iddr_clk), |
---|
313 | .CE (ce), |
---|
314 | .D (dq_idelay), |
---|
315 | .R (1'b0), |
---|
316 | .S (1'b0) |
---|
317 | ); |
---|
318 | |
---|
319 | //********************************************************* |
---|
320 | // Slice #1 (posedge CLK): Used for: |
---|
321 | // 1. IDDR transfer to CLK0 rising edge domain ("stg2a") |
---|
322 | // 2. stg2 falling edge -> stg3 rising edge transfer |
---|
323 | //********************************************************* |
---|
324 | |
---|
325 | // Stage 2 capture |
---|
326 | FDRSE u_ff_stg2a_fall |
---|
327 | ( |
---|
328 | .Q (stg2a_out_fall), |
---|
329 | .C (clk0), |
---|
330 | .CE (1'b1), |
---|
331 | .D (stg1_out_fall_sg3), |
---|
332 | .R (1'b0), |
---|
333 | .S (1'b0) |
---|
334 | )/* synthesis syn_preserve = 1 */ |
---|
335 | /* synthesis syn_replicate = 0 */; |
---|
336 | FDRSE u_ff_stg2a_rise |
---|
337 | ( |
---|
338 | .Q (stg2a_out_rise), |
---|
339 | .C (clk0), |
---|
340 | .CE (1'b1), |
---|
341 | .D (stg1_out_rise_sg3), |
---|
342 | .R (1'b0), |
---|
343 | .S (1'b0) |
---|
344 | )/* synthesis syn_preserve = 1 */ |
---|
345 | /* synthesis syn_replicate = 0 */; |
---|
346 | // Stage 3 falling -> rising edge translation |
---|
347 | FDRSE u_ff_stg3b_fall |
---|
348 | ( |
---|
349 | .Q (stg3b_out_fall), |
---|
350 | .C (clk0), |
---|
351 | .CE (1'b1), |
---|
352 | .D (stg2b_out_fall), |
---|
353 | .R (1'b0), |
---|
354 | .S (1'b0) |
---|
355 | )/* synthesis syn_preserve = 1 */ |
---|
356 | /* synthesis syn_replicate = 0 */; |
---|
357 | FDRSE u_ff_stg3b_rise |
---|
358 | ( |
---|
359 | .Q (stg3b_out_rise), |
---|
360 | .C (clk0), |
---|
361 | .CE (1'b1), |
---|
362 | .D (stg2b_out_rise), |
---|
363 | .R (1'b0), |
---|
364 | .S (1'b0) |
---|
365 | )/* synthesis syn_preserve = 1 */ |
---|
366 | /* synthesis syn_replicate = 0 */; |
---|
367 | |
---|
368 | //********************************************************* |
---|
369 | // Slice #2 (posedge CLK): Used for: |
---|
370 | // 1. IDDR transfer to CLK0 falling edge domain ("stg2b") |
---|
371 | //********************************************************* |
---|
372 | |
---|
373 | FDRSE_1 u_ff_stg2b_fall |
---|
374 | ( |
---|
375 | .Q (stg2b_out_fall), |
---|
376 | .C (clk0), |
---|
377 | .CE (1'b1), |
---|
378 | .D (stg1_out_fall_sg3), |
---|
379 | .R (1'b0), |
---|
380 | .S (1'b0) |
---|
381 | )/* synthesis syn_preserve = 1 */ |
---|
382 | /* synthesis syn_replicate = 0 */; |
---|
383 | |
---|
384 | FDRSE_1 u_ff_stg2b_rise |
---|
385 | ( |
---|
386 | .Q (stg2b_out_rise), |
---|
387 | .C (clk0), |
---|
388 | .CE (1'b1), |
---|
389 | .D (stg1_out_rise_sg3), |
---|
390 | .R (1'b0), |
---|
391 | .S (1'b0) |
---|
392 | )/* synthesis syn_preserve = 1 */ |
---|
393 | /* synthesis syn_replicate = 0 */; |
---|
394 | end else if (FPGA_SPEED_GRADE == 2) begin: gen_stg2_sg2 |
---|
395 | IDDR # |
---|
396 | ( |
---|
397 | .DDR_CLK_EDGE ("SAME_EDGE") |
---|
398 | ) |
---|
399 | u_iddr_dq |
---|
400 | ( |
---|
401 | .Q1 (stg1_out_fall_sg2), |
---|
402 | .Q2 (stg1_out_rise_sg2), |
---|
403 | .C (dq_iddr_clk), |
---|
404 | .CE (ce), |
---|
405 | .D (dq_idelay), |
---|
406 | .R (1'b0), |
---|
407 | .S (1'b0) |
---|
408 | ); |
---|
409 | |
---|
410 | //********************************************************* |
---|
411 | // Slice #1 (posedge CLK): Used for: |
---|
412 | // 1. IDDR transfer to CLK0 rising edge domain ("stg2a") |
---|
413 | // 2. stg2 falling edge -> stg3 rising edge transfer |
---|
414 | //********************************************************* |
---|
415 | |
---|
416 | // Stage 2 capture |
---|
417 | FDRSE u_ff_stg2a_fall |
---|
418 | ( |
---|
419 | .Q (stg2a_out_fall), |
---|
420 | .C (clk0), |
---|
421 | .CE (1'b1), |
---|
422 | .D (stg1_out_fall_sg2), |
---|
423 | .R (1'b0), |
---|
424 | .S (1'b0) |
---|
425 | )/* synthesis syn_preserve = 1 */ |
---|
426 | /* synthesis syn_replicate = 0 */; |
---|
427 | FDRSE u_ff_stg2a_rise |
---|
428 | ( |
---|
429 | .Q (stg2a_out_rise), |
---|
430 | .C (clk0), |
---|
431 | .CE (1'b1), |
---|
432 | .D (stg1_out_rise_sg2), |
---|
433 | .R (1'b0), |
---|
434 | .S (1'b0) |
---|
435 | )/* synthesis syn_preserve = 1 */ |
---|
436 | /* synthesis syn_replicate = 0 */; |
---|
437 | // Stage 3 falling -> rising edge translation |
---|
438 | FDRSE u_ff_stg3b_fall |
---|
439 | ( |
---|
440 | .Q (stg3b_out_fall), |
---|
441 | .C (clk0), |
---|
442 | .CE (1'b1), |
---|
443 | .D (stg2b_out_fall), |
---|
444 | .R (1'b0), |
---|
445 | .S (1'b0) |
---|
446 | )/* synthesis syn_preserve = 1 */ |
---|
447 | /* synthesis syn_replicate = 0 */; |
---|
448 | FDRSE u_ff_stg3b_rise |
---|
449 | ( |
---|
450 | .Q (stg3b_out_rise), |
---|
451 | .C (clk0), |
---|
452 | .CE (1'b1), |
---|
453 | .D (stg2b_out_rise), |
---|
454 | .R (1'b0), |
---|
455 | .S (1'b0) |
---|
456 | )/* synthesis syn_preserve = 1 */ |
---|
457 | /* synthesis syn_replicate = 0 */; |
---|
458 | |
---|
459 | //********************************************************* |
---|
460 | // Slice #2 (posedge CLK): Used for: |
---|
461 | // 1. IDDR transfer to CLK0 falling edge domain ("stg2b") |
---|
462 | //********************************************************* |
---|
463 | |
---|
464 | FDRSE_1 u_ff_stg2b_fall |
---|
465 | ( |
---|
466 | .Q (stg2b_out_fall), |
---|
467 | .C (clk0), |
---|
468 | .CE (1'b1), |
---|
469 | .D (stg1_out_fall_sg2), |
---|
470 | .R (1'b0), |
---|
471 | .S (1'b0) |
---|
472 | )/* synthesis syn_preserve = 1 */ |
---|
473 | /* synthesis syn_replicate = 0 */; |
---|
474 | |
---|
475 | FDRSE_1 u_ff_stg2b_rise |
---|
476 | ( |
---|
477 | .Q (stg2b_out_rise), |
---|
478 | .C (clk0), |
---|
479 | .CE (1'b1), |
---|
480 | .D (stg1_out_rise_sg2), |
---|
481 | .R (1'b0), |
---|
482 | .S (1'b0) |
---|
483 | )/* synthesis syn_preserve = 1 */ |
---|
484 | /* synthesis syn_replicate = 0 */; |
---|
485 | end else if (FPGA_SPEED_GRADE == 1) begin: gen_stg2_sg1 |
---|
486 | IDDR # |
---|
487 | ( |
---|
488 | .DDR_CLK_EDGE ("SAME_EDGE") |
---|
489 | ) |
---|
490 | u_iddr_dq |
---|
491 | ( |
---|
492 | .Q1 (stg1_out_fall_sg1), |
---|
493 | .Q2 (stg1_out_rise_sg1), |
---|
494 | .C (dq_iddr_clk), |
---|
495 | .CE (ce), |
---|
496 | .D (dq_idelay), |
---|
497 | .R (1'b0), |
---|
498 | .S (1'b0) |
---|
499 | ); |
---|
500 | |
---|
501 | //********************************************************* |
---|
502 | // Slice #1 (posedge CLK): Used for: |
---|
503 | // 1. IDDR transfer to CLK0 rising edge domain ("stg2a") |
---|
504 | // 2. stg2 falling edge -> stg3 rising edge transfer |
---|
505 | //********************************************************* |
---|
506 | |
---|
507 | // Stage 2 capture |
---|
508 | FDRSE u_ff_stg2a_fall |
---|
509 | ( |
---|
510 | .Q (stg2a_out_fall), |
---|
511 | .C (clk0), |
---|
512 | .CE (1'b1), |
---|
513 | .D (stg1_out_fall_sg1), |
---|
514 | .R (1'b0), |
---|
515 | .S (1'b0) |
---|
516 | )/* synthesis syn_preserve = 1 */ |
---|
517 | /* synthesis syn_replicate = 0 */; |
---|
518 | FDRSE u_ff_stg2a_rise |
---|
519 | ( |
---|
520 | .Q (stg2a_out_rise), |
---|
521 | .C (clk0), |
---|
522 | .CE (1'b1), |
---|
523 | .D (stg1_out_rise_sg1), |
---|
524 | .R (1'b0), |
---|
525 | .S (1'b0) |
---|
526 | )/* synthesis syn_preserve = 1 */ |
---|
527 | /* synthesis syn_replicate = 0 */; |
---|
528 | // Stage 3 falling -> rising edge translation |
---|
529 | FDRSE u_ff_stg3b_fall |
---|
530 | ( |
---|
531 | .Q (stg3b_out_fall), |
---|
532 | .C (clk0), |
---|
533 | .CE (1'b1), |
---|
534 | .D (stg2b_out_fall), |
---|
535 | .R (1'b0), |
---|
536 | .S (1'b0) |
---|
537 | )/* synthesis syn_preserve = 1 */ |
---|
538 | /* synthesis syn_replicate = 0 */; |
---|
539 | FDRSE u_ff_stg3b_rise |
---|
540 | ( |
---|
541 | .Q (stg3b_out_rise), |
---|
542 | .C (clk0), |
---|
543 | .CE (1'b1), |
---|
544 | .D (stg2b_out_rise), |
---|
545 | .R (1'b0), |
---|
546 | .S (1'b0) |
---|
547 | )/* synthesis syn_preserve = 1 */ |
---|
548 | /* synthesis syn_replicate = 0 */; |
---|
549 | |
---|
550 | //********************************************************* |
---|
551 | // Slice #2 (posedge CLK): Used for: |
---|
552 | // 1. IDDR transfer to CLK0 falling edge domain ("stg2b") |
---|
553 | //********************************************************* |
---|
554 | |
---|
555 | FDRSE_1 u_ff_stg2b_fall |
---|
556 | ( |
---|
557 | .Q (stg2b_out_fall), |
---|
558 | .C (clk0), |
---|
559 | .CE (1'b1), |
---|
560 | .D (stg1_out_fall_sg1), |
---|
561 | .R (1'b0), |
---|
562 | .S (1'b0) |
---|
563 | )/* synthesis syn_preserve = 1 */ |
---|
564 | /* synthesis syn_replicate = 0 */; |
---|
565 | |
---|
566 | FDRSE_1 u_ff_stg2b_rise |
---|
567 | ( |
---|
568 | .Q (stg2b_out_rise), |
---|
569 | .C (clk0), |
---|
570 | .CE (1'b1), |
---|
571 | .D (stg1_out_rise_sg1), |
---|
572 | .R (1'b0), |
---|
573 | .S (1'b0) |
---|
574 | )/* synthesis syn_preserve = 1 */ |
---|
575 | /* synthesis syn_replicate = 0 */; |
---|
576 | end |
---|
577 | endgenerate |
---|
578 | |
---|
579 | //*************************************************************************** |
---|
580 | // Second stage flops clocked by posedge CLK0 don't need another layer of |
---|
581 | // registering |
---|
582 | //*************************************************************************** |
---|
583 | |
---|
584 | assign stg3a_out_rise = stg2a_out_rise; |
---|
585 | assign stg3a_out_fall = stg2a_out_fall; |
---|
586 | |
---|
587 | //******************************************************************* |
---|
588 | |
---|
589 | assign rd_data_rise = (rd_data_sel) ? stg3a_out_rise : stg3b_out_rise; |
---|
590 | assign rd_data_fall = (rd_data_sel) ? stg3a_out_fall : stg3b_out_fall; |
---|
591 | |
---|
592 | endmodule |
---|