cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Observer
Observer
692 Views
Registered: ‎03-06-2020

Hold Time Violation Help

Jump to solution

Hello, I have been trying to create a microblaze server referencing the design from XAPP1026 (block diagram attached below) using the HTG-940 development board with XCVU13P FPGA. After going through the flow I ended up with a hold time violation after implementation. I tried physical optimization runs with explore directives but the hold time violation still persists. I am using Vivado 2019.2. What should I do in order to meet timing?

 

Thanks, 

 

 

 

 

 

 

 

Constraints:

 

set_property PACKAGE_PIN P15 [get_ports uart_rtl_0_rxd]
set_property PACKAGE_PIN R15 [get_ports uart_rtl_0_txd]
set_property PACKAGE_PIN AJ34 [get_ports reset]

set_property PACKAGE_PIN A18 [get_ports mdio_rtl_0_mdc]
set_property PACKAGE_PIN G19 [get_ports mdio_rtl_0_mdio_io]

 


set_property PACKAGE_PIN D21 [get_ports {gmii_rtl_0_rxd_o[1]}]
set_property PACKAGE_PIN E21 [get_ports {gmii_rtl_0_rxd_o[2]}]
set_property PACKAGE_PIN C21 [get_ports {gmii_rtl_0_rxd_o[3]}]
set_property PACKAGE_PIN D20 [get_ports {gmii_rtl_0_txd_o[0]}]
set_property PACKAGE_PIN A19 [get_ports {gmii_rtl_0_txd_o[1]}]
set_property PACKAGE_PIN B19 [get_ports {gmii_rtl_0_txd_o[2]}]

 

set_property PACKAGE_PIN E20 [get_ports {gmii_rtl_0_txd_o[3]}]

 

 

set_property PACKAGE_PIN B20 [get_ports gmii_rtl_0_gtx_clk]
set_property PACKAGE_PIN G20 [get_ports gmii_rtl_0_rx_clk]
set_property PACKAGE_PIN B21 [get_ports gmii_rtl_0_rx_dv]
set_property PACKAGE_PIN G21 [get_ports gmii_rtl_0_tx_en]

 

 

 


set_property PACKAGE_PIN BA34 [get_ports {clk_clk_p[0]}]

 

 


####################################################################################
# Constraints from file : 'bd_929b_eth_buf_0.xdc'
####################################################################################

current_instance intdesign1wrap/design_1_i/ddr4_0/inst
set_property LOC MMCM_X0Y2 [get_cells -hier -filter {NAME =~ */u_ddr4_infrastructure/gen_mmcme*.u_mmcme_adv_inst}]

 

####################################################################################
# Constraints from file : 'bd_929b_eth_buf_0.xdc'
####################################################################################


