cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Explorer
Explorer
11,848 Views
Registered: ‎10-27-2013

set_output_delay for source synchronous

Jump to solution

i am feeding data from FPGA to a DAC (source synchronous )...The DAC is configured for word mode(Page 30) ... in order to meet the input timing requirements for DAC (as in page 31) .... I have applied the following constraints

create_generated_clock -name clk_2x_adc_clk -source [get_pins adcdac/ODDR_inst/C] -combinational  [get_pins adcdac/ODDR_inst/Q]
set_output_delay -clock [get_clocks clk_2x_adc_clk] -min -1.24 [get_ports {dac_data[*]}] -clock_fall
set_output_delay -clock [get_clocks clk_2x_adc_clk] -max 0.86 [get_ports {dac_data[*]}] -clock_fall
set_output_delay -clock [get_clocks clk_2x_adc_clk] -min -1.05 [get_ports dac_frame] -clock_fall
set_output_delay -clock [get_clocks clk_2x_adc_clk] -max -0.04 [get_ports dac_frame] -clock_fall

The signals under consideration are dac_dci, dac_data ,dac_frame
clk_2x_adc_clk = 184 Mhz

after applying observe setup time violations on dac_data ..... I would like to verify applied constraints is it the right way??....

clk_structure.jpg
0 Kudos
1 Solution

Accepted Solutions
Highlighted
Guide
Guide
19,099 Views
Registered: ‎01-23-2009

There is clearly something wrong with the path analysis. The timing report should (as @rakeshm55 says) have a destination clock delay calculation that starts at the clock input, goes through the MMCM, the ODDR and the OBUF to become the generated clock at the output port. This is missing, and I don't know why.

 

This kind of clock forwarding and constraints is very common - it is even in the Vivado example design "wave_gen":

 

clk_fwd_path.gif

Using very similar constraints

create_generated_clock -name spi_clk -source [get_pins dac_spi_i0/out_ddr_flop_spi_clk_i0/ODDR_inst/C] -divide_by 1 -invert [get_ports spi_clk_pin]
set_output_delay -clock [get_clocks spi_clk] -max  1 [get_ports {spi_mosi_pin dac_cs_n_pin dac_clr_n_pin}]
set_output_delay -clock [get_clocks spi_clk] -min -1 [get_ports {spi_mosi_pin dac_cs_n_pin dac_clr_n_pin}]

Here, you can clearly see all the elements on the destination clock path...

 

So, we need to understand why this path is being analyzed incorrectly. There are a couple of possibilities:

  - there is something in the code that is preventing the proper analysis (like the clock ODDR not being routed to the pin, or the clock or output ODDR not being driven by the correct clock, ...)

  - there is some constraint other than the constraints shown that are messing up the timing analysis

    - another create_clock on the output port, or a different set_output_delay on the output port - possibly coming from another XDC file

  - there is a bug in the tool

 

I don't know what version of the tool you are using... I have seen the correct behavior in every version of Vivado since a long time ago, at least for the constraints above. One obvious difference is the -clock_fall - it is correct, but maybe this is what is messing up the tool. You could get around it by changing the create_clock to use the -invert like used in the wave_gen example, and removing the -clock_fall. You could do this in spite of the fact that your clock is not, in fact, inverting (in wave_gen, the D1 of the ODDR is connected to 0, and the D2 to 1, which actually does make it inverting) - the tool will just take your word for it.

 

You could also try a different version of Vivado, but I would be surprised if that changes anything...

 

Avrum

View solution in original post

0 Kudos
11 Replies
Highlighted
Xilinx Employee
Xilinx Employee
11,837 Views
Registered: ‎08-01-2008
check this ARs
https://www.xilinx.com/support/answers/63222.html
Thanks and Regards
Balkrishan
--------------------------------------------------------------------------------------------
Please mark the post as an answer "Accept as solution" in case it helped resolve your query.
Give kudos in case a post in case it guided to the solution.
0 Kudos
Highlighted
Guide
Guide
11,827 Views
Registered: ‎01-23-2009

