cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
304 Views
Registered: ‎01-16-2019

Timing problem(Hold) in DDR LVDS interface (IBUFDS==>ISERDESE2)

Jump to solution

Hi all,

the schematic of my 16 bits LVDS interface is shown in below. The input signals are from a ADC in DDR mode(450MHz, 900ms/s).  I used IDELAYE2 in LOAD_VAR mode to make sure that BitCLK has the same phase as the DCLK.  All  ISERDESE2 work in SDR. Since every ISERDESE2 has only 8 bits,  I used two ISERDESE2  operating at different edges in the data path. The Bitslip is used for the alignment of the frame clock(DataCLK: 450/8 MHz).  However, I become timing problem of the paths marked with red after Synthesis.  Are there someone have an ideal about the reason? And what should I do?  Thanks a lot.Zeichnung1.png

 

set_property IOSTANDARD LVDS_25 [get_ports rx_in0_p]
set_property IOSTANDARD LVDS_25 [get_ports rx_in0_n]
set_property IOSTANDARD LVDS_25 [get_ports rx_in1_p]
set_property IOSTANDARD LVDS_25 [get_ports rx_in1_n]
set_property IOSTANDARD LVDS_25 [get_ports rx_inCLK_p]
set_property IOSTANDARD LVDS_25 [get_ports rx_inCLK_n]
set_property IOSTANDARD LVDS_25 [get_ports rx_inFRCLK_p]
set_property IOSTANDARD LVDS_25 [get_ports rx_inFRCLK_n]
create_clock -period 2.222 -name rx_inCLK_p -waveform {0.000 1.111} [get_ports rx_inCLK_p]
set_input_jitter rx_inCLK_p 0.080
set_input_delay -clock [get_clocks rx_inCLK_p] -clock_fall -min -add_delay 0.528 [get_ports rx_inFRCLK_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -clock_fall -max -add_delay 0.572 [get_ports rx_inFRCLK_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -min -add_delay 0.528 [get_ports rx_inFRCLK_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -max -add_delay 0.572 [get_ports rx_inFRCLK_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -clock_fall -min -add_delay 0.528 [get_ports rx_in0_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -clock_fall -max -add_delay 0.572 [get_ports rx_in0_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -min -add_delay 0.528 [get_ports rx_in0_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -max -add_delay 0.572 [get_ports rx_in0_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -clock_fall -min -add_delay 0.528 [get_ports rx_in1_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -clock_fall -max -add_delay 0.572 [get_ports rx_in1_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -min -add_delay 0.528 [get_ports rx_in1_p]
set_input_delay -clock [get_clocks rx_inCLK_p] -max -add_delay 0.572 [get_ports rx_in1_p]

Unbenannfft.PNG

 

 

 

 

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Guide
Guide
192 Views
Registered: ‎01-23-2009

I am not following exactly what you are trying to do here, but...

This clearly looks like some kind of dynamic calibration mechanism - you have logic controlling the delay value of the IDELAY dynamically (any time you have things connected to the IDELAY dynamic control port (i.e. any time you have the IDELAY_TYPE set to something other than FIXED), you are doing some kind of dynamic changing of the IDELAY value. By definition, if you are dynamically changing an IDELAY value in the interface, it cannot be timed by static timing analysis (STA).

Therefore, setup and hold time violations are meaningless - they are being done using the configuration value of the IDELAY (which is probably 0). Furthermore, the whole (and only) reason to use a dynamic calibration mechanism is that the size of the data valid window is too small to capture statically - which is supported by your data

  • The valid data window (based on your clock and constraints) are 1.067ns wide (assuming your XDC constraints are correct - the variation on the set_input_delay is really small - only 44ps - I know of very few devices that give the clock to data skew variation being this tight). But 1.067ns is significantly too small to be captured statically on any device family
  • The sum of your setup and hold slack is quite negative (-2.332) - at least based on the limited report we see. If this value is negative (again, assuming your constraints are correct), this means that there is no value of the IDELAY that can make both of these positive
    • That being said, this number seems really high - I would have expected it to be closer to -1.0 to -1.5...

So all this says that you cannot capture this statically, and you need dynamic calibration. If you use dynamic calibration, static timing is not useful (other than determining that you need dynamic calibration). The fact that they fail is expected, and doesn't tell you more than the fact that you need dynamic calibration.

Now, as to whether your interface will work or not, that is a far harder question to answer. I don't understand your dynamic calibration mechanism (using the IDELAY to "make sure that BitCLK has the same phase as DCLK") - and I am not sure I understand why you are using two ISERDES in SDR mode instead of one in DDR mode. Ultimately it is up to you to prove that your dynamic calibration mechanism has the required characteristics (in terms of adapting to delay using the IDELAY) to be able to "find" the center of the data eye and be sure that there is enough width for reliable capture.

Avrum

View solution in original post

0 Kudos
2 Replies
Highlighted
Voyager
Voyager
219 Views
Registered: ‎08-02-2019

Hi @yuexia ,

I have a similar, working design with you.

I'm getting DDR clocked, 8 LVDS line from an ADC.

I tried first to deserialize data with ISERDES, but later I found it more complex. That's why I made it without ISERDES.

To handle DDR clock I used clock wizard and I generated double rated clock with same phase shift.

Trick is that: I used IDDR primitives to handle double edge clocked data. Because we can use double edge clocked registers only with IDDR primitives, later on this kind of registers is not applicable.

By this way, I got 2 data as negative and positive edges from DDR clocked data.

I sampled this data with new generated 2-times faster clock and then I converted this serial data into ADC clock domain.

 

LVDS_2_SingleEnded.png

 

I share with you some code parts:

1-) Get 1-bit output for positive edge of clock and 1-bit output for negative edge of clock  

   IDDR #(
      .DDR_CLK_EDGE("OPPOSITE_EDGE") // "OPPOSITE_EDGE", "SAME_EDGE" 
                                      //    or "SAME_EDGE_PIPELINED"       
   ) IDDR_ADC_OUT1A (
      .Q1(ADC_OUT_1A_POS), // 1-bit output for positive edge of clock
      .Q2(ADC_OUT_1A_NEG), // 1-bit output for negative edge of clock
      .C(DCO_90_DEGREE),   // 1-bit clock input
      .CE(1'b1), // 1-bit clock enable input
      .D(ADC_OUT_1A),   // 1-bit DDR data input
      .R(~RST_IN),   // 1-bit reset
      .S(1'b0)    // 1-bit set
   );

2-) Convert LVDS to Single Ended

   IBUFDS #(
          .DIFF_TERM("FALSE"),       // Differential Termination
          .IBUF_LOW_PWR("TRUE"),     // Low power="TRUE", Highest performance="FALSE" 
          .IOSTANDARD("DEFAULT")     // Specify the input I/O standard
       ) IBUFDS_inst2 (
          .O(ADC_FRAME_CLOCK),  // Buffer output
          .I(ADC_FRAME_CLOCK_P),  // Diff_p buffer input (connect directly to top-level port)
          .IB(ADC_FRAME_CLOCK_N) // Diff_n buffer input (connect directly to top-level port)
       );

3-) Deserialize Serial input

   // shift register
   always @ (posedge DCO_2x_90_DEGREE or negedge RST_IN) begin
    if (!RST_IN) begin
            adcdata_1a <= 12'h0;
            adcdata_1a_out_reg <= 12'h0;
        end
        else begin
            if (start == 1) begin    // reset shift register data
                // get current 12 bit data, and init it!!!
                adcdata_1a_out_reg <= adcdata_1a;
            end           
            
               if (start == 1) begin    // reset shift register data
                    // get current 12 bit data, and init it!!!
                    adcdata_1a <= {11'h0, odd ? ADC_OUT_1A_POS : ADC_OUT_1A_NEG};
                end
                else begin
                    adcdata_1a <= {adcdata_1a[10:0], odd ? ADC_OUT_1A_POS : ADC_OUT_1A_NEG};
                end 
        end
   end
 
 

 

I'm sure, it will solve your problem.

 

Regards

Saban

 

<--- If reply is helpful, please feel free to give Kudos, and close if it answers your question --->
0 Kudos
Highlighted
Guide
Guide
193 Views
Registered: ‎01-23-2009

I am not following exactly what you are trying to do here, but...

This clearly looks like some kind of dynamic calibration mechanism - you have logic controlling the delay value of the IDELAY dynamically (any time you have things connected to the IDELAY dynamic control port (i.e. any time you have the IDELAY_TYPE set to something other than FIXED), you are doing some kind of dynamic changing of the IDELAY value. By definition, if you are dynamically changing an IDELAY value in the interface, it cannot be timed by static timing analysis (STA).

Therefore, setup and hold time violations are meaningless - they are being done using the configuration value of the IDELAY (which is probably 0). Furthermore, the whole (and only) reason to use a dynamic calibration mechanism is that the size of the data valid window is too small to capture statically - which is supported by your data

  • The valid data window (based on your clock and constraints) are 1.067ns wide (assuming your XDC constraints are correct - the variation on the set_input_delay is really small - only 44ps - I know of very few devices that give the clock to data skew variation being this tight). But 1.067ns is significantly too small to be captured statically on any device family
  • The sum of your setup and hold slack is quite negative (-2.332) - at least based on the limited report we see. If this value is negative (again, assuming your constraints are correct), this means that there is no value of the IDELAY that can make both of these positive
    • That being said, this number seems really high - I would have expected it to be closer to -1.0 to -1.5...

So all this says that you cannot capture this statically, and you need dynamic calibration. If you use dynamic calibration, static timing is not useful (other than determining that you need dynamic calibration). The fact that they fail is expected, and doesn't tell you more than the fact that you need dynamic calibration.

Now, as to whether your interface will work or not, that is a far harder question to answer. I don't understand your dynamic calibration mechanism (using the IDELAY to "make sure that BitCLK has the same phase as DCLK") - and I am not sure I understand why you are using two ISERDES in SDR mode instead of one in DDR mode. Ultimately it is up to you to prove that your dynamic calibration mechanism has the required characteristics (in terms of adapting to delay using the IDELAY) to be able to "find" the center of the data eye and be sure that there is enough width for reliable capture.

Avrum

View solution in original post

0 Kudos