current_instance -quiet
set_property PACKAGE_PIN AW36 [get_ports {ddr4_rtl_0_adr[16]}]
set_property PACKAGE_PIN AY33 [get_ports {ddr4_rtl_0_adr[15]}]
set_property PACKAGE_PIN AW33 [get_ports {ddr4_rtl_0_adr[14]}]
set_property PACKAGE_PIN AV34 [get_ports {ddr4_rtl_0_adr[13]}]
set_property PACKAGE_PIN BD36 [get_ports {ddr4_rtl_0_adr[12]}]
set_property PACKAGE_PIN BF39 [get_ports {ddr4_rtl_0_adr[11]}]
set_property PACKAGE_PIN BA33 [get_ports {ddr4_rtl_0_adr[10]}]
set_property PACKAGE_PIN BE35 [get_ports {ddr4_rtl_0_adr[9]}]
set_property PACKAGE_PIN BD35 [get_ports {ddr4_rtl_0_adr[8]}]
set_property PACKAGE_PIN BD39 [get_ports {ddr4_rtl_0_adr[7]}]
set_property PACKAGE_PIN BC34 [get_ports {ddr4_rtl_0_adr[6]}]
set_property PACKAGE_PIN BC39 [get_ports {ddr4_rtl_0_adr[5]}]
set_property PACKAGE_PIN BF40 [get_ports {ddr4_rtl_0_adr[4]}]
set_property PACKAGE_PIN BD34 [get_ports {ddr4_rtl_0_adr[3]}]
set_property PACKAGE_PIN BE40 [get_ports {ddr4_rtl_0_adr[2]}]
set_property PACKAGE_PIN BB35 [get_ports {ddr4_rtl_0_adr[1]}]
set_property PACKAGE_PIN BD40 [get_ports {ddr4_rtl_0_adr[0]}]
set_property PACKAGE_PIN AY36 [get_ports {ddr4_rtl_0_ba[1]}]
set_property PACKAGE_PIN BA35 [get_ports {ddr4_rtl_0_ba[0]}]
set_property PACKAGE_PIN BE36 [get_ports {ddr4_rtl_0_bg[0]}]
set_property PACKAGE_PIN BF37 [get_ports {ddr4_rtl_0_bg[1]}]
set_property PACKAGE_PIN BB36 [get_ports {ddr4_rtl_0_ck_t[0]}]
set_property PACKAGE_PIN BE37 [get_ports {ddr4_rtl_0_cke[0]}]
set_property PACKAGE_PIN AY35 [get_ports {ddr4_rtl_0_cs_n[0]}]
set_property PACKAGE_PIN AH34 [get_ports {ddr4_rtl_0_dm_n[0]}]
set_property PACKAGE_PIN AG31 [get_ports {ddr4_rtl_0_dq[7]}]
set_property PACKAGE_PIN AG32 [get_ports {ddr4_rtl_0_dq[6]}]
set_property PACKAGE_PIN AF32 [get_ports {ddr4_rtl_0_dq[5]}]
set_property PACKAGE_PIN AF34 [get_ports {ddr4_rtl_0_dq[4]}]
set_property PACKAGE_PIN AJ33 [get_ports {ddr4_rtl_0_dq[3]}]
set_property PACKAGE_PIN AH33 [get_ports {ddr4_rtl_0_dq[2]}]
set_property PACKAGE_PIN AG34 [get_ports {ddr4_rtl_0_dq[1]}]
set_property PACKAGE_PIN AF33 [get_ports {ddr4_rtl_0_dq[0]}]
set_property PACKAGE_PIN AW35 [get_ports {ddr4_rtl_0_odt[0]}]
set_property PACKAGE_PIN BB38 [get_ports ddr4_rtl_0_act_n]
set_property PACKAGE_PIN BC38 [get_ports ddr4_rtl_0_reset_n]
set_property PACKAGE_PIN AH31 [get_ports {ddr4_rtl_0_dqs_t[0]}]