after applying observe setup time violations on dac_data

 

Do you mean that VIvado is reporting that it doesn't meet these constraints, or that your board doesn't function? I will assume the former - in which case, you should really post the failing path report...

 

The constraints you use look correct. In this case, at 184MHz with these setup/hold requirements, the interface should be relatively easy; 184MHz is a 5.4ns bit time. Your architecture takes the simple approach of using 1/2 the bit period for setup and one half for hold then you get 2.7ns for each, which should be more than enough to satisfy the 0.86ns setup and 1.24ns of hold required.

 

So, the only way we can help is to see the failing path reports - ideally show us both the setup and hold timing reports.

 

Avrum

Highlighted
Explorer
Explorer
11,797 Views
Registered: ‎10-27-2013

Hi,

At the onset I have reedited the constraints to

 

create_generated_clock -name dac_clk -source [get_pins adcdac/ODDR_inst/C] -combinational  [get_ports dac_dci]
set_output_delay -clock [get_clocks dac_clk] -min -1.24 [get_ports {dac_data[*]}] -clock_fall
set_output_delay -clock [get_clocks dac_clk] -max 0.86 [get_ports {dac_data[*]}] -clock_fall
set_output_delay -clock [get_clocks dac_clk] -min -1.05 [get_ports dac_frame] -clock_fall
set_output_delay -clock [get_clocks dac_clk] -max -0.04 [get_ports dac_frame] -clock_fall

 

Have changed from [get_pins adcdac/ODDR_inst/Q] to [get_ports dac_dci] ..... dac_dci actual port name is supposed to the the generated clock .....

 

Setup error obtained is attached along with hold for the same path

Setup_error.jpg
Hold_report.jpg
0 Kudos
Highlighted
Explorer
Explorer
11,790 Views
Registered: ‎10-27-2013

Why is the ODDR delay and OBUF for dac_dci/dac_clk  not considered in the destination clock path??

0 Kudos
Highlighted
Moderator
Moderator
11,772 Views
Registered: ‎01-16-2013
Hi Rakesh,

The path you have highlighted about is OUTPUT path from FPGA.
Source is FF and destination is Port i.e. output.
So there is no clock connection to the port and hence the information is not available in destination clock path.

In general period analysis both source and destination have clock connections and that's why those value are reported in timing analysis. But in case of set_output_delay only source values and requirements are available.

Thanks,
Yash
0 Kudos
Highlighted
Explorer
Explorer
11,770 Views
Registered: ‎10-27-2013

My understanding is that once we get clk to ODDR and output data to IOB register the applied set_out_delay will not have any impact on meeting the timings...

It generates  an error if the set up time and hold time in the constraint is not met...

In  my case tool throws up an error which I feel is becoz tool has not considered  the ODDR delay/OBUF delay for destination clock....This would be due to wrong application set_out_delay ....

I would like to know the mistake I am making......

0 Kudos
Highlighted
Professor
Professor
11,755 Views
Registered: ‎08-14-2007

It looks as if the timing is relative to the wrong clock edge.  Are you sure that your output clock has its falling edge in the middle of the output data period?  i.e. it should match the internal clock if your data is clocked out on the rising edge.  The ODDR D1 input should be '1' and the ODDR D2 input should be '0'.

-- Gabor
0 Kudos
Highlighted
Guide
Guide
19,100 Views
Registered: ‎01-23-2009

There is clearly something wrong with the path analysis. The timing report should (as @rakeshm55 says) have a destination clock delay calculation that starts at the clock input, goes through the MMCM, the ODDR and the OBUF to become the generated clock at the output port. This is missing, and I don't know why.

 

This kind of clock forwarding and constraints is very common - it is even in the Vivado example design "wave_gen":

 

clk_fwd_path.gif

Using very similar constraints

create_generated_clock -name spi_clk -source [get_pins dac_spi_i0/out_ddr_flop_spi_clk_i0/ODDR_inst/C] -divide_by 1 -invert [get_ports spi_clk_pin]
set_output_delay -clock [get_clocks spi_clk] -max  1 [get_ports {spi_mosi_pin dac_cs_n_pin dac_clr_n_pin}]
set_output_delay -clock [get_clocks spi_clk] -min -1 [get_ports {spi_mosi_pin dac_cs_n_pin dac_clr_n_pin}]

