Showing results for 
Show  only  | Search instead for 
Did you mean: 
Registered: ‎11-15-2018

Use the center-aligned to capture the edge-alinged input DDR


I'm designing the constraint file for a high-speed ADC operating up to 500MSPS with the DDR output data-format, shown as follows. And the skew is +-70ps. And the FPGA is Kintex-7


 At the moment, I set the ADC work at 250MSPS with DDR mode. Let's say the data clock from ADC is adc_clk. I would like to add 1 ns delay to the adc_clk via the IDELAY to capture the data(Same as 90-degree phase shift) so that the clock edge should align to the center of the data theoretically. According to the post I use the cheating way to constrain the timing, and the adc_clk and data path are shown as follows:

adc_clk -> IBUFDS -> IBUFR  -> IDELAY -> IDDR

data -> IBUFDS -> IDELAY -> IDDR

create_clock -period 4 -name virt_clk -waveform {0.00 2.00}
set_multicycle_path 0 -from [get_clocks virt_clk] -to [get_clocks adc0_clk]
set_false_path -setup -rise_from [get_clocks virt_clk] -fall_to [get_clocks adc0_clk]
set_false_path -setup -fall_from [get_clocks virt_clk] -rise_to [get_clocks adc0_clk]

set_multicycle_path -1 -hold -from [get_clocks virt_clk] -to [get_clocks adc0_clk]
set_false_path -hold -rise_from [get_clocks virt_clk] -rise_to [get_clocks adc0_clk]
set_false_path -hold -fall_from [get_clocks virt_clk] -fall_to [get_clocks adc0_clk]

set input_clock         virt_clk;      # Name of input clock
set skew_bre            1.93;             # Data invalid before the rising clock edge
set skew_are            2.07;             # Data invalid after the rising clock edge
set skew_bfe            1.93;             # Data invalid before the falling clock edge
set skew_afe            2.07;             # Data invalid after the falling clock edge
set input_ports         adc0_din_n[*];     # List of input ports

# Input Delay Constraint
set_input_delay -clock $input_clock -max $skew_are  [get_ports $input_ports];
set_input_delay -clock $input_clock -min -$skew_bre [get_ports $input_ports];
set_input_delay -clock $input_clock -max $skew_afe  [get_ports $input_ports] -clock_fall -add_delay;
set_input_delay -clock $input_clock -min -$skew_bfe [get_ports $input_ports] -clock_fall -add_delay;

My questions are:

1. After the implementation and check the timing, it is found that the delay on the adc_clk path is much larger, which is caused by IBUFDS, IBUFR, and the net, so decrease the delay for adc_clk via the IDELAY.  My understanding is correct?

2. For the post, how to generate or define the delay clock? In my case, I just used the IDELAY to delay the adc_clk, which could disrupt the cheating? In the timing report, Vivado analyzed the relationship between virt_clk and the delayed clock. shown as follows. How to fix these timing issues?


3. If setting the ADC work at 500MSPS, it is possible to capture the data statically since the valid data window is only 1ns for DDR? I remembered the valid data window should be more than 800ps in one post written by avrumn.




0 Kudos
2 Replies
Registered: ‎01-23-2009

So (at a quick glance) it looks like you have mixed the "correct" and "cheating" way together. If you are going to use the "correct" way (with the set_multicycle_path and the appropriate set_false_path commands, which all look correct), then you should specify your constraints "naturally" - set all 4 skew_??e to 0.070ns (the actual skew between the clock edges and the data as specified by your data sheet).

If this is a 500Msps interface (250MHz DDR) then the bit period is 2.0ns. You lose 0.070ns to skew on each side, making the valid window 2.0-2*0.07=1.86ns. With ChipSync clocking on a Kintex-7, this should be doable.

Once you have the constraints correct, we can look at the best way to do this. It turns out that you often get better timing results from having the IDELAY on the data only (not on both clock and data). Since the native setup/hold window (Tpscs/Tphcs) is after the clock edge, this is usually what you want. If not, then you can look at other options, which would entail either delaying the clock (not the data), or trying to push the data forward to the next clock edge, which will require removing the set_multicycle_path command (and associated set_false_path commands).


Tags (2)
0 Kudos
Registered: ‎11-15-2018

Hi @avrumw 

Many thanks for your reply.

For the ADC DDR output, I forgot one thing that the data lanes will be half of the SDR in DDR mode, so the adc_clk is still 500MHz. Under such a circumstance, it is possible to capture the data statically? According to the kintex-7(-2 speed) spec, TODCK/TOCKD is 0.5/-0.13, which means the valid window is 0.63ns. In my case, the valid data window is 1 - 2*0.07 = 0.86. Theoretically, it seems that the valid data window is enough, but I'm not sure about the practical. What do you think?

For the constraint, the skew parameters have been changed, following the correct way. What I have done is delaying the data path alone to meet adc_clk setup and hold time(intro-clock path), but finally, Vivado reports the setup time issue between virt_clk and adc_clk(inter-clock path). From this inter-clock path, it can be found the idelay for data path is larger than expected. The idelay seems to be a paradox for these two paths. How to continue next?


As you mention that push the data to the next clock edge, it is true to use the idelay to add more delay to implement this?  




0 Kudos