Debugging Kernels with ILA Debug Cores
SLASH can insert an AXIS Integrated Logic Analyzer (ILA) into the user region so
that kernel interfaces can be observed on hardware from the Vivado Hardware
Manager. Nets to probe are declared in the linker config.cfg; the linker
instantiates the ILA and routes it to the debug hub that the base shell exposes.
Declaring debug nets
Add a [debug] section to config.cfg with one net= entry per interface
to probe, using <instance>.<port> syntax. Up to 16 nets are supported. See
examples/00_axilite/config.cfg:
[debug]
net=increment_0.axis_out
net=increment_0.m_axi_gmem0
net=accumulate_0.s_axi_control
Build the design for hardware as usual (for example slashkit link -p hw or the
CMake add_vbin() flow). No other configuration is required.
Probe files
Vivado needs two debug probe files (.ltx), loaded in order – the base file
first, then the user-region file.
- Base probe file (static shell)
debug_nets.ltxdescribes the static shell’s debug network. It is generated once when the static shell is built and ships inside the installedslashkitpackage. Both static shells instantiate the debug hub, so pick the file matching the shell you built against –slashkit/resources/static_shell/debug_nets.ltxfor the service shell,slashkit/resources/static_shell_compute/debug_nets.ltxfor the compute shell.Load it as
PROBES.FILEand refresh. Do not assign it toFULL_PROBES.FILE– see the warning below.- Partial probe file (user region)
top_i_slash_slash_<project>_inst_0_hw_probes.ltxdescribes the ILAs in your design. When the[debug]section is present, the linker packages it inside the built.vbin(underimages/). Extract it withtar xzf <name>.vbin.
Opening the ILAs in the Hardware Manager
Connect the Vivado Hardware Manager to the board and load the base probes file first:
open_hw_manager
connect_hw_server
open_hw_target
# The V80 presents two JTAG devices; the FPGA is xcv80, not arm_dap.
current_hw_device [lindex [get_hw_devices xcv80*] 0]
set_property PROBES.FILE {debug_nets.ltx} [current_hw_device]
refresh_hw_device [current_hw_device]
Then program your .vbin and load the partial probes file:
set_property PROBES.FILE {top_i_slash_slash_<project>_inst_0_hw_probes.ltx} [current_hw_device]
refresh_hw_device [current_hw_device]
The ILA cores declared in [debug] then appear under the device and can be
triggered and captured as usual.
Pause the host (e.g. with a sleep, or a prompt for user input) so the ILA can be armed before the kernel runs – but place the pause
after any setFrequency() call, not immediately after .vbin programming.
Arming first and changing the clock afterwards breaks the capture (see the warning
below). The working order is:
program the
.vbinset the user clock (host
setFrequency(), orv80-smi debug clockwiz --set)pause the host (sleep, or request user input)
arm the ILA and set triggers
release the host (wait for sleep to expire, or provide user input)
Important
Construct the host-side device with programming disabled:
vrt::Device device(bdf, vbin, /*program=*/false);
The parameter defaults to true, which reprograms the device on construction
and wipes an ILA that has already been armed. Note that this also skips applying
the clock frequency recorded in the .vbin, so the user clock keeps whatever
rate it already had.
Warning
Load debug_nets.ltx as PROBES.FILE only. Assigning it to
FULL_PROBES.FILE as well makes run_hw_ila fail with:
ERROR: [Labtools 27-188] Use refresh_hw_device command, with a valid
[debug_nets.ltx] file before running this command.
The base-then-partial load order is still required; it is the extra
FULL_PROBES.FILE assignment alone that breaks the core. The core still
arms and triggers in that state, so the failure looks like an ILA whose
waveform window never updates rather than an error at set-up time.
Warning
Do not call vrt::Device::setFrequency() while an ILA is armed. Changing
the user clock under an armed core leaves it able to trigger but unable to hand
its buffer back, and the upload fails with:
ERROR: [Xicom 50-298] ILA core [...] - ChipScope Service AxisILA upload:
integer modulo by zero
As with FULL_PROBES.FILE above, the core arms and triggers normally, so this
presents as a waveform window that never updates rather than as an error when
the clock is set. It does not depend on the frequency requested – the same
failure occurs whether the new rate is above or below the one the design was
timed at.
Set the clock before arming, either from the host or with
v80-smi debug clockwiz -d <BDF> --set <hz> --region user, and leave it alone
for the rest of the session.