Here, you can clearly see all the elements on the destination clock path...

 

So, we need to understand why this path is being analyzed incorrectly. There are a couple of possibilities:

  - there is something in the code that is preventing the proper analysis (like the clock ODDR not being routed to the pin, or the clock or output ODDR not being driven by the correct clock, ...)

  - there is some constraint other than the constraints shown that are messing up the timing analysis

    - another create_clock on the output port, or a different set_output_delay on the output port - possibly coming from another XDC file

  - there is a bug in the tool

 

I don't know what version of the tool you are using... I have seen the correct behavior in every version of Vivado since a long time ago, at least for the constraints above. One obvious difference is the -clock_fall - it is correct, but maybe this is what is messing up the tool. You could get around it by changing the create_clock to use the -invert like used in the wave_gen example, and removing the -clock_fall. You could do this in spite of the fact that your clock is not, in fact, inverting (in wave_gen, the D1 of the ODDR is connected to 0, and the D2 to 1, which actually does make it inverting) - the tool will just take your word for it.

 

You could also try a different version of Vivado, but I would be surprised if that changes anything...

 

Avrum

View solution in original post

0 Kudos
Highlighted
Explorer
Explorer
11,701 Views
Registered: ‎10-27-2013

Thank u Avrum

 

I have changed my create_generated_clock to as suggested

 

create_generated_clock -name dac_clk -source [get_pins adcdac/ODDR_inst/C] -combinational [get_ports dac_dci]

To

create_generated_clock -name dac_clk -source [get_pins adcdac/ODDR_inst/C] -multiply_by 1 [get_ports dac_dci]

set_output_delay -clock [get_clocks dac_clk] -clock_fall -min -1.240 [get_ports {dac_data[*]}]
set_output_delay -clock [get_clocks dac_clk] -clock_fall -max 0.860 [get_ports {dac_data[*]}]
set_output_delay -clock [get_clocks dac_clk] -clock_fall -min -1.050 [get_ports dac_frame]
set_output_delay -clock [get_clocks dac_clk] -clock_fall -max -0.040 [get_ports dac_frame]

Now the implementation meets timing for output constraint.....

 

 

Setup_time.jpg
0 Kudos
Highlighted
Guide
Guide
8,388 Views
Registered: ‎01-23-2009

This is a tool bug - the -combinational should be identical to the -divide_by 1 or -multiply_by 1.

 

I have reproduced it with the Xilinx example design in 2016.3 and will submit it as a bug.

 

Avrum

Highlighted
Guide
Guide
8,225 Views
Registered: ‎01-23-2009

So, it turns out, that this is the correct behavior...

 

The create_generated_clock -combinational is NOT a synonym for -divide_by 1 or -multiply_by 1. The -combinational flag was introduced by Synopsys "later" in the development of the SDC, and instructs the tool to only consider propagation paths from the source clock to the generated clock through combinational logic - i.e. the propagation will not go through a clocked (or sequential) cell.

 

So, in this case (and many others), where we are trying to propagate the generated clock through an ODDR (which is a sequential cell), the -divide_by 1 or -multiply_by 1 correctly propagate through the ODDR. However, the -combinational is not allowed to propagate through a sequential cell. Since this is the only path that connects the source clock to the generated clock, and it is not considered when using the -combinational flag, the generated clock is not valid; if you do a check_timing command, it will report that the generated clock has no source clock.

 

Since the generated clock has no source clock, it cannot perform the clock propagation from the source clock, which is why we don't see any clock propagation in the Destination Clock Delay.

 

So, this is not a bug (I apologize to Xilinx) - this is the expected and correct behavior.

 

However, (and as a summary) NEVER USE create_generated_clock -combinational command (unless you REALLY REALLY know what you are doing and need its specific behavior - and by the way, I never have...).

 

Avrum