03-25-2020 02:39 PM
Port 'X' is an FPGA clock pin.
It's defined using a "create_clock" XDC command.
I have a requirement to drive this clock to an input port 'Y' like this:
Y <= X ;
I want the delay between X and Y to be as little as possible.
What constraint do you advice to use ?
03-25-2020 05:33 PM - edited 03-25-2020 06:27 PM
If you ARE NOT going to use the clock inside the FPGA, then you can route the clock in through a pin and then directly out through an adjacent pin. You could then put set_input_delay and set_output_delay on the two pins with values that just allow this in-out path for the clock to pass timing analysis – which will keep routing short inside the FPGA. However, I guess this is the silly solution since you probably are going to use the clock inside the FPGA.
If you ARE going to use the clock inside the FPGA, then you’ll need to route the clock into the clock tree and then back out of the tree to reach an FPGA pin that carries the clock out of the FPGA. I suspect the shortest delay results from using the routing, “pin > IBUF > BUFIO/BUFR > ODDR > pin”, and choosing pins that are very near the physical location of the BUFIO/BUFR in the FPGA.
However, the coolest solution is to use the Zero Delay Buffer architecture described by Figure 3-11 in UG572. As the name implies, this will give you a routing delay through the FPGA of zero! This magic is made possible by the MMCM feedback loop. Specifically, in Figure 3-11, your clock comes in from a pin on the top-left and is routed as “input-pin1 > IBUFG1 > MMCM.CLKIN1 > MMCM.CLKOUT0 > BUFG1 > OBUF1 > output-pin”. Then, you put all the same stuff (input-pin2, IBUFG2, BUFG2, OBUF2, output-pin2) in the MMCM feedback loop from MMCM.CLKFBOUT to MMCM.CLKFBIN. -and what happens is that the MMCM automatically adjusts the phase of the clock at input-pin2 to match the phase of the clock at input-pin1. That is, it appears that the clock has gone through the FPGA and out again without suffering any phase-shift (ie. zero delay). Magic!
P.S. In Figure 3-11, I think it is wrong for BUFG to directly drive OBUF. Instead, BUFG should drive an ODDR - as a means of sending the clock out of the FPGA.
03-26-2020 10:33 AM - edited 03-26-2020 10:37 AM
For the “input-pin > IBUF > BUFIO/BUFR > ODDR > output-pin” solution, you should write create_clock and set_input_jitter constraints and place them in the Vivado project .xdc file. These constraints would look something like the following.
create_clock -period 10.000 [get_ports <input-pin>] set_input_jitter [get_clocks -of_objects [get_ports <input-pin>]] 0.1
For the Zero Delay Buffer solution, both the create_clock and the set_input_jitter constraint will be automatically written for you by the Clocking Wizard and placed in .xdc files associated with the Clocking Wizard IP.
Finally, here is a variation to the Zero Delay Buffer solution. This variation could be used if you are unable to send the MMCM feedback loop of the Zero Delay Buffer outside the FPGA. This variation is to simply use the normal feed loop architecture as shown below by Figure 3-9 from UG572(v1.9).
Use an oscilloscope to look at the phase of the source-clock and the looped-back-clock (ie. the clock that you “looped back to it source” – as you say). Then, use the Clocking Wizard to manually adjust the phase of MMCM.CLKOUT0 until (on the oscilloscope) both the source-clock and the looped-back-clock have the same phase. Since the source-clock and the looped-back-clock now have the same phase it will appear that the looped-back-clock has zero-delay compared to the source clock.
The disadvantage of this Zero Delay Buffer variation is that the phase between the source-clock and the looped-back-clock will drift as delay through some components (eg. OBUF) changes with PVT. This phase drift will not happen with the actual Zero Delay Buffer solution since this drift is automatically compensated for (in real-time) by the feedback loop action.