Enabling Kernels for Debugging with Chipscope - 2023.2 English

Vitis Unified Software Platform Documentation: Application Acceleration Development (UG1393)

Document ID
Release Date
2023.2 English

System ILA

The key to hardware debugging lies in instrumenting the kernels with the required debug logic. The following topic discusses the v++ linker options that can be used to list the available kernel ports, enable the System Integrated Logic Analyzer (ILA) core on selected ports, and enable the AXI Protocol Checker debug core for checking for protocol violations.

The ILA core provides transaction-level visibility into an instance of a compute unit (CU) running on hardware. AXI traffic of interest can also be captured and viewed using the ILA core. The ILA provides custom event triggering on one or more signals to allow waveform capture at system speeds. The waveforms can be analyzed in a viewer and used to debug hardware, finding protocol violations, or performance issues. It can also be crucial for debugging difficult situation like application hangs.

Captured data can be accessed through the AMD virtual cable (XVC) using the Vivado tools. See the Vivado Design Suite User Guide: Programming and Debugging (UG908) for complete details.

The ILA core can be added to an existing RTL kernel to enable debugging features within that design, or it can be inserted automatically by the v++ compiler during the linking stage. The v++ command provides the --debug option as described in --debug Options to attach System ILA cores at the interfaces to the kernels for debugging and performance monitoring purposes.

Important: ILA debug cores require system resources, including logic and local memory to capture and store the signal data. Therefore they provide excellent visibility into your kernel, but they can affect both performance and resource utilization.

The -–debug option to enable ILA IP core insertion has the following syntax:

 --debug.chipscope <cu_name>[:<interface_name>]>
Tip: The <interface_name> is optional, and if not specified all ports on the CU will be analyzed. You can use the --debug.list_ports option to return the interface names on the kernel to use with --debug options.

In case of a flattened design or any design where there would be multiple debug bridges in master mode, the flow will not pick one to stitch the debug cores, a constraint is needed to define the connectivity. For example in a Samsung Smart SSD U.2 flat shell, there is no partitioning between the static and dynamic regions while generating the kernels with the debug (ILA) options enabled. It is required to specify the connectivity of the kernel AXI ports that needs to be under debug to the user debug bridge in the dynamic region.

To specify the connectivity, you must provide the option below in the v++ command line:

--advanced.paramcompiler.userPostDebugProfileOverlayTcl=<path to post_dbg_profile_overlay.tcl > 

Inside the post_dbg_profile_overlay.tcl, the file must call the XDC file with the connect debug core command and mention its processing order.

For example, the contents in the post_dbg_profile_overlay.tcl file are given below.

read_xdc < path to the connect_debug_core.xdc file>
set_property used_in_implementation TRUE [get_files <path to the connect_debug_core.xdc file>]
set_property PROCESSING_ORDER EARLY [get_files <path to the connect_debug_core.xdc file>]]

In the connect_debug_core.xdc file, you have to specify the connect_debug_cores constraint.

For example:

connect_debug_cores -master [get_cells -hierarchical -filter {NAME =~ *debug_bridge_xsdbm/inst/xsdbm}] 
-slaves [get_cells -hierarchical -filter {NAME =~ level0_i/ulp/system_ila_0}]

AXI Protocol Checker

The AXI Protocol Checker core monitors AXI interfaces. When attached to an interface, it actively checks for protocol violations and provides an indication of which violation occurred. You can assign it for all CUs in the design, or for specific CUs and ports.

The -–debug option to enable AXI Protocol Checker insertion has the following syntax:

 --debug.protocol all

The protocol checker can be specified with the keyword all, or the <cu_name>:<interface_name>.

Note: The --debug.list_ports option can be specified to return the actual names of ports on the kernel to use with protocol or chipscope.

An example flow you could use for adding ILA or protocol checkers to your design is outlined below:

  1. Compile the kernel source files into an XO file, using the -g option to instrument the kernel for debug features:
    v++ -c -g -k <kernel_name> --platform <platform> -o <kernel_xo_file>.xo <kernel_source_files> 
  2. After the kernel has been compiled into an XO file, use --debug.list_ports to cause the v++ compiler to print the list of valid compute units and port combinations for the kernel:
    v++ -l -g --platform <platform> --connectivity.nk <kernel_name>:<compute_units>:<kernel_nameN> 
    --debug.list_ports <kernel_xo_file>.xo 
  3. Add the ILA or AXI debug cores on the desired ports by replacing list_ports with the appropriate --debug.chipscope or --debug.protocol command syntax:
    v++ -l -g --platform <platform> --connectivity.nk <kernel_name>:<compute_units>:<kernel_nameN> 
    --debug.chipscope <compute_unit_name>:<interface_name> <kernel_xo_file>.xo
Tip: The --debug option can be specified multiple times in a single v++ command line, or configuration file to specify multiple CUs and interfaces.

When the design is built, you can debug the design using the Vivado hardware manager as described in Debugging with ChipScope.