set_property IOSTANDARD LVCMOS18 [get_ports {gmii_rtl_0_rxd_o[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {gmii_rtl_0_rxd_o[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {gmii_rtl_0_rxd_o[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {gmii_rtl_0_rxd_o[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports mdio_rtl_0_mdc]
set_property IOSTANDARD LVCMOS18 [get_ports mdio_rtl_0_mdio_io]
set_property IOSTANDARD LVCMOS12 [get_ports reset]
set_property IOSTANDARD LVCMOS18 [get_ports uart_rtl_0_rxd]
set_property IOSTANDARD LVCMOS18 [get_ports uart_rtl_0_txd]
set_property IOSTANDARD LVCMOS18 [get_ports {gmii_rtl_0_txd_o[3]}]
set_property IOSTANDARD LVCMOS18 [get_ports {gmii_rtl_0_txd_o[2]}]
set_property IOSTANDARD LVCMOS18 [get_ports {gmii_rtl_0_txd_o[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {gmii_rtl_0_txd_o[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports gmii_rtl_0_gtx_clk]
set_property IOSTANDARD LVCMOS18 [get_ports gmii_rtl_0_rx_clk]
set_property IOSTANDARD LVCMOS18 [get_ports gmii_rtl_0_rx_dv]
set_property IOSTANDARD LVCMOS18 [get_ports gmii_rtl_0_tx_en]
set_property IOSTANDARD DIFF_SSTL12 [get_ports {clk_clk_n[0]}]
set_property IOSTANDARD DIFF_SSTL12 [get_ports {clk_clk_p[0]}]
create_clock -period 5.000 -name {clk_clk_p[0]} -waveform {0.000 2.500} [get_ports {clk_clk_p[0]}]
create_clock -period 5.000 -name intdesign1wrap/design_1_i/util_idelay_ctrl_0/inst/rdy -waveform {0.000 2.500} [get_pins intdesign1wrap/design_1_i/util_idelay_ctrl_0/inst/dlyctrl/RDY]

####################################################################################
# Constraints from file : 'bd_929b_eth_buf_0.xdc'
####################################################################################

set_property LOC BITSLICE_RX_TX_X0Y726 [get_cells {intdesign1wrap/design_1_i/axi_ethernet_0/U0/mac/U0/tri_mode_ethernet_mac_i/gmii_interface/rxdata_bus[0].delay_gmii_rxd}]
set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
connect_debug_port dbg_hub/clk [get_nets clk]

forum2.PNG
forum5.PNG
forum4.PNG
forum3.PNG
0 Kudos
1 Solution

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

First,

The constraints shown here are not consistent with the results you showed last time. The failing hold path had a set_input_delay -min of 0.6 as it does now, but the passing setup time had a set_input_delay -max of 6.0 in the previous results, whereas it is only 1.0 now.

As I mentioned, the 6.0 didn't look reasonable - it was way bigger than one would expect. That being said, the 1.0 is pretty small - specifying only a 0.4ns uncertainty window in the 8.0ns bit period.

That being said, though, "reasonable" isn't really important - the only real question is what is correct. This GMII interface is talking to an external PHY. The set_input_delay command that should be applied are derived only from the clock/data skew of the PHY and any board delay imbalance. These are "known" for you PHY and your board, and must be reflected in the values used for the set_input_delay; anything else is incorrect.

As for setting the IDELAY value, you can either set it in the RTL when the IDELAYE3 is instantiated - in the "generic map" you are showing in your previous screenshot, you would add

DELAY_FORMAT => "TIME",
DELAY_VALUE   => <value>

Alternatively (and especially if the IDELAY is instantiated by in an IP), you can set these properties in the top level XDC file

set_property DELAY_FORMAT TIME [get_cells intdesign1wrap/design_1_i/axi_ethernet_0/U0/mac/U0/tri_mode_ethernet_mac_i/gmii_interface/rxdata_bus[*].delay_gmii_rxd]
set_property DELAY_VALUE <value> [get_cells intdesign1wrap/design_1_i/axi_ethernet_0/U0/mac/U0/tri_mode_ethernet_mac_i/gmii_interface/rxdata_bus[*].delay_gmii_rxd]

Avrum

View solution in original post

8 Replies
Highlighted
Xilinx Employee
Xilinx Employee
640 Views
Registered: ‎05-14-2008

This is the input paths covered by set_input_delay constraint.

You need to cross-check both the setup time and hold time on the input paths to see if there is any space for the window to meet the requirement. 

You need to generate the datasheet report (report_datasheet or enable datasheet report in report_timing_summary) for analysis.

And also need to analyze the details of the paths (details of source clock path, data path and destination clock path) which are not shown in the images you provided.

This AR can be a reference for you to learn how to resolve input path timing:

https://www.xilinx.com/support/answers/45028.html

This is an AR for ISE tool. OFFSET IN is a constraint in ISE to setup requirement for input paths. In Vivado we use set_input_delay. But the methods to resolve input path timing are more or less the same between the two tools.

If you don't know how to analyze, please provide the whole text-format timing report with datasheet report enabled.

-vivian

-------------------------------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------------------------------
如果提供的信息能解决您的问题,请标记为“接受为解决方案”。
如果您认为帖子有帮助,请点击“奖励”。谢谢!
-------------------------------------------------------------------------------------------------
Highlighted
Observer
Observer
601 Views
Registered: ‎03-06-2020

Hi @viviany  Here is my timing report with datasheet.

0 Kudos
Highlighted
Guide
Guide
590 Views
Registered: ‎01-23-2009

It would have been helpful to see your timing constraints as well, but I was able to infer them from the timing reports...

It appears that the constraints are the equivalent of

create_clock -period 8 -name gmii_rtl_0_rx_clk [get_ports gmii_rtl_0_rx_clk]
set_input_delay -clock gmii_rtl_0_rx_clk  -min 0.6 [get_ports gmii_rtl_rxd_o[*]]
set_input_delay -clock gmii_rtl_0_rx_clk  -max 6.0 [get_ports gmii_rtl_rxd_o[*]]

In other words you are telling the tools that the PHY connected to this GMII interface, which is running at 125MHz SDR (8ns period) has a clock to valid time of anywhere between 0.6ns and 6.0ns. This is probably the WORST PHY EVER; GMII PHYs are usually clock forwarded, the rx_clk and rx_d (and rx_dv) are in a source synchronous timing relationship, and should normally be very tightly correlated; with only small differences in the min and max timing; I wouldn't have been surprised to see something like -min -0.6 and -max 0.6, for a 1.2ns unknown period within the 8ns bit period (hence a 6.8ns valid window within the 8ns bit period). However, your constraints have a 5.4ns unknown window (and hence a 4.4ns valid window) within the 8ns period. This is huge, and is most likely an error.

Given these constraints, the interface is only vaguely viable - there is technically positive margin between the setup and hold checks; setup check has +1.88ns of margin and the hold check has -1.77ns of margin. So, in theory, if you can increase the delay of the data by anywhere between 1.77ns and 1.88ns (ideally 1.825ns) then your interface should pass timing. I see that there is an IDELAYE3 on the data path, so increasing the delay of this by 1.825ns will make your interface pass.

But - as I mentioned before, this is almost certainly not the correct timing constraints... Where did these come from?

Avrum

Highlighted
Advisor
Advisor
578 Views
Registered: ‎02-12-2013

Source synchronous interfaces like this nearly always meet timing by design.  By that I mean there are DDR registers in the IO block that set the timing of the data and clock.

If that is the case the purpose of the set_input_delay constraint is to eliminate error messages due to missing io timing constraints.  The constraint has no effect on the design and does not affect implementation in any way.

Furthermore, the synopsis design constraints language (SDC = XDC) is not really very intuitive when it comes to io timing.  You can spend a lot of time tweaking these constraints and never really feel good about it.

Best wishes

----------------------------------------
DSP in hardware and software
-----------------------------------------
Highlighted
Guide
Guide
533 Views
Registered: ‎01-23-2009

@pedro_uno ,

Source synchronous interfaces like this nearly always meet timing by design.

I have to disagree. Just like other interfaces, source synchronous interfaces need to be designed, constrained, and timed properly. While source synchronous interfaces are usually easier to get to meet timing, they still need to go through these steps - the example here is a good one.

While the interface can meet timing, it can only do so with the proper amount of delay to ensure that the valid data window overlaps the required setup/hold window of the sampling mechanism. The only way to determine the required setup/hold window of the sampling mechanism, and hence what the proper amount of delay to program in the IDELAY is through static timing analysis. If you get the value of this IDELAY incorrect (as is currently done in this interface) then the interface will not work reliably - only by ensuring that you meet the setup and hold requirements (done by setting the proper IDELAY value) can you be sure that the interface will work.

The constraint has no effect on the design and does not affect implementation in any way.

This is true. In a properly designed I/O interface, all the resources are fixed; the clock buffers (and other clock resources) the IOBs and the IOB/DDR registers are all in fixed locations and use dedicated routing. As a result, the timing of these interfaces will not vary from run to run, and, consequently, the constraints will not alter the placement and routing of these resources.

By that I mean there are DDR registers in the IO block that set the timing of the data and clock.

The IOB/DDR registers (this happens to be an SDR interface, so is only using the IOB flip-flops in SDR mode), are nothing more than "regular" registers (SDR) or (at least logically) pairs of regular registers (DDR) that capture data from coming in from the IBUF. There is no built in mechanism that "sets the timing of the data and clock" - it is up to the user to design a proper clocking scheme for these registers and do any manipulation of the clock/data timing relationship using the tools available; either the phase shifting capability of the MMCM/PLL to move the clock into the "correct" sampling position, or the delay of the IDELAY to move the data so that the clock is in the middle of the data window. In fact, it is specifically because of this that you need to do proper static timing analysis; you need that data in order to determine the correct phase shift or IDELAY delay.

Only in the case of UltraScale/UltraScale+/Versal I/O in "native mode" using BISC is there some form of automatic calibration mechanism for edge aligned or center aligned source synchronous interfaces (and there is something simpler but vaguely similar in the Spartan-6, as well).

As for SDC/XDC being "not intuitive" for I/O timing, I will agree that it is a bit more complicated to wrap you head around the way SDC/XDC deal with external delays, but once you do, they do become at least somewhat intuitive. SDC/XDC has designed the set_input_delay and set_output_delay commands to provide the information about the external components that are required to "complete the static timing path" (since part of these paths are internal to the FPGA and part are external). Once the paths are "completed" with this additional data, the setup/hold checks done on these static timing paths are identical to those performed on purely internal static timing paths; there are no special rules associated with them.

Avrum

Highlighted
Observer
Observer
528 Views
Registered: ‎03-06-2020

Hi @avrumw ,

The timing constraints I think were automatically generated by vivado. After I synthesized my design, the only thing I did for constraints was assign the ports and pins since the last time I created a similar project on an Artix-7 it was able to meet timing. I am also not familiar with timing and using timing constraints. How would I set the delay for IDELAYE3? I went to edit-->find-->IDELAYE3 and went to the source which is shown below in pic. Is there another way like writing set_input_delay IDELAYE3? I also tried reducing the max delay albeit I should have used the values for 0.6 and -0.6 but it does not change the hold time violation. Also the timing report is different since I loaded up an older revision of the project. When I tried to edit the constraints it became read-only and I could not get it to revert so I just rebooted and tried again.

forum6.PNG
forum7.PNG
0 Kudos
Highlighted
Guide
Guide
477 Views
Registered: ‎01-23-2009

First,

The constraints shown here are not consistent with the results you showed last time. The failing hold path had a set_input_delay -min of 0.6 as it does now, but the passing setup time had a set_input_delay -max of 6.0 in the previous results, whereas it is only 1.0 now.

As I mentioned, the 6.0 didn't look reasonable - it was way bigger than one would expect. That being said, the 1.0 is pretty small - specifying only a 0.4ns uncertainty window in the 8.0ns bit period.

That being said, though, "reasonable" isn't really important - the only real question is what is correct. This GMII interface is talking to an external PHY. The set_input_delay command that should be applied are derived only from the clock/data skew of the PHY and any board delay imbalance. These are "known" for you PHY and your board, and must be reflected in the values used for the set_input_delay; anything else is incorrect.

As for setting the IDELAY value, you can either set it in the RTL when the IDELAYE3 is instantiated - in the "generic map" you are showing in your previous screenshot, you would add

DELAY_FORMAT => "TIME",
DELAY_VALUE   => <value>

Alternatively (and especially if the IDELAY is instantiated by in an IP), you can set these properties in the top level XDC file

set_property DELAY_FORMAT TIME [get_cells intdesign1wrap/design_1_i/axi_ethernet_0/U0/mac/U0/tri_mode_ethernet_mac_i/gmii_interface/rxdata_bus[*].delay_gmii_rxd]
set_property DELAY_VALUE <value> [get_cells intdesign1wrap/design_1_i/axi_ethernet_0/U0/mac/U0/tri_mode_ethernet_mac_i/gmii_interface/rxdata_bus[*].delay_gmii_rxd]

Avrum

View solution in original post

Highlighted
Advisor
Advisor
471 Views
Registered: ‎02-12-2013

In general the IO timing constraints do nothing for you. The syntax for source synchronous interfaces is especially bad.

I recommend you lock down your I/O timing by putting the I/O registers in the IO block. A common way to do this is to use the IDDR or ODDR primitive.  Those will get locked into the IO block.  The other way is to use a constraint like this.

    set_property IOB TRUE [get_ports {port_name}];

Sometimes this constraint works sometimes it does not so you should check it.

----------------------------------------
DSP in hardware and software
-----------------------------------------