⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 phy_dq_iob.v

📁 DDR2源代码 DDR2源代码 DDR2源代码
💻 V
📖 第 1 页 / 共 4 页
字号:
//*****************************************************************************// DISCLAIMER OF LIABILITY// // This text/file contains proprietary, confidential// information of Xilinx, Inc., is distributed under license// from Xilinx, Inc., and may be used, copied and/or// disclosed only pursuant to the terms of a valid license// agreement with Xilinx, Inc. Xilinx hereby grants you a // license to use this text/file solely for design, simulation, // implementation and creation of design files limited // to Xilinx devices or technologies. Use with non-Xilinx // devices or technologies is expressly prohibited and // immediately terminates your license unless covered by// a separate agreement.//// Xilinx is providing this design, code, or information // "as-is" solely for use in developing programs and // solutions for Xilinx devices, with no obligation on the // part of Xilinx to provide support. By providing this design, // code, or information as one possible implementation of // this feature, application or standard, Xilinx is making no // representation that this implementation is free from any // claims of infringement. You are responsible for // obtaining any rights you may require for your implementation. // Xilinx expressly disclaims any warranty whatsoever with // respect to the adequacy of the implementation, including // but not limited to any warranties or representations that this// implementation is free from claims of infringement, implied // warranties of merchantability or fitness for a particular // purpose.//// Xilinx products are not intended for use in life support// appliances, devices, or systems. Use in such applications is// expressly prohibited.//// Any modifications that are made to the Source Code are // done at the user抯 sole risk and will be unsupported.//// Copyright (c) 2006-2007 Xilinx, Inc. All rights reserved.//// This copyright and support notice must be retained as part // of this text at all times. //*****************************************************************************//   ____  ____//  /   /\/   /// /___/  \  /    Vendor: Xilinx// \   \   \/     Version: 2.1//  \   \         Application: MIG//  /   /         Filename: phy_dq_iob.v// /___/   /\     Date Last Modified: $Date: 2007/11/28 13:20:56 $// \   \  /  \    Date Created: Wed Aug 16 2006//  \___\/\___\////Device: Virtex-5//Design Name: DDR2//Purpose://   This module places the data in the IOBs.//Reference://Revision History://*****************************************************************************`timescale 1ns/1psmodule phy_dq_iob #  (   parameter DQ_COL = 0,   parameter DQ_MS  = 0   )  (   input        clk0,   input        clk90,   input        clkdiv0,   input        rst90,   input        dlyinc,   input        dlyce,   input        dlyrst,   input  [1:0] dq_oe_n,   input        dqs,   input        ce,   input        rd_data_sel,   input        wr_data_rise,   input        wr_data_fall,   output       rd_data_rise,   output       rd_data_fall,   inout        ddr_dq   );  wire       dq_iddr_clk;  wire       dq_idelay;  wire       dq_in;  wire       dq_oe_n_r;  wire       dq_out;  // prevent MAP from optimizing dummy carry-chain and LUT logic in RPM slices  (* S = "TRUE", syn_keep = 1 *) wire [3:0] dummy_carry4_co_a;  (* S = "TRUE", syn_keep = 1 *) wire [3:0] dummy_carry4_co_b;  (* S = "TRUE", syn_keep = 1 *) wire [3:0] dummy_lut_o5_a;  (* S = "TRUE", syn_keep = 1 *) wire [3:0] dummy_lut_o5_b;  (* S = "TRUE", syn_keep = 1 *) wire [3:0] dummy_lut_o6_a;  (* S = "TRUE", syn_keep = 1 *) wire [3:0] dummy_lut_o6_b;  wire       stg2a_out_fall;  wire       stg2a_out_rise;  wire       stg2b_out_fall;  wire       stg2b_out_rise;  wire       stg3a_out_fall;  wire       stg3a_out_rise;  wire       stg3b_out_fall;  wire       stg3b_out_rise;  //***************************************************************************  // Directed routing constraints for route between IDDR and stage 2 capture  // in fabric.  // Only 2 out of the 12 wire declarations will be used for any given  // instantiation of this module.  // Varies according:  //  (1) I/O column (left, center, right) used  //  (2) Which I/O in I/O pair (master, slave) used  // Nomenclature: _Xy, X = column (0 = left, 1 = center, 2 = right),  //  y = master or slave  //***************************************************************************  // master, left  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_rise_0m;  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_fall_0m;  // slave, left  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_rise_0s;  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_fall_0s;  // master, center  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_rise_1m;  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_fall_1m;  // slave, center  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_rise_1s;  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_fall_1s;  // master, right  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_rise_2m;  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_fall_2m;  // slave, right  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_rise_2s;  (* syn_keep = "1", keep = "TRUE",     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!}" *)  wire stg1_out_fall_2s;  //***************************************************************************  // Bidirectional I/O  //***************************************************************************  IOBUF u_iobuf_dq    (     .I  (dq_out),     .T  (dq_oe_n_r),     .IO (ddr_dq),     .O  (dq_in)     );  //***************************************************************************  // Write (output) path  //***************************************************************************  // on a write, rising edge of DQS corresponds to rising edge of CLK180  // (aka falling edge of CLK0 -> rising edge DQS). We also know:  //  1. data must be driven 1/4 clk cycle before corresponding DQS edge  //  2. first rising DQS edge driven on falling edge of CLK0  //  3. rising data must be driven 1/4 cycle before falling edge of CLK0  //  4. therefore, rising data driven on rising edge of CLK  ODDR #    (     .SRTYPE("SYNC"),     .DDR_CLK_EDGE("SAME_EDGE")     )    u_oddr_dq      (       .Q  (dq_out),       .C  (clk90),       .CE (1'b1),       .D1 (wr_data_rise),       .D2 (wr_data_fall),       .R  (1'b0),       .S  (1'b0)       );  // make sure output is tri-state during reset (DQ_OE_N_R = 1)  ODDR #    (     .SRTYPE("ASYNC"),     .DDR_CLK_EDGE("SAME_EDGE")     )    u_tri_state_dq      (       .Q  (dq_oe_n_r),       .C  (clk90),       .CE (1'b1),       .D1 (dq_oe_n[0]),       .D2 (dq_oe_n[1]),       .R  (rst90),       .S  (1'b0)       );  //***************************************************************************  // Read data capture scheme description:  // Data capture consists of 3 ranks of flops, and a MUX  //  1. Rank 1 ("Stage 1"): IDDR captures delayed DDR DQ from memory using  //     delayed DQS.  //     - Data is split into 2 SDR streams, one each for rise and fall data.  //     - BUFIO (DQS) input inverted to IDDR. IDDR configured in SAME_EDGE  //       mode. This means that: (1) Q1 = fall data, Q2 = rise data,  //       (2) Both rise and fall data are output on falling edge of DQS -  //       rather than rise output being output on one edge of DQS, and fall  //       data on the other edge if the IDDR were configured in OPPOSITE_EDGE  //       mode. This simplifies Stage 2 capture (only one core clock edge  //       used, removing effects of duty-cycle-distortion), and saves one  //       fabric flop in Rank 3.  //  2. Rank 2 ("Stage 2"): Fabric flops are used to capture output of first  //     rank into FPGA clock (CLK) domain. Each rising/falling SDR stream  //     from IDDR is feed into two flops, one clocked off rising and one off  //     falling edge of CLK. One of these flops is chosen, with the choice  //     being the one that reduces # of DQ/DQS taps necessary to align Stage  //     1 and Stage 2. Same edge is used to capture both rise and fall SDR  //     streams.  //  3. Rank 3 ("Stage 3"): Removes half-cycle paths in CLK domain from  //     output of Rank 2. This stage, like Stage 2, is clocked by CLK. Note  //     that Stage 3 can be expanded to also support SERDES functionality  //  4. Output MUX: Selects whether Stage 1 output is aligned to rising or  //     falling edge of CLK (i.e. specifically this selects whether IDDR  //     rise/fall output is transfered to rising or falling edge of CLK).  // Implementation:  //  1. Rank 1 is implemented using an IDDR primitive  //  2. Rank 2 is implemented using:  //     - An RPM to fix the location of the capture flops near the DQ I/O.  //       The exact RPM used depends on which I/O column (left, center,  //       right) the DQ I/O is placed at - this affects the optimal location  //       of the slice flops (or does it - can we always choose the two  //       columns to slices to the immediate right of the I/O to use, no  //       matter what the column?). The origin of the RPM must be set in the  //       UCF file using the RLOC_ORIGIN constraint (where the original is  //       based on the DQ I/O location).  //     - Directed Routing Constraints ("DIRT strings") to fix the routing  //       to the rank 2 fabric flops. This is done to minimize: (1) total  //       route delay (and therefore minimize voltage/temperature-related  //       variations), and (2) minimize skew both within each rising and  //       falling data net, as well as between the rising and falling nets.  //       The exact DIRT string used depends on: (1) which I/O column the  //       DQ I/O is placed, and (2) whether the DQ I/O is placed on the  //       "Master" or "Slave" I/O of a diff pair (DQ is not differential, but  //       the routing will be affected by which of each I/O pair is used)  // 3. Rank 3 is implemented using fabric flops. No LOC or DIRT contraints  //    are used, tools are expected to place these and meet PERIOD timing  //    without constraints (constraints may be necessary for "full" designs,  //    in this case, user may need to add LOC constraints - if this is the  //    case, there are no constraints - other than meeting PERIOD timing -  //    for rank 3 flops.  //***************************************************************************  // IDELAY to delay incoming data for synchronization purposes  IODELAY #    (     .DELAY_SRC             ("I"),     .IDELAY_TYPE           ("VARIABLE"),     .HIGH_PERFORMANCE_MODE ("TRUE"),     .IDELAY_VALUE          (0),     .ODELAY_VALUE          (0)     )    u_idelay_dq      (       .DATAOUT (dq_idelay),       .C       (clkdiv0),       .CE      (dlyce),       .DATAIN  (),       .IDATAIN (dq_in),       .INC     (dlyinc),       .ODATAIN (),       .RST     (dlyrst),       .T       ()       );  //***************************************************************************  // Rank 1 capture: Use IDDR to generate two SDR outputs  //***************************************************************************  // invert clock to IDDR in order to use SAME_EDGE mode (otherwise, we "run  // out of clocks" because DQS is not continuous  assign dq_iddr_clk = ~dqs;  //***************************************************************************  // Rank 2 capture: Use fabric flops to capture Rank 1 output. Use RPM and  // DIRT strings here.  // BEL ("Basic Element of Logic") and relative location constraints for  // second stage capture. C  // Varies according:  //  (1) I/O column (left, center, right) used  //  (2) Which I/O in I/O pair (master, slave) used  // NOTES:  //  1. Placing unrelated logic can cause routing conflicts later during  //     PAR (e.g. if MAP uses carry chain in one of these slices, the  //     AX/BX/CX/DX input may be used instead for the carry-chain, which  //     then results in a routing conflict (with the directed routing  //     constraints for the IDDR -> fabric flop paths). Additional unused  //     LUT's and carry-chains are instantiated to prevent MAP from using  //     these resources.  //***************************************************************************  // Six different cases for the different I/O column, master/slave  // combinations (can't seem to do this using a localparam, which  // would be easier, XST doesn't allow it)  generate    if ((DQ_MS == 1) && (DQ_COL == 0)) begin: gen_stg2_0m      //*****************************************************************      // master, left      //*****************************************************************      IDDR #        (         .DDR_CLK_EDGE ("SAME_EDGE")         )        u_iddr_dq          (           .Q1 (stg1_out_fall_0m),           .Q2 (stg1_out_rise_0m),           .C  (dq_iddr_clk),           .CE (ce),           .D  (dq_idelay),           .R  (1'b0),           .S  (1'b0)           );      //*********************************************************      // Slice #1 (posedge CLK): Used for:      //  1. IDDR transfer to CLK0 rising edge domain ("stg2a")      //  2. stg2 falling edge -> stg3 rising edge transfer      //*********************************************************      // Stage 2 capture      (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "DFF" *)      FDC u_ff_stg2a_fall        (         .D   (stg1_out_fall_0m),         .Q   (stg2a_out_fall),         .C   (clk0),         .CLR (1'b0)         )/* synthesis syn_preserve = 1 */          /* synthesis syn_replicate = 0 */;      (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "CFF" *)      FDC u_ff_stg2a_rise        (         .D   (stg1_out_rise_0m),         .Q   (stg2a_out_rise),         .C   (clk0),         .CLR (1'b0)         )/* synthesis syn_preserve = 1 */          /* synthesis syn_replicate = 0 */;      // Stage 3 falling -> rising edge translation      (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "BFF" *)      FDC u_ff_stg3b_fall        (         .D   (stg2b_out_fall),         .Q   (stg3b_out_fall),         .C   (clk0),         .CLR (1'b0)         )/* synthesis syn_preserve = 1 */          /* synthesis syn_replicate = 0 */;      (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "AFF" *)      FDC u_ff_stg3b_rise        (         .D   (stg2b_out_rise),         .Q   (stg3b_out_rise),         .C   (clk0),         .CLR (1'b0)         )/* synthesis syn_preserve = 1 */          /* synthesis syn_replicate = 0 */;      //*********************************************************      // Slice #2 (posedge CLK): Used for:      //  1. IDDR transfer to CLK0 falling edge domain ("stg2b")      //*********************************************************      (* HU_SET = "stg2_capture", RLOC = "X3Y0", BEL = "DFF" *)      FDC_1 u_ff_stg2b_fall        (         .D   (stg1_out_fall_0m),         .Q   (stg2b_out_fall),         .C   (clk0),         .CLR (1'b0)         )/* synthesis syn_preserve = 1 */          /* synthesis syn_replicate = 0 */;      (* HU_SET = "stg2_capture", RLOC = "X3Y0", BEL = "CFF" *)      FDC_1 u_ff_stg2b_rise        (         .D   (stg1_out_rise_0m),         .Q   (stg2b_out_rise),         .C   (clk0),         .CLR (1'b0)         )/* synthesis syn_preserve = 1 */          /* synthesis syn_replicate = 0 */;      //*********************************************************      // Dummy logic. See comments at beginning of generate statement      //*********************************************************      (* HU_SET = "stg2_capture", RLOC = "X2Y0", syn_noprune = 1 *)      CARRY4 u_dummy_carry_stg2a        (         .CO     (dummy_carry4_co_a),         .O      (),         .CI     (1'b0),         .CYINIT (1'b0),         .DI     (dummy_lut_o5_a),         .S      (dummy_lut_o6_a)         );      (* HU_SET = "stg2_capture", RLOC = "X2Y0", BEL = "A6LUT",         syn_noprune = 1 *)      LUT6_2 #        (         .INIT (64'h0000000000000000)         )        u_dummy_lut_stg2a_a          (           .O5 (dummy_lut_o5_a[0]),           .O6 (dummy_lut_o6_a[0]),           .I0 (),           .I1 (),           .I2 (),           .I3 (),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -