UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor panaj
Visitor
15,806 Views
Registered: ‎11-14-2013

The constraint about IDELAYCTRL and IDELAYE2 in source synchronous interface.

I’m designing a source synchronous interface for ADS6444( ADC of TI) with K7 series FPGA XC7K325T-2FFG900. There are three ADCs, so I use three pairs of IDELAYCTRL and IDELAYE2 to synchronize their BitClks respectively. They are in different clock regions, one is in X0Y3 region, one is in X0Y5 region and one is in X0Y6 region. What I want to know is how to constraint the IDELAYCTRL and IDELAYE2 ?

Actually, I tried two methods:

1)     Give LOC constraints to each IDELAYCTRL, IDELAYE2, BUFIO and BUFR, the source code for one ADC is as follows:

         // IDELAYCTRL: IDELAYE2/ODELAYE2 Tap Delay Value Control

   //             Kintex-7

   // Xilinx HDL Language Template, version 14.3

 

   (*LOC="IDELAYCTRL_X0Y3"*)

   IDELAYCTRL AdcToplevel_I_IdlyCtrl (

      .RDY(IntIdlyCtrlRdy),  // 1-bit output: Ready output

      .REFCLK(SysRefClk),    // 1-bit input: Reference clock input

      .RST(AppsSysRst)       // 1-bit input: Active high reset input

   );       

        

assign   IntClkCtrlDlyRst = BitClkRst;

 

   wire IntBitClk;

         wire IntBitClk_MonClkIn;

   wire IntBitClk_RefClkIn;

   // IDELAYE2: Input Fixed or Variable Delay Element

   //           Kintex-7

   // Xilinx HDL Language Template, version 14.3

 

 

   (*LOC="IDELAY_X0Y172"*)

   IDELAYE2 #(

      .CINVCTRL_SEL("FALSE"),          // Enable dynamic clock inversion (FALSE, TRUE)

      .DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)

      .HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")

      .IDELAY_TYPE("VARIABLE"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE

      .IDELAY_VALUE(16),                // Input delay tap setting (0-31)

      .PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE

      .REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0).

      .SIGNAL_PATTERN("CLOCK")          // DATA, CLOCK input signal

   )

   IDELAYE2_Inst (

      .CNTVALUEOUT(), // 5-bit output: Counter value output

      .DATAOUT(IntBitClk),         // 1-bit output: Delayed data output

      .C(IntBitClk_RefClkIn),     // 1-bit input: Clock input

      .CE(IntClkCtrlDlyCe),      // 1-bit input: Active high enable increment/decrement input

      .CINVCTRL(),       // 1-bit input: Dynamic clock inversion input

      .CNTVALUEIN(),   // 5-bit input: Counter value input

      .DATAIN(),           // 1-bit input: Internal delay data input

      .IDATAIN(BitClk),  // 1-bit input: Data input from the I/O

      .INC(IntClkCtrlDlyInc),          // 1-bit input: Increment / Decrement tap delay input

      .LD(IntClkCtrlDlyRst),          // 1-bit input: Load IDELAY_VALUE input

      .LDPIPEEN(1'b0),       // 1-bit input: Enable PIPELINE register to load data input

      .REGRST(1'b0)  // 1-bit input: Active-high reset tap-delay input. Reset for the pipeline register.Only used in VAR_LOAD_PIPE mode.

   );

 

   // End of IDELAYE2_inst instantiation

 

         wire IntBitClk_MonClkOut;

          wire IntBitClk_RefClkOut;

   (*LOC="BUFIO_X0Y12"*)

//            Input from ISERDES.O           -- Output and CLK for all ISERDES

    BUFIO AdcClk_I_Bufio (

      .O(IntBitClk_MonClkOut),     // Clock buffer output,IntBitClk_MonClkOut

      .I(IntBitClk)      // Clock buffer input, IntClkCtrl_OutClk

   );

  

   // End of BUFIO_inst instantiation

        

  // BUFR: Regional Clock Buffer for I/O and Logic Resources within a Clock Region

   //       Kintex-7

   // Xilinx HDL Language Template, version 14.3

   (*LOC="BUFR_X0Y12"*)

   BUFR #(

      .BUFR_DIVIDE("8"), // Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"

      .SIM_DEVICE("7SERIES")  // Must be set to "7SERIES"

   )

   AdcClk_I_Bufr (

      .O(IntBitClk_RefClkOut),     // 1-bit output: Clock output port

      .CE(1'b1),   // 1-bit input: Active high, clock enable (Divided modes only)

      .CLR(1'b0), // 1-bit input: Active high, asynchronous clear (Divided modes only)

      .I(IntBitClk)      // 1-bit input: Clock buffer input driven by an IBUFG, MMCM or local interconnect

   );

   // End of BUFR_inst instantiation

 

2)     Constraint each pair of IDELAYCTRL and IDELAYE2 in one bank into one IODELAY_GROUP, the source code for one ADC is as follows:

   (* IODELAY_GROUP = "Group_ADS1" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL

   IDELAYCTRL AdcToplevel_I_IdlyCtrl (

      .RDY(IntIdlyCtrlRdy),  // 1-bit output: Ready output

      .REFCLK(SysRefClk),    // 1-bit input: Reference clock input

      .RST(AppsSysRst)       // 1-bit input: Active high reset input

   );

   assign   IntClkCtrlDlyRst = BitClkRst;

 

   wire IntBitClk;

         wire IntBitClk_MonClkIn;

   wire IntBitClk_RefClkIn;

   // IDELAYE2: Input Fixed or Variable Delay Element

   //           Kintex-7

   // Xilinx HDL Language Template, version 14.3

 

   (* IODELAY_GROUP = "Group_ADS1" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL

   IDELAYE2 #(

      .CINVCTRL_SEL("FALSE"),          // Enable dynamic clock inversion (FALSE, TRUE)

      .DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)

      .HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")

      .IDELAY_TYPE("VARIABLE"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE

      .IDELAY_VALUE(16),                // Input delay tap setting (0-31)

      .PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE

      .REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0).

      .SIGNAL_PATTERN("CLOCK")          // DATA, CLOCK input signal

   )

   IDELAYE2_Inst (

      .CNTVALUEOUT(), // 5-bit output: Counter value output

      .DATAOUT(IntBitClk),         // 1-bit output: Delayed data output

      .C(IntBitClk_RefClkIn),     // 1-bit input: Clock input

      .CE(IntClkCtrlDlyCe),      // 1-bit input: Active high enable increment/decrement input

      .CINVCTRL(),       // 1-bit input: Dynamic clock inversion input

      .CNTVALUEIN(),   // 5-bit input: Counter value input

      .DATAIN(),           // 1-bit input: Internal delay data input

      .IDATAIN(BitClk),  // 1-bit input: Data input from the I/O

      .INC(IntClkCtrlDlyInc),          // 1-bit input: Increment / Decrement tap delay input

      .LD(IntClkCtrlDlyRst),          // 1-bit input: Load IDELAY_VALUE input

      .LDPIPEEN(1'b0),       // 1-bit input: Enable PIPELINE register to load data input

      .REGRST(1'b0)  // 1-bit input: Active-high reset tap-delay input. Reset for the pipeline register.Only used in VAR_LOAD_PIPE mode.

   );

 

   // End of IDELAYE2_inst instantiation

 

         wire IntBitClk_MonClkOut;

          wire IntBitClk_RefClkOut;

//            Input from ISERDES.O           -- Output and CLK for all ISERDES

    BUFIO AdcClk_I_Bufio (

      .O(IntBitClk_MonClkOut),     // Clock buffer output,IntBitClk_MonClkOut

      .I(IntBitClk)      // Clock buffer input, IntClkCtrl_OutClk

   );

  

   // End of BUFIO_inst instantiation

        

  // BUFR: Regional Clock Buffer for I/O and Logic Resources within a Clock Region

   //       Kintex-7

   // Xilinx HDL Language Template, version 14.3

   BUFR #(

      .BUFR_DIVIDE("8"), // Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"

      .SIM_DEVICE("7SERIES")  // Must be set to "7SERIES"

   )

   AdcClk_I_Bufr (

      .O(IntBitClk_RefClkOut),     // 1-bit output: Clock output port

      .CE(1'b1),   // 1-bit input: Active high, clock enable (Divided modes only)

      .CLR(1'b0), // 1-bit input: Active high, asynchronous clear (Divided modes only)

      .I(IntBitClk)      // 1-bit input: Clock buffer input driven by an IBUFG, MMCM or local interconnect

   );

 

   // End of BUFR_inst instantiation

 

The errors are as follows:

ERROR 

Place:1073 - Placer was unable to create RPM[IOB_RPMs] for the component LS_AD1_DCLKP of type IOB33V for the following reason. The reason for this issue: The structured logic has to be merged with another RPM which causes a placement violation for component < empty >. The following components are part of this structure: IOB33V LS_AD1_DCLKP ILOGIC ADC_Interface_Inst/Adc_Toplevel_Adc1/ADC_Bit1_Inst/ISERDESE2_Inst

 

ERROR 

Place:1073 - Placer was unable to create RPM[IOB_RPMs] for the component LS_AD2_DCLKP of type IOB33V for the following reason. The reason for this issue: The structured logic has to be merged with another RPM which causes a placement violation for component < empty >. The following components are part of this structure: IOB33V LS_AD2_DCLKP ILOGIC ADC_Interface_Inst/Adc_Toplevel_Adc2/ADC_Bit2_Inst/ISERDESE2_Inst

 

ERROR 

Place:1073 - Placer was unable to create RPM[IOB_RPMs] for the component LS_AD3_DCLKP of type IOB33V for the following reason. The reason for this issue: The structured logic has to be merged with another RPM which causes a placement violation for component < empty >. The following components are part of this structure: IOB33V LS_AD3_DCLKP ILOGIC ADC_Interface_Inst/Adc_Toplevel_Adc3/ADC_Bit3_Inst/ISERDESE2_Inst

 

ERROR 

Pack:1654 - The timing-driven placement phase encountered an error.

 </t

 

0 Kudos
4 Replies
Historian
Historian
15,788 Views
Registered: ‎01-23-2009

Re: The constraint about IDELAYCTRL and IDELAYE2 in source synchronous interface.

OK - way too many LOC constraints... Actually NONE are required...

 

First, just LOC your primary inputs to the pin locations they need. Since there is only a single connection from an IOB to an ISERDES and IDELAY, the IDELAY is automatically LOC'ed to the IOB of the pin.

 

Second, the IDELAYCTRL is a reference for calibrating the IDELAYs. While it is true that there is one per bank, you don't actually have to instantiate each one. If you instantiate only one in your RTL design, the tools will automatically replicate it into all banks that have an IDELAY or ODELAY.

 

Generally, all IDELAYCTRL cells in an FPGA are identical - they all use the same reset and clock inputs, and people rarely pay attention to the RDY. So, instantiating it once and allowing the tool to replicate it is exactly what you want. There are rare cases where you might want different IDELAYCTRL to have different inputs - say some of them run at 300MHz and some at 200MHz (in a -3 part), or you want to independently reset some of them (but I can't figure out why anyone would ever want to). In this case, what you do is specify an IODELAY_GROUP property for each IDELAY and for each IDELAYCTRL. If an IDELAY and IDELAYCTRL share the same IODELAY_GROUP then that instructs the tool to replicate teh IDELAYCTRL with that IODELAY_GROUP into the bank with the IDELAY that has that IODELAY_GROUP. If there are IOBs in the same bank with different IODELAY_GROUPs then the tool will fail with an error.

 

But, in your situation, the simplest thing to do is to remove all the LOCs (except in your UCF/XDC for the pins), remove  all the IODELAY_GROUP properties, instantiate only a single IDELAYCTRL, and let the tools do the rest.

 

Avrum

Visitor panaj
Visitor
15,761 Views
Registered: ‎11-14-2013

Re: The constraint about IDELAYCTRL and IDELAYE2 in source synchronous interface.

Hi Avrum,

Thanks for your answer. But now I get some new problems. I found that all the signal connecting to the D input of ISERDESE2 get the same Warnings, so is the IDELAYCTRL. 

That is as follows:

Starting initial Timing Analysis.  WARNING:Par:288 - The signal AdcToplevel_InstA/AdcData_Inst/IntDatD0_n has no load.  PAR will not attempt to route this signal.

WARNING:Par:288 - The signal AdcToplevel_InstA/AdcData_Inst/IntDatD0_p has no load.  PAR will not attempt to route this signal.

WARNING:Par:288 - The signal AdcToplevel_InstA/AdcData_Inst/IntDatD1_n has no load.  PAR will not attempt to route this signal.

WARNING:Par:288 - The signal AdcToplevel_InstA/AdcData_Inst/IntDatD1_p has no load.  PAR will not attempt to route this signal.

WARNING:Par:288 - The signal AdcToplevel_InstA/AdcFrame_Inst/IntFrmClkToIsrds_n has no load.  PAR will not attempt to route this signal.

WARNING:Par:288 - The signal AdcToplevel_InstA/AdcFrame_Inst/IntFrmClkToIsrds_p has no load.  PAR will not attempt to route this signal.

WARNING:Par:288 - The signal SysRefClk has no load.  PAR will not attempt to route this signal.

WARNING:Par:283 - There are 7 loadless signals in this design. This design will cause Bitgen to issue DRC warnings.

WARNING:PhysDesignRules:367 - The signal

   <AdcToplevel_InstA/AdcData_Inst/IntDatD0_n> is incomplete. The signal does

   not drive any load pins in the design.

WARNING:PhysDesignRules:367 - The signal

   <AdcToplevel_InstA/AdcData_Inst/IntDatD0_p> is incomplete. The signal does

   not drive any load pins in the design.

WARNING:PhysDesignRules:367 - The signal

   <AdcToplevel_InstA/AdcData_Inst/IntDatD1_n> is incomplete. The signal does

   not drive any load pins in the design.

WARNING:PhysDesignRules:367 - The signal

   <AdcToplevel_InstA/AdcData_Inst/IntDatD1_p> is incomplete. The signal does

   not drive any load pins in the design.

WARNING:PhysDesignRules:367 - The signal

   <AdcToplevel_InstA/AdcFrame_Inst/IntFrmClkToIsrds_n> is incomplete. The

   signal does not drive any load pins in the design.

WARNING:PhysDesignRules:367 - The signal

   <AdcToplevel_InstA/AdcFrame_Inst/IntFrmClkToIsrds_p> is incomplete. The

   signal does not drive any load pins in the design.

WARNING:PhysDesignRules:367 - The signal <SysRefClk> is incomplete. The signal

   does not drive any load pins in the design.

 

The related code is as follows:

The first part(about IntDatD0_p/n and IntDatD1_p/n):

   IBUFDS_DIFF_OUT #(

      .DIFF_TERM("TRUE"),   // Differential Termination, "TRUE"/"FALSE" 

      .IBUF_LOW_PWR("TRUE"), // Low power="TRUE", Highest performance="FALSE" 

      .IOSTANDARD("LVDS_25") // Specify the input I/O standard

   ) AdcDataChnl_I_Ibufds_DD0 (

      .O(IntDatD0_p),   // Buffer diff_p output

      .OB(IntDatD0_n), // Buffer diff_n output

      .I(DatD0_p),   // Diff_p buffer input (connect directly to top-level port)

      .IB(DatD0_n)  // Diff_n buffer input (connect directly to top-level port)

   );  

 

   IBUFDS_DIFF_OUT #(

      .DIFF_TERM("TRUE"),   // Differential Termination, "TRUE"/"FALSE" 

      .IBUF_LOW_PWR("TRUE"), // Low power="TRUE", Highest performance="FALSE" 

      .IOSTANDARD("LVDS_25") // Specify the input I/O standard

   ) AdcDataChnl_I_Ibufds_DD1 (

      .O(IntDatD1_p),   // Buffer diff_p output

      .OB(IntDatD1_n), // Buffer diff_n output

      .I(DatD1_p),   // Diff_p buffer input (connect directly to top-level port)

      .IB(DatD1_n)  // Diff_n buffer input (connect directly to top-level port)

   );  

  

ISERDESE2 #(

      .DATA_RATE("SDR"),           // DDR, SDR

      .DATA_WIDTH(4),              // Parallel data width (2-8,10,14)

      .DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)

      .DYN_CLK_INV_EN("FALSE"),    // Enable DYNCLKINVSEL inversion (FALSE, TRUE)

      // INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)

      .INIT_Q1(1'b0),

      .INIT_Q2(1'b0),

      .INIT_Q3(1'b0),

      .INIT_Q4(1'b0),

      .INTERFACE_TYPE("NETWORKING"),   // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE

      .IOBDELAY("NONE"),           // NONE, BOTH, IBUF, IFD

      .NUM_CE(1),                  // Number of clock enables (1,2)

      .OFB_USED("FALSE"),          // Select OFB path (FALSE, TRUE)

      .SERDES_MODE("MASTER"),      // MASTER, SLAVE

      // SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)

      .SRVAL_Q1(1'b0),

      .SRVAL_Q2(1'b0),

      .SRVAL_Q3(1'b0),

      .SRVAL_Q4(1'b0) 

   )

   AdcDataChnl_I_Isrds_D0_p (

      .O(),                       // 1-bit output: Combinatorial output

      // Q1 - Q8: 1-bit (each) output: Registered data outputs

      .Q1(IntDatSrds0Out[6]),

      .Q2(IntDatSrds0Out[4]),

      .Q3(IntDatSrds0Out[2]),

      .Q4(IntDatSrds0Out[0]),

      .Q5(),

      .Q6(),

      .Q7(),

      .Q8(),

      // SHIFTOUT1-SHIFTOUT2: 1-bit (each) output: Data width expansion output ports

      .SHIFTOUT1(),

      .SHIFTOUT2(),

      .BITSLIP(DatBitSlip_p),           // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to

                                   // CLKDIV when asserted (active High). Subsequently, the data seen on the Q1

                                   // to Q8 output ports will shift, as in a barrel-shifter operation, one

                                   // position every time Bitslip is invoked (DDR operation is different from

                                   // SDR).

 

      // CE1, CE2: 1-bit (each) input: Data register clock enable inputs

      .CE1(IntDatDone),

      .CE2(1'b0),

      .CLKDIVP(1'b0),           // 1-bit input: TBD

      // Clocks: 1-bit (each) input: ISERDESE2 clock input ports

      .CLK(IntDatClk),                   // 1-bit input: High-speed clock

      .CLKB(1'b0),                 // 1-bit input: High-speed secondary clock

      .CLKDIV(DatClkDiv),             // 1-bit input: Divided clock

      .OCLK(1'b0),                 // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY" 

      // Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity

      .DYNCLKDIVSEL(1'b0), // 1-bit input: Dynamic CLKDIV inversion

      .DYNCLKSEL(1'b0),       // 1-bit input: Dynamic CLK/CLKB inversion

      // Input Data&colon; 1-bit (each) input: ISERDESE2 data input ports

      .D(IntDatD0_p),                       // 1-bit input: Data input

      .DDLY(1'b0),                 // 1-bit input: Serial data from IDELAYE2

      .OFB(1'b0),                   // 1-bit input: Data feedback from OSERDESE2

      .OCLKB(1'b0),               // 1-bit input: High speed negative edge output clock

      .RST(DatRstIn),                   // 1-bit input: Active high asynchronous reset

      // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports

      .SHIFTIN1(1'b0),

      .SHIFTIN2(1'b0) 

   );

 

 

   ISERDESE2 #(

      .DATA_RATE("SDR"),           // DDR, SDR

      .DATA_WIDTH(4),              // Parallel data width (2-8,10,14)

      .DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)

      .DYN_CLK_INV_EN("FALSE"),    // Enable DYNCLKINVSEL inversion (FALSE, TRUE)

      // INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)

      .INIT_Q1(1'b0),

      .INIT_Q2(1'b0),

      .INIT_Q3(1'b0),

      .INIT_Q4(1'b0),

      .INTERFACE_TYPE("NETWORKING"),   // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE

      .IOBDELAY("NONE"),           // NONE, BOTH, IBUF, IFD

      .NUM_CE(1),                  // Number of clock enables (1,2)

      .OFB_USED("FALSE"),          // Select OFB path (FALSE, TRUE)

      .SERDES_MODE("MASTER"),      // MASTER, SLAVE

      // SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)

      .SRVAL_Q1(1'b0),

      .SRVAL_Q2(1'b0),

      .SRVAL_Q3(1'b0),

      .SRVAL_Q4(1'b0) 

   )

   AdcDataChnl_I_Isrds_D0_n (

      .O(),                       // 1-bit output: Combinatorial output

      // Q1 - Q8: 1-bit (each) output: Registered data outputs

      .Q1(IntDatSrds0Out[7]),

      .Q2(IntDatSrds0Out[5]),

      .Q3(IntDatSrds0Out[3]),

      .Q4(IntDatSrds0Out[1]),

      .Q5(),

      .Q6(),

      .Q7(),

      .Q8(),

      // SHIFTOUT1-SHIFTOUT2: 1-bit (each) output: Data width expansion output ports

      .SHIFTOUT1(),

      .SHIFTOUT2(),

      .BITSLIP(DatBitSlip_n),           // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to

                                   // CLKDIV when asserted (active High). Subsequently, the data seen on the Q1

                                   // to Q8 output ports will shift, as in a barrel-shifter operation, one

                                   // position every time Bitslip is invoked (DDR operation is different from

                                   // SDR).

 

      // CE1, CE2: 1-bit (each) input: Data register clock enable inputs

      .CE1(IntDatDone),

      .CE2(1'b0),

      .CLKDIVP(1'b0),           // 1-bit input: TBD

      // Clocks: 1-bit (each) input: ISERDESE2 clock input ports

      .CLK(IntDatClk_n),                   // 1-bit input: High-speed clock

      .CLKB(1'b0),                 // 1-bit input: High-speed secondary clock

      .CLKDIV(DatClkDiv),             // 1-bit input: Divided clock

      .OCLK(1'b0),                 // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY" 

      // Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity

      .DYNCLKDIVSEL(1'b0), // 1-bit input: Dynamic CLKDIV inversion

      .DYNCLKSEL(1'b0),       // 1-bit input: Dynamic CLK/CLKB inversion

      // Input Data&colon; 1-bit (each) input: ISERDESE2 data input ports

      .D(IntDatD0_n),                       // 1-bit input: Data input

      .DDLY(1'b0),                 // 1-bit input: Serial data from IDELAYE2

      .OFB(1'b0),                   // 1-bit input: Data feedback from OSERDESE2

      .OCLKB(1'b0),               // 1-bit input: High speed negative edge output clock

      .RST(DatRstIn),                   // 1-bit input: Active high asynchronous reset

      // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports

      .SHIFTIN1(1'b0),

      .SHIFTIN2(1'b0) 

   );

 

 

   ISERDESE2 #(

      .DATA_RATE("SDR"),           // DDR, SDR

      .DATA_WIDTH(4),              // Parallel data width (2-8,10,14)

      .DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)

      .DYN_CLK_INV_EN("FALSE"),    // Enable DYNCLKINVSEL inversion (FALSE, TRUE)

      // INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)

      .INIT_Q1(1'b0),

      .INIT_Q2(1'b0),

      .INIT_Q3(1'b0),

      .INIT_Q4(1'b0),

      .INTERFACE_TYPE("NETWORKING"),   // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE

      .IOBDELAY("NONE"),           // NONE, BOTH, IBUF, IFD

      .NUM_CE(1),                  // Number of clock enables (1,2)

      .OFB_USED("FALSE"),          // Select OFB path (FALSE, TRUE)

      .SERDES_MODE("MASTER"),      // MASTER, SLAVE

      // SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)

      .SRVAL_Q1(1'b0),

      .SRVAL_Q2(1'b0),

      .SRVAL_Q3(1'b0),

      .SRVAL_Q4(1'b0) 

   )

   AdcDataChnl_I_Isrds_D1_p (

      .O(),                       // 1-bit output: Combinatorial output

      // Q1 - Q8: 1-bit (each) output: Registered data outputs

      .Q1(IntDatSrds1Out[6]),

      .Q2(IntDatSrds1Out[4]),

      .Q3(IntDatSrds1Out[2]),

      .Q4(IntDatSrds1Out[0]),

      .Q5(),

      .Q6(),

      .Q7(),

      .Q8(),

      // SHIFTOUT1-SHIFTOUT2: 1-bit (each) output: Data width expansion output ports

      .SHIFTOUT1(),

      .SHIFTOUT2(),

      .BITSLIP(DatBitSlip_p),           // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to

                                   // CLKDIV when asserted (active High). Subsequently, the data seen on the Q1

                                   // to Q8 output ports will shift, as in a barrel-shifter operation, one

                                   // position every time Bitslip is invoked (DDR operation is different from

                                   // SDR).

 

      // CE1, CE2: 1-bit (each) input: Data register clock enable inputs

      .CE1(IntDatDone),

      .CE2(1'b0),

      .CLKDIVP(1'b0),           // 1-bit input: TBD

      // Clocks: 1-bit (each) input: ISERDESE2 clock input ports

      .CLK(IntDatClk),                   // 1-bit input: High-speed clock

      .CLKB(1'b0),                 // 1-bit input: High-speed secondary clock

      .CLKDIV(DatClkDiv),             // 1-bit input: Divided clock

      .OCLK(1'b0),                 // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY" 

      // Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity

      .DYNCLKDIVSEL(1'b0), // 1-bit input: Dynamic CLKDIV inversion

      .DYNCLKSEL(1'b0),       // 1-bit input: Dynamic CLK/CLKB inversion

      // Input Data&colon; 1-bit (each) input: ISERDESE2 data input ports

      .D(IntDatD1_p),                       // 1-bit input: Data input

      .DDLY(1'b0),                 // 1-bit input: Serial data from IDELAYE2

      .OFB(1'b0),                   // 1-bit input: Data feedback from OSERDESE2

      .OCLKB(1'b0),               // 1-bit input: High speed negative edge output clock

      .RST(DatRstIn),                   // 1-bit input: Active high asynchronous reset

      // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports

      .SHIFTIN1(1'b0),

      .SHIFTIN2(1'b0) 

   );

 

  ISERDESE2 #(

      .DATA_RATE("SDR"),           // DDR, SDR

      .DATA_WIDTH(4),              // Parallel data width (2-8,10,14)

      .DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)

      .DYN_CLK_INV_EN("FALSE"),    // Enable DYNCLKINVSEL inversion (FALSE, TRUE)

      // INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)

      .INIT_Q1(1'b0),

      .INIT_Q2(1'b0),

      .INIT_Q3(1'b0),

      .INIT_Q4(1'b0),

      .INTERFACE_TYPE("NETWORKING"),   // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE

      .IOBDELAY("NONE"),           // NONE, BOTH, IBUF, IFD

      .NUM_CE(1),                  // Number of clock enables (1,2)

      .OFB_USED("FALSE"),          // Select OFB path (FALSE, TRUE)

      .SERDES_MODE("MASTER"),      // MASTER, SLAVE

      // SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)

      .SRVAL_Q1(1'b0),

      .SRVAL_Q2(1'b0),

      .SRVAL_Q3(1'b0),

      .SRVAL_Q4(1'b0) 

   )

   AdcDataChnl_I_Isrds_D1_n (

      .O(),                       // 1-bit output: Combinatorial output

      // Q1 - Q8: 1-bit (each) output: Registered data outputs

      .Q1(IntDatSrds1Out[7]),

      .Q2(IntDatSrds1Out[5]),

      .Q3(IntDatSrds1Out[3]),

      .Q4(IntDatSrds1Out[1]),

      .Q5(),

      .Q6(),

      .Q7(),

      .Q8(),

      // SHIFTOUT1-SHIFTOUT2: 1-bit (each) output: Data width expansion output ports

      .SHIFTOUT1(),

      .SHIFTOUT2(),

      .BITSLIP(DatBitSlip_n),           // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to

                                   // CLKDIV when asserted (active High). Subsequently, the data seen on the Q1

                                   // to Q8 output ports will shift, as in a barrel-shifter operation, one

                                   // position every time Bitslip is invoked (DDR operation is different from

                                   // SDR).

 

      // CE1, CE2: 1-bit (each) input: Data register clock enable inputs

      .CE1(IntDatDone),

      .CE2(1'b0),

      .CLKDIVP(1'b0),           // 1-bit input: TBD

      // Clocks: 1-bit (each) input: ISERDESE2 clock input ports

      .CLK(IntDatClk_n),                   // 1-bit input: High-speed clock

      .CLKB(1'b0),                 // 1-bit input: High-speed secondary clock

      .CLKDIV(DatClkDiv),             // 1-bit input: Divided clock

      .OCLK(1'b0),                 // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY" 

      // Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity

      .DYNCLKDIVSEL(1'b0), // 1-bit input: Dynamic CLKDIV inversion

      .DYNCLKSEL(1'b0),       // 1-bit input: Dynamic CLK/CLKB inversion

      // Input Data&colon; 1-bit (each) input: ISERDESE2 data input ports

      .D(IntDatD1_n),                       // 1-bit input: Data input

      .DDLY(1'b0),                 // 1-bit input: Serial data from IDELAYE2

      .OFB(1'b0),                   // 1-bit input: Data feedback from OSERDESE2

      .OCLKB(1'b0),               // 1-bit input: High speed negative edge output clock

      .RST(DatRstIn),                   // 1-bit input: Active high asynchronous reset

      // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports

      .SHIFTIN1(1'b0),

      .SHIFTIN2(1'b0) 

   );

 

The second part(about IntFrmClkToIsrds_p/n ):

   IBUFDS_DIFF_OUT #(

      .DIFF_TERM("TRUE"),   // Differential Termination, "TRUE"/"FALSE" 

      .IBUF_LOW_PWR("TRUE"), // Low power="TRUE", Highest performance="FALSE" 

      .IOSTANDARD("LVDS_25") // Specify the input I/O standard. Leave it to be constraint in the .ucf .

   ) IBUFDS_DIFF_OUT_Inst (

      .O(IntFrmClkToIsrds_p),   // Buffer diff_p output

      .OB(IntFrmClkToIsrds_n), // Buffer diff_n output

      .I(FrmClk_p),   // Diff_p buffer input (connect directly to top-level port)

      .IB(FrmClk_n)  // Diff_n buffer input (connect directly to top-level port)

   );

 

//   IBUFDS #(

//      .DIFF_TERM("TRUE"),       // Differential Termination

//      .IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 

//      .IOSTANDARD("DEFAULT")     // Specify the input I/O standard

//   ) IBUFDS_Inst (

//      .O(IntFrmClkToIsrds_p),  // Buffer output

//      .I(FrmClk_p),  // Diff_p buffer input (connect directly to top-level port)

//      .IB(FrmClk_n) // Diff_n buffer input (connect directly to top-level port)

//   );

//assign IntFrmClkToIsrds_n = ~IntFrmClkToIsrds_p;

 

   ISERDESE2 #(

      .DATA_RATE("SDR"),           // DDR, SDR

      .DATA_WIDTH(4),              // Parallel data width (2-8,10,14)

      .DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)

      .DYN_CLK_INV_EN("FALSE"),    // Enable DYNCLKINVSEL inversion (FALSE, TRUE)

      // INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)

      .INIT_Q1(1'b0),

      .INIT_Q2(1'b0),

      .INIT_Q3(1'b0),

      .INIT_Q4(1'b0),

      .INTERFACE_TYPE("NETWORKING"),   // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE

      .IOBDELAY("NONE"),           // NONE, BOTH, IBUF, IFD

      .NUM_CE(1),                  // Number of clock enables (1,2)

      .OFB_USED("FALSE"),          // Select OFB path (FALSE, TRUE)

      .SERDES_MODE("MASTER"),      // MASTER, SLAVE

      // SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)

      .SRVAL_Q1(1'b0),

      .SRVAL_Q2(1'b0),

      .SRVAL_Q3(1'b0),

      .SRVAL_Q4(1'b0) 

   )

   AdcFrm_I_Isrds_p (

      .O(),                       // 1-bit output: Combinatorial output

      // Q1 - Q8: 1-bit (each) output: Registered data outputs

      .Q1(IntFrmSrdsOut[6]),

      .Q2(IntFrmSrdsOut[4]),

      .Q3(IntFrmSrdsOut[2]),

      .Q4(IntFrmSrdsOut[0]),

      .Q5(),

      .Q6(),

      .Q7(),

      .Q8(),

      // SHIFTOUT1-SHIFTOUT2: 1-bit (each) output: Data width expansion output ports

      .SHIFTOUT1(),

      .SHIFTOUT2(),

      .BITSLIP(IntFrmClkBitSlip_p),           // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to

                                   // CLKDIV when asserted (active High). Subsequently, the data seen on the Q1

                                   // to Q8 output ports will shift, as in a barrel-shifter operation, one

                                   // position every time Bitslip is invoked (DDR operation is different from

                                   // SDR).

 

      // CE1, CE2: 1-bit (each) input: Data register clock enable inputs

      .CE1(IntFrmClkDone),

      .CE2(1'b0),

      .CLKDIVP(1'b0),           // 1-bit input: TBD

      // Clocks: 1-bit (each) input: ISERDESE2 clock input ports

      .CLK(IntFrmClk),                   // 1-bit input: High-speed clock

      .CLKB(1'b0),                 // 1-bit input: High-speed secondary clock

      .CLKDIV(FrmClkDiv),             // 1-bit input: Divided clock

      .OCLK(1'b0),                 // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY" 

      // Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity

      .DYNCLKDIVSEL(1'b0), // 1-bit input: Dynamic CLKDIV inversion

      .DYNCLKSEL(1'b0),       // 1-bit input: Dynamic CLK/CLKB inversion

      // Input Data&colon; 1-bit (each) input: ISERDESE2 data input ports

      .D(IntFrmClkToIsrds_p),                       // 1-bit input: Data input

      .DDLY(1'b0),                 // 1-bit input: Serial data from IDELAYE2

      .OFB(1'b0),                   // 1-bit input: Data feedback from OSERDESE2

      .OCLKB(1'b0),               // 1-bit input: High speed negative edge output clock

      .RST(IntFrmRstOut),         // 1-bit input: Active high asynchronous reset. How about using FrmClkRst?

      // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports

      .SHIFTIN1(1'b0),

      .SHIFTIN2(1'b0) 

   );

 

  ISERDESE2 #(

      .DATA_RATE("SDR"),           // DDR, SDR

      .DATA_WIDTH(4),              // Parallel data width (2-8,10,14)

      .DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)

      .DYN_CLK_INV_EN("FALSE"),    // Enable DYNCLKINVSEL inversion (FALSE, TRUE)

      // INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)

      .INIT_Q1(1'b0),

      .INIT_Q2(1'b0),

      .INIT_Q3(1'b0),

      .INIT_Q4(1'b0),

      .INTERFACE_TYPE("NETWORKING"),   // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE

      .IOBDELAY("NONE"),           // NONE, BOTH, IBUF, IFD

      .NUM_CE(1),                  // Number of clock enables (1,2)

      .OFB_USED("FALSE"),          // Select OFB path (FALSE, TRUE)

      .SERDES_MODE("MASTER"),      // MASTER, SLAVE

      // SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)

      .SRVAL_Q1(1'b0),

      .SRVAL_Q2(1'b0),

      .SRVAL_Q3(1'b0),

      .SRVAL_Q4(1'b0) 

   )

   AdcFrm_I_Isrds_n (

      .O(),                       // 1-bit output: Combinatorial output

      // Q1 - Q8: 1-bit (each) output: Registered data outputs

      .Q1(IntFrmSrdsOut[7]),

      .Q2(IntFrmSrdsOut[5]),

      .Q3(IntFrmSrdsOut[3]),

      .Q4(IntFrmSrdsOut[1]),

      .Q5(),

      .Q6(),

      .Q7(),

      .Q8(),

      // SHIFTOUT1-SHIFTOUT2: 1-bit (each) output: Data width expansion output ports

      .SHIFTOUT1(),

      .SHIFTOUT2(),

      .BITSLIP(IntFrmClkBitSlip_n),           // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to

                                   // CLKDIV when asserted (active High). Subsequently, the data seen on the Q1

                                   // to Q8 output ports will shift, as in a barrel-shifter operation, one

                                   // position every time Bitslip is invoked (DDR operation is different from

                                   // SDR).

 

      // CE1, CE2: 1-bit (each) input: Data register clock enable inputs

      .CE1(IntFrmClkDone),

      .CE2(1'b0),

      .CLKDIVP(1'b0),           // 1-bit input: TBD

      // Clocks: 1-bit (each) input: ISERDESE2 clock input ports

      .CLK(IntFrmClk_n),                   // 1-bit input: High-speed clock

      .CLKB(1'b0),                 // 1-bit input: High-speed secondary clock

      .CLKDIV(FrmClkDiv),             // 1-bit input: Divided clock

      .OCLK(1'b0),                 // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY" 

      // Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity

      .DYNCLKDIVSEL(1'b0), // 1-bit input: Dynamic CLKDIV inversion

      .DYNCLKSEL(1'b0),       // 1-bit input: Dynamic CLK/CLKB inversion

      // Input Data&colon; 1-bit (each) input: ISERDESE2 data input ports

      .D(IntFrmClkToIsrds_n),                       // 1-bit input: Data input

      .DDLY(1'b0),                 // 1-bit input: Serial data from IDELAYE2

      .OFB(1'b0),                   // 1-bit input: Data feedback from OSERDESE2

      .OCLKB(1'b0),               // 1-bit input: High speed negative edge output clock

      .RST(IntFrmRstOut),                   // 1-bit input: Active high asynchronous reset.How about using FrmClkRst?

      // SHIFTIN1-SHIFTIN2: 1-bit (each) input: Data width expansion input ports

      .SHIFTIN1(1'b0),

      .SHIFTIN2(1'b0) 

   );

 

The third part(about SysRefClk,  SysRefClk sgnal is only used to drive this IDELAYCTRL):

   IDELAYCTRL AdcToplevel_I_IdlyCtrl (

      .RDY(IntIdlyCtrlRdy),       // 1-bit output: Ready output

      .REFCLK(SysRefClk), // 1-bit input: Reference clock input

      .RST(AppsSysRst)        // 1-bit input: Active high reset input

   );

 

I want to know is there anything that I didn’t take into account when using IDELAYCTRL and ISERDESE2? I will be very appreciate for your help, thanks.

0 Kudos
Scholar samcossais
Scholar
13,519 Views
Registered: ‎12-07-2009

Re: The constraint about IDELAYCTRL and IDELAYE2 in source synchronous interface.


@avrumw wrote:

OK - way too many LOC constraints... Actually NONE are required...

 

First, just LOC your primary inputs to the pin locations they need. Since there is only a single connection from an IOB to an ISERDES and IDELAY, the IDELAY is automatically LOC'ed to the IOB of the pin.

 

Second, the IDELAYCTRL is a reference for calibrating the IDELAYs. While it is true that there is one per bank, you don't actually have to instantiate each one. If you instantiate only one in your RTL design, the tools will automatically replicate it into all banks that have an IDELAY or ODELAY.

 

Generally, all IDELAYCTRL cells in an FPGA are identical - they all use the same reset and clock inputs, and people rarely pay attention to the RDY. So, instantiating it once and allowing the tool to replicate it is exactly what you want. There are rare cases where you might want different IDELAYCTRL to have different inputs - say some of them run at 300MHz and some at 200MHz (in a -3 part), or you want to independently reset some of them (but I can't figure out why anyone would ever want to). In this case, what you do is specify an IODELAY_GROUP property for each IDELAY and for each IDELAYCTRL. If an IDELAY and IDELAYCTRL share the same IODELAY_GROUP then that instructs the tool to replicate teh IDELAYCTRL with that IODELAY_GROUP into the bank with the IDELAY that has that IODELAY_GROUP. If there are IOBs in the same bank with different IODELAY_GROUPs then the tool will fail with an error.

 

But, in your situation, the simplest thing to do is to remove all the LOCs (except in your UCF/XDC for the pins), remove  all the IODELAY_GROUP properties, instantiate only a single IDELAYCTRL, and let the tools do the rest.

 

Avrum


Thanks for this information ! User guides and ISE messages were not explicit about that at all.

 

I have recently started using Vivado (after 10 years using ISE) and it is much more clear.

 

Unlike ISE who tells us to lock all the IDELAYCTRL and set a common group name for them and the corresponding IODELAYs, VIvado explicitely gives us another option, which is to instantiate only one IDELAYCTRL for the whole FPGA without any IODELAY_GROUP or LOC contraint :

 


[Place 30-351] Design has more than one unlocked and ungrouped IDELAYCTRL instances. Please instantiate a delay controller (or use an existing one if delay values allow so) and apply appropriate IODELAY_GROUP or LOC constraints on the delay instances, or instantiate only one delay controller for the design without any IODELAY_GROUP or LOC constraints. The instances involved are:
idelayctrl0_inst
 idelayctrl3_inst
 idelayctrl5_inst
 idelayctrl6_inst
 and idelayctrl7_inst


 

 

Setting the right location and group was REALLY inconvenient (especially because if you do it wrong, the error happens at the very end of ISE mapping, which took a few hours in my previous project...) so I'm glad to learn that I won't have to lose my time doing this anymore.

0 Kudos
Scholar samcossais
Scholar
13,518 Views
Registered: ‎12-07-2009

Re: The constraint about IDELAYCTRL and IDELAYE2 in source synchronous interface.

panaj >

 

It seems that the ISERDES outputs are not used. This is usually caused because the circuit ahead is not working properly (for example it's is stuck to a constant output value, thus the synthesis tool removes it). I advice you to do some simulation and check the behavior.

0 Kudos