Debug Hub and ILA Clocking

Debug Hub, ILA, and VIO Clocking #

Some of the most useful tools in Vivado are the Internal Logic Analyzers (ILA) and Virtual IO (VIO). ILAs and VIOs are called Debug Cores. There are some clocking details to using Debug Cores that are a little confusing in the documentation. Here we point out a couple key details to using debug cores. Most of this information can be found spread across Xilinx User Guide 908. Note: the information herein has been checked for Vivado 2022 and 2025.

Architecture #

The general architecture for a design with two clock domains is shown in the Figure below. Each ILA can only probe one domain. The debug hub interfaces between each ILA and the BSCAN. The BSCAN is the dedicated JTAG to FPGA fabric interface. The debug hub must have a clock driving it; the clock to the debug hub must be free running (no generated clocks) and stable. The debug hub clock must be at least 2.5 times the JTAG clock frequency but less than or equal to 100MHz.

flowchart LR


BSCAN <--> dbg_hub


dbg_hub <--> ila_2
subgraph clk_domain_2
	clk2([clk2]) --> ila_2
end

subgraph clk_domain_1
	clk1([clk1]) --> ila_1
end
dbg_hub <--> ila_1
clk1 --> dbg_hub

What can be slightly confusing is that the debug hub is automatically instantiated by Vivado at implementation. The next section discusses how to configure the debug hub.

Configuration Notes #

When instantiating an ILA, Vivado will add four lines to the target constraints file. These constraints must be executed at the end of synthesis, before implementation.

set_property C_CLK_INPUT_FREQ_HZ 100000000 [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_IBUF_BUFG]

The first line sets the clock frequency of the clock into the debug hub in Hz. If the clock frequency is over 100MHz, the C_ENABLE_CLK_DIVIDER should be set to true. This will enable a small MMCM within the debug hub to divide the clock appropriately. The last line tells Vivado what clock to wire into the debug hub. Invariable Vivado will infer some of these constraints incorrectly (especially with multiple clock domains) when adding an ILA and they must be manually corrected.

Sometimes it may also be necessary to “disconnect” the debug hub clock first:

disconnect_debug_port dbg_hub/clk

Symptoms #

One frustrating problem is if the ILA instantiates correctly, brings up correctly, but when the arm button is pressed, the ILA reverts immediately to idle. And there are NO errors! If this happens, then the most likely culprit is that something with the clock configuration is incorrect. For example, this can happen if the clock frequency defined is different than the frequency of the clock wired into the debug hub.

Conclusion #

Hopefully this saves a few people from some of the frustrations of configuring the debug hub clock in Vivado. At the very least, it might save my future self from the pain.