add DDR2 controller, generated via MIG
[fleet.git] / src / edu / berkeley / fleet / fpga / ddr2 / ddr2_phy_dq_iob.v
1 //*****************************************************************************
2 // DISCLAIMER OF LIABILITY
3 //
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.
15 //
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
30 // purpose.
31 //
32 // Xilinx products are not intended for use in life support
33 // appliances, devices, or systems. Use in such applications is
34 // expressly prohibited.
35 //
36 // Any modifications that are made to the Source Code are
37 // done at the users sole risk and will be unsupported.
38 //
39 // Copyright (c) 2006-2007 Xilinx, Inc. All rights reserved.
40 //
41 // This copyright and support notice must be retained as part
42 // of this text at all times.
43 //*****************************************************************************
44 //   ____  ____
45 //  /   /\/   /
46 // /___/  \  /    Vendor: Xilinx
47 // \   \   \/     Version: 2.3
48 //  \   \         Application: MIG
49 //  /   /         Filename: ddr2_phy_dq_iob.v
50 // /___/   /\     Date Last Modified: $Date: 2008/07/17 07:52:27 $
51 // \   \  /  \    Date Created: Wed Aug 16 2006
52 //  \___\/\___\
53 //
54 //Device: Virtex-5
55 //Design Name: DDR2
56 //Purpose:
57 //   This module places the data in the IOBs.
58 //Reference:
59 //Revision History:
60 //*****************************************************************************
61
62 `timescale 1ns/1ps
63
64 module ddr2_phy_dq_iob #
65   (
66    parameter DQ_COL                = 0,
67    parameter DQ_MS                 = 0,
68    parameter HIGH_PERFORMANCE_MODE = "TRUE"
69    )
70   (
71    input        clk0,
72    input        clk90,
73    input        clkdiv0,
74    input        rst90,
75    input        dlyinc,
76    input        dlyce,
77    input        dlyrst,
78    input  [1:0] dq_oe_n,
79    input        dqs,
80    input        ce,
81    input        rd_data_sel,
82    input        wr_data_rise,
83    input        wr_data_fall,
84    output       rd_data_rise,
85    output       rd_data_fall,
86    inout        ddr_dq
87    );
88
89   wire       dq_iddr_clk;
90   wire       dq_idelay;
91   wire       dq_in;
92   wire       dq_oe_n_r;
93   wire       dq_out;
94   wire       stg2a_out_fall;
95   wire       stg2a_out_rise;
96   wire       stg2b_out_fall;
97   wire       stg2b_out_rise;
98   wire       stg3a_out_fall;
99   wire       stg3a_out_rise;
100   wire       stg3b_out_fall;
101   wire       stg3b_out_rise;
102
103   //***************************************************************************
104   // Directed routing constraints for route between IDDR and stage 2 capture
105   // in fabric.
106   // Only 2 out of the 12 wire declarations will be used for any given
107   // instantiation of this module.
108   // Varies according:
109   //  (1) I/O column (left, center, right) used
110   //  (2) Which I/O in I/O pair (master, slave) used
111   // Nomenclature: _Xy, X = column (0 = left, 1 = center, 2 = right),
112   //  y = master or slave
113   //***************************************************************************
114
115   // master, left
116   (* syn_keep = "1", keep = "TRUE",
117      ROUTE = "{3;1;5vlx50tff1136;93a1e3bb!-1;-78112;-4200;S!0;-143;-1248!1;-452;0!2;2747;1575!3;2461;81!4;2732;-960!4;2732;-984!5;404;8!6;404;8!7;683;-568;L!8;843;24;L!}" *)
118   wire stg1_out_rise_0m;
119   (* syn_keep = "1", keep = "TRUE",
120      ROUTE = "{3;1;5vlx50tff1136;907923a!-1;-78112;-4192;S!0;-143;-1192!0;-143;-1272!1;-452;0!2;-452;0!3;2723;-385!4;2731;-311!5;3823;-1983!6;5209;1271!7;1394;3072!8;0;-8!9;404;8!10;0;-144!11;683;-536;L!12;404;8!14;843;8;L!}" *)
121   wire stg1_out_fall_0m;
122   // slave, left
123   (* syn_keep = "1", keep = "TRUE",
124      ROUTE = "{3;1;5vlx50tff1136;53bb9d6f!-1;-78112;-4600;S!0;-143;-712!1;-452;0!2;1008;-552!3;2780;1360!4;0;-8!5;0;-240!5;0;-264!6;404;8!7;404;8!8;683;-568;L!9;843;24;L!}" *)
125   wire stg1_out_rise_0s;
126   (* syn_keep = "1", keep = "TRUE",
127      ROUTE = "{3;1;5vlx50tff1136;46bf60d8!-1;-78112;-4592;S!0;-143;-800!1;-452;0!2;1040;1592!3;5875;-85!4;-3127;-843!4;-3127;-939!5;404;8!6;404;8!7;683;-696;L!8;843;-136;L!}" *)
128   wire stg1_out_fall_0s;
129   // master, center
130   (* syn_keep = "1", keep = "TRUE",
131      ROUTE = "{3;1;5vlx50tff1136;9ee47800!-1;-6504;-50024;S!0;-175;-1136!1;-484;0!2;-3208;1552!3;-4160;-2092!4;-1428;1172!4;-1428;1076!5;404;8!6;404;8!7;843;-152;L!8;683;-728;L!}" *)
132   wire stg1_out_rise_1m;
133   (* syn_keep = "1", keep = "TRUE",
134      ROUTE = "{3;1;5vlx50tff1136;e7df31c2!-1;-6504;-50016;S!0;-175;-1192!1;-484;0!2;-5701;1523!3;-3095;-715!3;-4423;2421!4;0;-8!5;1328;-3288!6;0;-240!7;404;8!8;404;8!9;683;-696;L!10;843;-136;L!}" *)
135   wire stg1_out_fall_1m;
136   // slave, center
137   (* syn_keep = "1", keep = "TRUE",
138      ROUTE = "{3;1;5vlx50tff1136;a8c11eb3!-1;-6504;-50424;S!0;-175;-856!1;-484;0!2;-5677;-337!3;1033;1217!3;-295;4353!4;0;-8!5;1328;-3288!6;0;-120!7;404;8!8;404;8!9;683;-696;L!10;843;-152;L!}" *)
139   wire stg1_out_rise_1s;
140   (* syn_keep = "1", keep = "TRUE",
141      ROUTE = "{3;1;5vlx50tff1136;ed30cce!-1;-6504;-50416;S!0;-175;-848!1;-484;0!2;-3192;-432!3;-1452;1368!3;-6645;85!4;0;-8!5;5193;1035!6;0;-264!7;404;8!8;404;8!9;683;-568;L!10;843;24;L!}" *)
142   wire stg1_out_fall_1s;
143   // master, right
144   (* syn_keep = "1", keep = "TRUE",
145      ROUTE = "{3;1;5vlx50tff1136;4d035a44!-1;54728;-108896;S!0;-175;-1248!1;-484;0!2;-3192;-424!3;-4208;2092!4;-1396;-972!4;-1396;-996!5;404;8!6;404;8!7;683;-568;L!8;843;24;L!}" *)
146   wire stg1_out_rise_2m;
147   (* syn_keep = "1", keep = "TRUE",
148      ROUTE = "{3;1;5vlx50tff1136;92ae8739!-1;54728;-108888;S!0;-175;-1272!1;-484;0!2;-5677;-329!3;-1691;-83!4;-1428;1076!4;-1428;1052!5;404;8!6;404;8!7;683;-728;L!8;843;-136;L!}" *)
149   wire stg1_out_fall_2m;
150   // slave, right
151   (* syn_keep = "1", keep = "TRUE",
152      ROUTE = "{3;1;5vlx50tff1136;9de34bf1!-1;54728;-109296;S!0;-175;-712!1;-484;0!2;-5685;-475!3;1041;1107!3;1041;1011!4;404;8!5;404;8!6;683;-536;L!7;843;24;L!}" *)
153   wire stg1_out_rise_2s;
154   (* syn_keep = "1", keep = "TRUE",
155      ROUTE = "{3;1;5vlx50tff1136;1df9e65d!-1;54728;-109288;S!0;-175;-800!1;-484;0!2;-3208;1608!3;-1436;-792!4;0;-8!5;0;-240!5;0;-144!6;404;8!7;404;8!8;843;-136;L!9;683;-696;L!}" *)
156   wire stg1_out_fall_2s;
157
158   //***************************************************************************
159   // Bidirectional I/O
160   //***************************************************************************
161
162   IOBUF u_iobuf_dq
163     (
164      .I  (dq_out),
165      .T  (dq_oe_n_r),
166      .IO (ddr_dq),
167      .O  (dq_in)
168      );
169
170   //***************************************************************************
171   // Write (output) path
172   //***************************************************************************
173
174   // on a write, rising edge of DQS corresponds to rising edge of CLK180
175   // (aka falling edge of CLK0 -> rising edge DQS). We also know:
176   //  1. data must be driven 1/4 clk cycle before corresponding DQS edge
177   //  2. first rising DQS edge driven on falling edge of CLK0
178   //  3. rising data must be driven 1/4 cycle before falling edge of CLK0
179   //  4. therefore, rising data driven on rising edge of CLK
180   ODDR #
181     (
182      .SRTYPE("SYNC"),
183      .DDR_CLK_EDGE("SAME_EDGE")
184      )
185     u_oddr_dq
186       (
187        .Q  (dq_out),
188        .C  (clk90),
189        .CE (1'b1),
190        .D1 (wr_data_rise),
191        .D2 (wr_data_fall),
192        .R  (1'b0),
193        .S  (1'b0)
194        );
195
196   // make sure output is tri-state during reset (DQ_OE_N_R = 1)
197   ODDR #
198     (
199      .SRTYPE("ASYNC"),
200      .DDR_CLK_EDGE("SAME_EDGE")
201      )
202     u_tri_state_dq
203       (
204        .Q  (dq_oe_n_r),
205        .C  (clk90),
206        .CE (1'b1),
207        .D1 (dq_oe_n[0]),
208        .D2 (dq_oe_n[1]),
209        .R  (1'b0),
210        .S  (rst90)
211        );
212
213   //***************************************************************************
214   // Read data capture scheme description:
215   // Data capture consists of 3 ranks of flops, and a MUX
216   //  1. Rank 1 ("Stage 1"): IDDR captures delayed DDR DQ from memory using
217   //     delayed DQS.
218   //     - Data is split into 2 SDR streams, one each for rise and fall data.
219   //     - BUFIO (DQS) input inverted to IDDR. IDDR configured in SAME_EDGE
220   //       mode. This means that: (1) Q1 = fall data, Q2 = rise data,
221   //       (2) Both rise and fall data are output on falling edge of DQS -
222   //       rather than rise output being output on one edge of DQS, and fall
223   //       data on the other edge if the IDDR were configured in OPPOSITE_EDGE
224   //       mode. This simplifies Stage 2 capture (only one core clock edge
225   //       used, removing effects of duty-cycle-distortion), and saves one
226   //       fabric flop in Rank 3.
227   //  2. Rank 2 ("Stage 2"): Fabric flops are used to capture output of first
228   //     rank into FPGA clock (CLK) domain. Each rising/falling SDR stream
229   //     from IDDR is feed into two flops, one clocked off rising and one off
230   //     falling edge of CLK. One of these flops is chosen, with the choice
231   //     being the one that reduces # of DQ/DQS taps necessary to align Stage
232   //     1 and Stage 2. Same edge is used to capture both rise and fall SDR
233   //     streams.
234   //  3. Rank 3 ("Stage 3"): Removes half-cycle paths in CLK domain from
235   //     output of Rank 2. This stage, like Stage 2, is clocked by CLK. Note
236   //     that Stage 3 can be expanded to also support SERDES functionality
237   //  4. Output MUX: Selects whether Stage 1 output is aligned to rising or
238   //     falling edge of CLK (i.e. specifically this selects whether IDDR
239   //     rise/fall output is transfered to rising or falling edge of CLK).
240   // Implementation:
241   //  1. Rank 1 is implemented using an IDDR primitive
242   //  2. Rank 2 is implemented using:
243   //     - An RPM to fix the location of the capture flops near the DQ I/O.
244   //       The exact RPM used depends on which I/O column (left, center,
245   //       right) the DQ I/O is placed at - this affects the optimal location
246   //       of the slice flops (or does it - can we always choose the two
247   //       columns to slices to the immediate right of the I/O to use, no
248   //       matter what the column?). The origin of the RPM must be set in the
249   //       UCF file using the RLOC_ORIGIN constraint (where the original is
250   //       based on the DQ I/O location).
251   //     - Directed Routing Constraints ("DIRT strings") to fix the routing
252   //       to the rank 2 fabric flops. This is done to minimize: (1) total
253   //       route delay (and therefore minimize voltage/temperature-related
254   //       variations), and (2) minimize skew both within each rising and
255   //       falling data net, as well as between the rising and falling nets.
256   //       The exact DIRT string used depends on: (1) which I/O column the
257   //       DQ I/O is placed, and (2) whether the DQ I/O is placed on the
258   //       "Master" or "Slave" I/O of a diff pair (DQ is not differential, but
259   //       the routing will be affected by which of each I/O pair is used)
260   // 3. Rank 3 is implemented using fabric flops. No LOC or DIRT contraints
261   //    are used, tools are expected to place these and meet PERIOD timing
262   //    without constraints (constraints may be necessary for "full" designs,
263   //    in this case, user may need to add LOC constraints - if this is the
264   //    case, there are no constraints - other than meeting PERIOD timing -
265   //    for rank 3 flops.
266   //***************************************************************************
267
268   //***************************************************************************
269   // MIG 2.2: Define AREA_GROUP = "DDR_CAPTURE_FFS" contain all RPM flops in
270   //          design. In UCF file, add constraint:
271   //             AREA_GROUP "DDR_CAPTURE_FFS" GROUP = CLOSED;
272   //          This is done to prevent MAP from packing unrelated logic into
273   //          the slices used by the RPMs. Doing so may cause the DIRT strings
274   //          that define the IDDR -> fabric flop routing to later become
275   //          unroutable during PAR because the unrelated logic placed by MAP
276   //          may use routing resources required by the DIRT strings. MAP
277   //          does not currently take into account DIRT strings when placing
278   //          logic
279   //***************************************************************************
280
281   // IDELAY to delay incoming data for synchronization purposes
282   IODELAY #
283     (
284      .DELAY_SRC             ("I"),
285      .IDELAY_TYPE           ("VARIABLE"),
286      .HIGH_PERFORMANCE_MODE (HIGH_PERFORMANCE_MODE),
287      .IDELAY_VALUE          (0),
288      .ODELAY_VALUE          (0)
289      )
290     u_idelay_dq
291       (
292        .DATAOUT (dq_idelay),
293        .C       (clkdiv0),
294        .CE      (dlyce),
295        .DATAIN  (),
296        .IDATAIN (dq_in),
297        .INC     (dlyinc),
298        .ODATAIN (),
299        .RST     (dlyrst),
300        .T       ()
301        );
302
303   //***************************************************************************
304   // Rank 1 capture: Use IDDR to generate two SDR outputs
305   //***************************************************************************
306
307   // invert clock to IDDR in order to use SAME_EDGE mode (otherwise, we "run
308   // out of clocks" because DQS is not continuous
309   assign dq_iddr_clk = ~dqs;
310
311   //***************************************************************************
312   // Rank 2 capture: Use fabric flops to capture Rank 1 output. Use RPM and
313   // DIRT strings here.
314   // BEL ("Basic Element of Logic") and relative location constraints for
315   // second stage capture. C
316   // Varies according:
317   //  (1) I/O column (left, center, right) used
318   //  (2) Which I/O in I/O pair (master, slave) used
319   //***************************************************************************
320
321   // Six different cases for the different I/O column, master/slave
322   // combinations (can't seem to do this using a localparam, which
323   // would be easier, XST doesn't allow it)
324   generate
325     if ((DQ_MS == 1) && (DQ_COL == 0)) begin: gen_stg2_0m
326
327       //*****************************************************************
328       // master, left
329       //*****************************************************************
330
331       IDDR #
332         (
333          .DDR_CLK_EDGE ("SAME_EDGE")
334          )
335         u_iddr_dq
336           (
337            .Q1 (stg1_out_fall_0m),
338            .Q2 (stg1_out_rise_0m),
339            .C  (dq_iddr_clk),
340            .CE (ce),
341            .D  (dq_idelay),
342            .R  (1'b0),
343            .S  (1'b0)
344            );
345
346       //*********************************************************
347       // Slice #1 (posedge CLK): Used for:
348       //  1. IDDR transfer to CLK0 rising edge domain ("stg2a")
349       //  2. stg2 falling edge -> stg3 rising edge transfer
350       //*********************************************************
351
352       // Stage 2 capture
353       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "DFF",
354          AREA_GROUP = "DDR_CAPTURE_FFS" *)
355       FDRSE u_ff_stg2a_fall
356         (
357          .Q   (stg2a_out_fall),
358          .C   (clk0),
359          .CE  (1'b1),
360      .D   (stg1_out_fall_0m),
361          .R   (1'b0),
362          .S   (1'b0)
363          )/* synthesis syn_preserve = 1 */
364           /* synthesis syn_replicate = 0 */;
365       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "CFF",
366          AREA_GROUP = "DDR_CAPTURE_FFS" *)
367       FDRSE u_ff_stg2a_rise
368         (
369          .Q   (stg2a_out_rise),
370          .C   (clk0),
371          .CE  (1'b1),
372      .D   (stg1_out_rise_0m),
373          .R   (1'b0),
374          .S   (1'b0)
375          )/* synthesis syn_preserve = 1 */
376           /* synthesis syn_replicate = 0 */;
377       // Stage 3 falling -> rising edge translation
378       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "BFF",
379          AREA_GROUP = "DDR_CAPTURE_FFS" *)
380       FDRSE u_ff_stg3b_fall
381         (
382          .Q   (stg3b_out_fall),
383          .C   (clk0),
384          .CE  (1'b1),
385      .D   (stg2b_out_fall),
386          .R   (1'b0),
387          .S   (1'b0)
388          )/* synthesis syn_preserve = 1 */
389           /* synthesis syn_replicate = 0 */;
390       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "AFF",
391          AREA_GROUP = "DDR_CAPTURE_FFS" *)
392       FDRSE u_ff_stg3b_rise
393         (
394          .Q   (stg3b_out_rise),
395          .C   (clk0),
396          .CE  (1'b1),
397      .D   (stg2b_out_rise),
398          .R   (1'b0),
399          .S   (1'b0)
400          )/* synthesis syn_preserve = 1 */
401           /* synthesis syn_replicate = 0 */;
402
403       //*********************************************************
404       // Slice #2 (posedge CLK): Used for:
405       //  1. IDDR transfer to CLK0 falling edge domain ("stg2b")
406       //*********************************************************
407
408       (* HU_SET = "stg2_capture", RLOC = "X3Y0", BEL = "DFF",
409          AREA_GROUP = "DDR_CAPTURE_FFS" *)
410       FDRSE_1 u_ff_stg2b_fall
411         (
412          .Q   (stg2b_out_fall),
413          .C   (clk0),
414          .CE  (1'b1),
415      .D   (stg1_out_fall_0m),
416          .R   (1'b0),
417          .S   (1'b0)
418          )/* synthesis syn_preserve = 1 */
419           /* synthesis syn_replicate = 0 */;
420
421       (* HU_SET = "stg2_capture", RLOC = "X3Y0", BEL = "CFF",
422          AREA_GROUP = "DDR_CAPTURE_FFS" *)
423       FDRSE_1 u_ff_stg2b_rise
424         (
425          .Q   (stg2b_out_rise),
426          .C   (clk0),
427          .CE  (1'b1),
428      .D   (stg1_out_rise_0m),
429          .R   (1'b0),
430          .S   (1'b0)
431          )/* synthesis syn_preserve = 1 */
432           /* synthesis syn_replicate = 0 */;
433
434     end else if ((DQ_MS == 0) && (DQ_COL == 0)) begin: gen_stg2_0s
435
436       //*****************************************************************
437       // slave, left
438       //*****************************************************************
439
440       IDDR #
441         (
442          .DDR_CLK_EDGE ("SAME_EDGE")
443          )
444         u_iddr_dq
445           (
446            .Q1 (stg1_out_fall_0s),
447            .Q2 (stg1_out_rise_0s),
448            .C  (dq_iddr_clk),
449            .CE (ce),
450            .D  (dq_idelay),
451            .R  (1'b0),
452            .S  (1'b0)
453            );
454
455       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "BFF",
456          AREA_GROUP = "DDR_CAPTURE_FFS" *)
457       FDRSE u_ff_stg2a_fall
458         (
459          .Q   (stg2a_out_fall),
460          .C   (clk0),
461          .CE  (1'b1),
462      .D   (stg1_out_fall_0s),
463          .R   (1'b0),
464          .S   (1'b0)
465          )/* synthesis syn_preserve = 1 */
466           /* synthesis syn_replicate = 0 */;
467       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "CFF",
468          AREA_GROUP = "DDR_CAPTURE_FFS" *)
469       FDRSE u_ff_stg2a_rise
470         (
471          .Q   (stg2a_out_rise),
472          .C   (clk0),
473          .CE  (1'b1),
474      .D   (stg1_out_rise_0s),
475          .R   (1'b0),
476          .S   (1'b0)
477          )/* synthesis syn_preserve = 1 */
478           /* synthesis syn_replicate = 0 */;
479
480       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "DFF",
481          AREA_GROUP = "DDR_CAPTURE_FFS" *)
482       FDRSE u_ff_stg3b_fall
483         (
484          .Q   (stg3b_out_fall),
485          .C   (clk0),
486          .CE  (1'b1),
487      .D   (stg2b_out_fall),
488          .R   (1'b0),
489          .S   (1'b0)
490          )/* synthesis syn_preserve = 1 */
491           /* synthesis syn_replicate = 0 */;
492       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "AFF",
493          AREA_GROUP = "DDR_CAPTURE_FFS" *)
494       FDRSE u_ff_stg3b_rise
495         (
496          .Q   (stg3b_out_rise),
497          .C   (clk0),
498          .CE  (1'b1),
499      .D   (stg2b_out_rise),
500          .R   (1'b0),
501          .S   (1'b0)
502          )/* synthesis syn_preserve = 1 */
503           /* synthesis syn_replicate = 0 */;
504
505       (* HU_SET = "stg2_capture", RLOC = "X1Y0", BEL = "AFF",
506        AREA_GROUP = "DDR_CAPTURE_FFS" *)
507       FDRSE_1 u_ff_stg2b_fall
508         (
509          .Q   (stg2b_out_fall),
510          .C   (clk0),
511          .CE  (1'b1),
512      .D   (stg1_out_fall_0s),
513          .R   (1'b0),
514          .S   (1'b0)
515          )/* synthesis syn_preserve = 1 */
516           /* synthesis syn_replicate = 0 */;
517       (* HU_SET = "stg2_capture", RLOC = "X1Y0", BEL = "CFF",
518        AREA_GROUP = "DDR_CAPTURE_FFS" *)
519       FDRSE_1 u_ff_stg2b_rise
520         (
521          .Q   (stg2b_out_rise),
522          .C   (clk0),
523          .CE  (1'b1),
524      .D   (stg1_out_rise_0s),
525          .R   (1'b0),
526          .S   (1'b0)
527          )/* synthesis syn_preserve = 1 */
528           /* synthesis syn_replicate = 0 */;
529
530     end else if ((DQ_MS == 1) && (DQ_COL == 1))  begin: gen_stg2_1m
531
532       //*****************************************************************
533       // master, center
534       //*****************************************************************
535
536       IDDR #
537         (
538          .DDR_CLK_EDGE ("SAME_EDGE")
539          )
540         u_iddr_dq
541           (
542            .Q1 (stg1_out_fall_1m),
543            .Q2 (stg1_out_rise_1m),
544            .C  (dq_iddr_clk),
545            .CE (ce),
546            .D  (dq_idelay),
547            .R  (1'b0),
548            .S  (1'b0)
549            );
550
551       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "BFF",
552          AREA_GROUP = "DDR_CAPTURE_FFS" *)
553       FDRSE u_ff_stg2a_fall
554         (
555          .Q   (stg2a_out_fall),
556          .C   (clk0),
557          .CE  (1'b1),
558      .D   (stg1_out_fall_1m),
559          .R   (1'b0),
560          .S   (1'b0)
561          )/* synthesis syn_preserve = 1 */
562           /* synthesis syn_replicate = 0 */;
563       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "AFF",
564          AREA_GROUP = "DDR_CAPTURE_FFS" *)
565       FDRSE u_ff_stg2a_rise
566         (
567          .Q   (stg2a_out_rise),
568          .C   (clk0),
569          .CE  (1'b1),
570      .D   (stg1_out_rise_1m),
571          .R   (1'b0),
572          .S   (1'b0)
573          )/* synthesis syn_preserve = 1 */
574           /* synthesis syn_replicate = 0 */;
575
576       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "DFF",
577          AREA_GROUP = "DDR_CAPTURE_FFS" *)
578       FDRSE u_ff_stg3b_fall
579         (
580          .Q   (stg3b_out_fall),
581          .C   (clk0),
582          .CE  (1'b1),
583      .D   (stg2b_out_fall),
584          .R   (1'b0),
585          .S   (1'b0)
586          )/* synthesis syn_preserve = 1 */
587           /* synthesis syn_replicate = 0 */;
588       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "CFF",
589          AREA_GROUP = "DDR_CAPTURE_FFS" *)
590       FDRSE u_ff_stg3b_rise
591         (
592          .Q   (stg3b_out_rise),
593          .C   (clk0),
594          .CE  (1'b1),
595      .D   (stg2b_out_rise),
596          .R   (1'b0),
597          .S   (1'b0)
598          )/* synthesis syn_preserve = 1 */
599           /* synthesis syn_replicate = 0 */;
600
601       (* HU_SET = "stg2_capture", RLOC = "X1Y0", BEL = "AFF",
602          AREA_GROUP = "DDR_CAPTURE_FFS" *)
603       FDRSE_1 u_ff_stg2b_fall
604         (
605          .Q   (stg2b_out_fall),
606          .C   (clk0),
607          .CE  (1'b1),
608      .D   (stg1_out_fall_1m),
609          .R   (1'b0),
610          .S   (1'b0)
611          )/* synthesis syn_preserve = 1 */
612           /* synthesis syn_replicate = 0 */;
613       (* HU_SET = "stg2_capture", RLOC = "X1Y0", BEL = "BFF",
614          AREA_GROUP = "DDR_CAPTURE_FFS" *)
615       FDRSE_1 u_ff_stg2b_rise
616         (
617          .Q   (stg2b_out_rise),
618          .C   (clk0),
619          .CE  (1'b1),
620      .D   (stg1_out_rise_1m),
621          .R   (1'b0),
622          .S   (1'b0)
623          )/* synthesis syn_preserve = 1 */
624           /* synthesis syn_replicate = 0 */;
625
626     end else if ((DQ_MS == 0) && (DQ_COL == 1)) begin: gen_stg2_1s
627
628       //*****************************************************************
629       // slave, center
630       //*****************************************************************
631
632       IDDR #
633         (
634          .DDR_CLK_EDGE ("SAME_EDGE")
635          )
636         u_iddr_dq
637           (
638            .Q1 (stg1_out_fall_1s),
639            .Q2 (stg1_out_rise_1s),
640            .C  (dq_iddr_clk),
641            .CE (ce),
642            .D  (dq_idelay),
643            .R  (1'b0),
644            .S  (1'b0)
645            );
646
647       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "CFF",
648          AREA_GROUP = "DDR_CAPTURE_FFS" *)
649       FDRSE u_ff_stg2a_fall
650         (
651          .Q   (stg2a_out_fall),
652          .C   (clk0),
653          .CE  (1'b1),
654      .D   (stg1_out_fall_1s),
655          .R   (1'b0),
656          .S   (1'b0)
657          )/* synthesis syn_preserve = 1 */
658           /* synthesis syn_replicate = 0 */;
659       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "BFF",
660          AREA_GROUP = "DDR_CAPTURE_FFS" *)
661       FDRSE u_ff_stg2a_rise
662         (
663          .Q   (stg2a_out_rise),
664          .C   (clk0),
665          .CE  (1'b1),
666      .D   (stg1_out_rise_1s),
667          .R   (1'b0),
668          .S   (1'b0)
669          )/* synthesis syn_preserve = 1 */
670           /* synthesis syn_replicate = 0 */;
671
672       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "DFF",
673          AREA_GROUP = "DDR_CAPTURE_FFS" *)
674       FDRSE u_ff_stg3b_fall
675         (
676          .Q   (stg3b_out_fall),
677          .C   (clk0),
678          .CE  (1'b1),
679      .D   (stg2b_out_fall),
680          .R   (1'b0),
681          .S   (1'b0)
682          )/* synthesis syn_preserve = 1 */
683           /* synthesis syn_replicate = 0 */;
684       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "AFF",
685          AREA_GROUP = "DDR_CAPTURE_FFS" *)
686       FDRSE u_ff_stg3b_rise
687         (
688          .Q   (stg3b_out_rise),
689          .C   (clk0),
690          .CE  (1'b1),
691      .D   (stg2b_out_rise),
692          .R   (1'b0),
693          .S   (1'b0)
694          )/* synthesis syn_preserve = 1 */
695           /* synthesis syn_replicate = 0 */;
696
697       (* HU_SET = "stg2_capture", RLOC = "X3Y0", BEL = "CFF",
698          AREA_GROUP = "DDR_CAPTURE_FFS" *)
699       FDRSE_1 u_ff_stg2b_fall
700         (
701          .Q   (stg2b_out_fall),
702          .C   (clk0),
703          .CE  (1'b1),
704      .D   (stg1_out_fall_1s),
705          .R   (1'b0),
706          .S   (1'b0)
707          )/* synthesis syn_preserve = 1 */
708           /* synthesis syn_replicate = 0 */;
709       (* HU_SET = "stg2_capture", RLOC = "X3Y0", BEL = "BFF",
710          AREA_GROUP = "DDR_CAPTURE_FFS" *)
711       FDRSE_1 u_ff_stg2b_rise
712         (
713          .Q   (stg2b_out_rise),
714          .C   (clk0),
715          .CE  (1'b1),
716      .D   (stg1_out_rise_1s),
717          .R   (1'b0),
718          .S   (1'b0)
719          )/* synthesis syn_preserve = 1 */
720           /* synthesis syn_replicate = 0 */;
721
722     end else if ((DQ_MS == 1) && (DQ_COL == 2)) begin: gen_stg2_2m
723
724       //*****************************************************************
725       // master, right
726       //*****************************************************************
727
728       IDDR #
729         (
730          .DDR_CLK_EDGE ("SAME_EDGE")
731          )
732         u_iddr_dq
733           (
734            .Q1 (stg1_out_fall_2m),
735            .Q2 (stg1_out_rise_2m),
736            .C  (dq_iddr_clk),
737            .CE (ce),
738            .D  (dq_idelay),
739            .R  (1'b0),
740            .S  (1'b0)
741            );
742
743       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "AFF",
744          AREA_GROUP = "DDR_CAPTURE_FFS" *)
745       FDRSE u_ff_stg2a_fall
746         (
747          .Q   (stg2a_out_fall),
748          .C   (clk0),
749          .CE  (1'b1),
750      .D   (stg1_out_fall_2m),
751          .R   (1'b0),
752          .S   (1'b0)
753          )/* synthesis syn_preserve = 1 */
754           /* synthesis syn_replicate = 0 */;
755       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "CFF",
756          AREA_GROUP = "DDR_CAPTURE_FFS" *)
757       FDRSE u_ff_stg2a_rise
758         (
759          .Q   (stg2a_out_rise),
760          .C   (clk0),
761          .CE  (1'b1),
762      .D   (stg1_out_rise_2m),
763          .R   (1'b0),
764          .S   (1'b0)
765          )/* synthesis syn_preserve = 1 */
766           /* synthesis syn_replicate = 0 */;
767
768       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "DFF",
769          AREA_GROUP = "DDR_CAPTURE_FFS" *)
770       FDRSE u_ff_stg3b_fall
771         (
772          .Q   (stg3b_out_fall),
773          .C   (clk0),
774          .CE  (1'b1),
775      .D   (stg2b_out_fall),
776          .R   (1'b0),
777          .S   (1'b0)
778          )/* synthesis syn_preserve = 1 */
779           /* synthesis syn_replicate = 0 */;
780       (* HU_SET = "stg2_capture", RLOC = "X0Y0", BEL = "BFF",
781          AREA_GROUP = "DDR_CAPTURE_FFS" *)
782       FDRSE u_ff_stg3b_rise
783         (
784          .Q   (stg3b_out_rise),
785          .C   (clk0),
786          .CE  (1'b1),
787      .D   (stg2b_out_rise),
788          .R   (1'b0),
789          .S   (1'b0)
790          )/* synthesis syn_preserve = 1 */
791           /* synthesis syn_replicate = 0 */;
792
793       (* HU_SET = "stg2_capture", RLOC = "X1Y0", BEL = "AFF",
794          AREA_GROUP = "DDR_CAPTURE_FFS" *)
795       FDRSE_1 u_ff_stg2b_fall
796         (
797          .Q   (stg2b_out_fall),
798          .C   (clk0),
799          .CE  (1'b1),
800      .D   (stg1_out_fall_2m),
801          .R   (1'b0),
802          .S   (1'b0)
803          )/* synthesis syn_preserve = 1 */
804           /* synthesis syn_replicate = 0 */;
805       (* HU_SET = "stg2_capture", RLOC = "X1Y0", BEL = "CFF",
806          AREA_GROUP = "DDR_CAPTURE_FFS" *)
807       FDRSE_1 u_ff_stg2b_rise
808         (
809          .Q   (stg2b_out_rise),
810          .C   (clk0),
811          .CE  (1'b1),
812      .D   (stg1_out_rise_2m),
813          .R   (1'b0),
814          .S   (1'b0)
815          )/* synthesis syn_preserve = 1 */
816           /* synthesis syn_replicate = 0 */;
817
818     end else if ((DQ_MS == 0) && (DQ_COL == 2)) begin: gen_stg2_2s
819
820       //*****************************************************************
821       // slave, right
822       //*****************************************************************
823
824       IDDR #
825         (
826          .DDR_CLK_EDGE ("SAME_EDGE")
827          )
828         u_iddr_dq
829           (
830            .Q1 (stg1_out_fall_2s),
831            .Q2 (stg1_out_rise_2s),
832            .C  (dq_iddr_clk),
833            .CE (ce),
834            .D  (dq_idelay),
835            .R  (1'b0),
836            .S  (1'b0)
837            );
838
839       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "BFF",
840          AREA_GROUP = "DDR_CAPTURE_FFS" *)
841       FDRSE u_ff_stg2a_fall
842         (
843          .Q   (stg2a_out_fall),
844          .C   (clk0),
845          .CE  (1'b1),
846      .D   (stg1_out_fall_2s),
847          .R   (1'b0),
848          .S   (1'b0)
849          )/* synthesis syn_preserve = 1 */
850           /* synthesis syn_replicate = 0 */;
851       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "DFF",
852          AREA_GROUP = "DDR_CAPTURE_FFS" *)
853       FDRSE u_ff_stg2a_rise
854         (
855          .Q   (stg2a_out_rise),
856          .C   (clk0),
857          .CE  (1'b1),
858      .D   (stg1_out_rise_2s),
859          .R   (1'b0),
860          .S   (1'b0)
861          )/* synthesis syn_preserve = 1 */
862           /* synthesis syn_replicate = 0 */;
863       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "CFF",
864          AREA_GROUP = "DDR_CAPTURE_FFS" *)
865       FDRSE u_ff_stg3b_fall
866         (
867          .Q   (stg3b_out_fall),
868          .C   (clk0),
869          .CE  (1'b1),
870      .D   (stg2b_out_fall),
871          .R   (1'b0),
872          .S   (1'b0)
873          )/* synthesis syn_preserve = 1 */
874           /* synthesis syn_replicate = 0 */;
875       (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "AFF",
876          AREA_GROUP = "DDR_CAPTURE_FFS" *)
877       FDRSE u_ff_stg3b_rise
878         (
879          .Q   (stg3b_out_rise),
880          .C   (clk0),
881          .CE  (1'b1),
882      .D   (stg2b_out_rise),
883          .R   (1'b0),
884          .S   (1'b0)
885          )/* synthesis syn_preserve = 1 */
886           /* synthesis syn_replicate = 0 */;
887
888       (* HU_SET = "stg2_capture", RLOC = "X3Y0", BEL = "AFF",
889          AREA_GROUP = "DDR_CAPTURE_FFS" *)
890       FDRSE_1 u_ff_stg2b_fall
891         (
892          .Q   (stg2b_out_fall),
893          .C   (clk0),
894          .CE  (1'b1),
895      .D   (stg1_out_fall_2s),
896          .R   (1'b0),
897          .S   (1'b0)
898          )/* synthesis syn_preserve = 1 */
899           /* synthesis syn_replicate = 0 */;
900       (* HU_SET = "stg2_capture", RLOC = "X3Y0", BEL = "CFF",
901          AREA_GROUP = "DDR_CAPTURE_FFS" *)
902       FDRSE_1 u_ff_stg2b_rise
903         (
904          .Q   (stg2b_out_rise),
905          .C   (clk0),
906          .CE  (1'b1),
907      .D   (stg1_out_rise_2s),
908          .R   (1'b0),
909          .S   (1'b0)
910          )/* synthesis syn_preserve = 1 */
911           /* synthesis syn_replicate = 0 */;
912
913     end
914   endgenerate
915
916   //***************************************************************************
917   // Second stage flops clocked by posedge CLK0 don't need another layer of
918   // registering
919   //***************************************************************************
920
921   assign stg3a_out_rise = stg2a_out_rise;
922   assign stg3a_out_fall = stg2a_out_fall;
923
924   //*******************************************************************
925
926   assign rd_data_rise = (rd_data_sel) ? stg3a_out_rise : stg3b_out_rise;
927   assign rd_data_fall = (rd_data_sel) ? stg3a_out_fall : stg3b_out_fall;
928
929 endmodule