Problem Description

I am trying to figure out the "correct" way to constrain (in .xdc format - this is in Vivado) a forwarded source-synchronous clock that is generated (by division) from the system clock and center-sampled at the receiving module. The situation is as follows:

We have an ADC that our FPGA is sending data to. The interface to the ADC is source-synchronous: we forward a clock along with the data. It is also center-sampled in that we generate the data (at the FPGA) on the falling edge of the forwarded clock, and capture the data on the rising edge of the forwarded clock. To add to the complexity, this forwarded clock is generated by dividing the system clock. We want to be able to set the output delay of this forwarded clock/data so we can specify the setup and hold times of the ADC. The issue is that we are unsure how to specify the multicycle constraints such that Vivado figures out the correct launch and capture edge.

In real life, our forwarded clock is only divided by two from the system clock, but we want to know how to do this in the most general case, and so we'll set the division rate to eight for the sake of example.


Waveform showing clk, generated (/8) clock, and data. Data is launched on falling edge of generated clock, and captured on rising edge of generated clock:

Waveform showing clk, generated (/8) clock, and data. Data is launched on falling edge of generated clock, and captured on rising edge of generated clock.

The big issue is figuring out the correct multicycle constraints. There seems to be no intuitive way to specify that data is launched on the falling edge of the generated clock and captured by the rising edge. The main issue is that the data is actually generated by the system clock - an FSM (that creates the generated clock) ensures that new data is only launched on edges where the generated clock falls. The "launch clock" is thus the system clock, while the "capture clock" is SCKO.

Below is a drawing of the system; SDO and SCKO are outputs of the FPGA:

A drawing of the system: SDO and SCKO are outputs of the FPGA.

Attempted Solutions

We were able to quite easily solve the question of multicycling with regards to setup; in this case we set:

set_multicycle_path 4 -setup -from [get_clocks sys_clk] -to [get_clocks SCKO] -start

This makes sense - our capture edge is 4 cycles from our launch edge, so we push the setup time forward hold cycles. These 4 cycles are in terms of the system clock, so we make sure to use the -start flag so that the setup multiplier is in terms of the launch clock.

The question is: what should we do for the hold multicycle path, and why?


For research, we can consult Vivado's UG903: Using Constraints. Of particular use is the section on multicycle paths - specifically the "Multicycles Between FAST-to-SLOW Clocks" section on page 117. But this only tells us how to handle an extended datapath - we don't understand how to apply this to our project, where we need to make sure Vivado knows that data is only launched on the falling edge of SCKO (which is NOT the clock that generates it - sys_clk generates it, but only certain rising edges of sys_clk).

We've tried cycling through different hold multipliers, but we're not sure what the correct way of doing this is. For our "divide by 2" example, we found that setting a hold multiplier of 1 would work - the path report seemed to indicate something we could convince ourselves was the right answer (namely, it started the "source clock" at one period after the "launch clock" - this would correspond to the launch path starting at the falling edge of the forwarded clock and the capture path starting at the rising edge of the forwarded clock.

We've also looked at several parameters for our generated clock, output delay, and set multicycle path constraints. We've looked at the "-clock_fall" flag, but this tells the tool that we want to capture on the falling edge (when we actually need to tell it to launch on the falling edge, but of a different clock). We've also looked at "-rise" and "-fall", but haven't been able to really figure out what those do or what effect they have.


In short: what is the correct multi-cycle constraint to put here, and why?

  • \$\begingroup\$ The solution for divide-by-eight is completely different from the solution for divide-by-two, because the clock domain crossing for divide-by-eight is a lot simpler. For divide-by-two, I'd just use a dual clock FIFO and run a quick calibration on startup to move the sampling clock phase to the center. \$\endgroup\$ Aug 28, 2022 at 11:43

1 Answer 1


We want to be able to set the output delay of this forwarded clock/data so we can specify the setup and hold times of the ADC.

From the above explanation, You need generating delay on the data and clock lines, I have two solutions for this problem.

1) using Input Delay Resources(IDELAY) or ODELAY https://www.xilinx.com/support/documentation/user_guides/ug471_7Series_SelectIO.pdf

in high-speed design, some delays in PCB compensated with delay buffers.(these are have some tab of delays)

2) the second solution is synchronizing FPGA clock with feedback of ADC clock(it generate in PLL) I think, it's not easy and helpful for your case!


I think in FPGA you should first consider which circuit you need, then tell the compiler to generate that. the Xilinx said "logical path that requires more than one clock cycle for the data to stabilize at the endpoint. If the control circuitry of the path start point and end point allows it, Xilinx recommends that you use the Multicycle Path".

Now in your example where you have two signal from FPGA side to ADC, ( you don't say low-power requirement, the multi-cycle help this goal) the Xilinx said "data to stabilize" because this may generate metastability. with clock and data pin from FPGA to ADC then the delay between clock edge and stable data has two cases, the first bigger than one cycle of the clock or less than, for the latter case IDELAY is ok but if you have bigger than one cycle delay( where you may concern about it) you compensate your delay, by setting a data in last clock cycle or two clock or higher, then the sub-clock delay compensate with(IDELAY).

I think your case does not need "set_multicycle_path". If you want low power then you may concern about "Multicycles in Single Clock Domain". If you have a pin receives a signal from ADC side, when the ADC not stable less than clock cycle you should try "Multicycles in Single Clock Domain" for metastability reason.

  • \$\begingroup\$ if your problem is not the delay, a diagram of system and direction of the signal may help for better understanding of the problem. \$\endgroup\$
    – M KS
    Nov 9, 2018 at 20:31
  • \$\begingroup\$ That's not really the issue, sorry. My issue lies with what .xdc command I should write to properly constrain it, not the structure of the system itself. I'll add a diagram of the system to the original post. \$\endgroup\$
    – YSl
    Nov 9, 2018 at 20:37
  • \$\begingroup\$ @YSl, May I ask you, why you apply this constrain? ( I think a low-power design and improve safety for instance), What are you waiting for? (in circuit) now, I think hold is not important, \$\endgroup\$
    – M KS
    Nov 9, 2018 at 22:33
  • \$\begingroup\$ @YSl Why you don't include input pin from ADC, that is related to set_multicycle_path, not the out pin you just senddata on it! If you tell me, what you expect to add to the original circuit, I can explain the timing. \$\endgroup\$
    – M KS
    Nov 10, 2018 at 8:00
  • \$\begingroup\$ We're including this constraint because we want to make sure our output path meets the setup and hold times (with trace delays) of the ADC. I'm not sure what you mean about the input pin from the ADC - the only relevance that has to the FPGA constraints is specifying what the output delay numbers are. We want to understand how to do multicycle constraints better in general, which is why this question asks about a -divide_by 8 path instead of the real -divide_by 2 path that we have. \$\endgroup\$
    – YSl
    Nov 12, 2018 at 19:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.