Using the Debug Environment - 2024.1 English

AI Engine Tools and Flows User Guide (UG1076)

Document ID
UG1076
Release Date
2024-05-30
Version
2024.1 English

The Vitis IDE debug environment has many features found in traditional GUI-based debug environments, such as GDB. You can add break points to the code, step over or step into specific lines of codes, loops, or functions, and examine the state of variables and force them to specific values. These are a few of the features in the Vitis IDE debug environment.

After you have launched the Debug perspective, you will see several windows or views displayed, such as the Debug view in the upper left of the display, as shown in the following figure. During the debug process, several windows show the debug state that include call stack, code at breakpoint, step over states, breakpoints view, variables view, registers view, disassemble view, and pipeline view.

The Debug view shows states of cores that are under debug. It shows where (which file and which line of source code of the file) debugger stops at and with what action it is taking (breakpoint/step over/…) as shown in the following figure.

Figure 1. Debug View

The following figure shows the Breakpoints information with current setup breakpoints. The square with a check mark indicates the breakpoint is enabled. Click on the check mark to clear the check mark and disable breakpoint during debugging. This lets you manage breakpoints without having to remove them or add them back into the code.

Figure 2. Breakpoints View
Important: Each AI Engine tile supports four breakpoints when debugging on the AI Engine simulator, or co-simulation. The TCF framework stops at the AI Engine kernel main() by default. Breakpoints attached to a while statement consume two breakpoint resources. A workaround is to attach the breakpoint inside the while loop. This only consumes one breakpoint.

In a source-level debugger, you can trace the source variables allocated to memory or registers. Their location and contents can be visualized. However, when all optimizations are enabled, tracing source variables is not straightforward:

  • Local scalar variables typically reside in registers, often different ones at different points in the execution.
  • Variables allocated to memory are not always directly updated. For example, a global variable can be loaded in registers in front of a loop. Then, it can be operated on in registers inside the loop, and only stored back in memory after the loop. This is referred to as optimization redundant store removal.
  • Similarly, stepping through the source code becomes difficult when the code of a single source line is scattered in the eventual object code.