[10] | 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 |
---|