To help you get familiar with
debugging using the command line flow, this example walks you through building and
debugging the IDCT example available from the Xilinx GitHub.
- In a terminal, set up your environment as described in Setting Up the Vitis Environment.
- If you have not already done it, clone the Vitis Examples GitHub repository to acquire all of
the Vitis
examples:
git clone https://github.com/Xilinx/Vitis_Accel_Examples.git
This creates a Vitis_Examples directory which includes the IDCT example.
- CD to the IDCT example
directory:
cd Vitis_Examples/vision/idct/
The host code is fully contained in src/idct.cpp and the kernel code is part of src/krnl_idct.cpp.
- Build the kernel software for software emulation as discussed in Building the Device Binary.
- Compile the kernel object file for debugging using the
v++
compiler, where-g
indicates that the code is compiled for debugging:v++ -t sw_emu --platform <DEVICE> -g -c -k krnl_idct \ -o krnl_idct.xo src/krnl_idct.cpp
- Link the kernel object file, also specifying
-g
:v++ -g -l -t sw_emu --platform <DEVICE> -config config.cfg \ -o krnl_idct.xclbin krnl_idct.xo
The--config
option specifies the configuration file, config.cfg, that contains the directives for the build process as described in the Vitis Compiler Configuration File. The contents of the configuration file are as follows:kernel_frequency=250 [connectivity] nk=krnl_idct:1:krnl_idct_1 sp=krnl_idct_1.m_axi_gmem0:DDR[0] sp=krnl_idct_1.m_axi_gmem1:DDR[0] sp=krnl_idct_1.m_axi_gmem2:DDR[1] [advanced] prop=solution.hls_pre_tcl='src/hls_config.tcl"
- Compile the kernel object file for debugging using the
- Compile and link the host code for debugging using the GNU compiler chain,
g++
as described in Building the Host Program:Note: For embedded processor target platforms you will use the GNU Arm cross-compiler as described in Compiling and Linking for Arm.- Compile host code C++ files for debugging using the
-g
option:g++ -c -I${XILINX_XRT}/include -g -o idct.o src/idct.cpp
- Link the object files for debugging using
-g
:g++ -g -lOpenCL -lpthread -lrt -lstdc++ -L${XILINX_XRT}/lib/ -o idct idct.o
- Compile host code C++ files for debugging using the
- As described in emconfigutil Utility, prepare the emulation
environment using the following command:
emconfigutil --platform <device>
The actual emulation mode (sw_emu
orhw_emu
) then needs to be set through theXCL_EMULATION_MODE
environment variable. In C-shell this would be as follows:setenv XCL_EMULATION_MODE sw_emu
- As described in xrt.ini File, you must setup the runtime
for debug. In the same directory as the compiled host application, create an
xrt.ini file with the following
content:
[Debug] app_debug=true
- Run GDB on the host and kernel code. The following steps guide you through
the command line debug process which requires three separate command terminals,
setup as described in Setting Up the Vitis Environment.
- In the first terminal, start the XRT debug server,
which handles the transactions between the host and kernel
code:
${XILINX_VITIS}/bin/xrt_server --sdx-url
- In a second terminal, set the emulation
mode:
setenv XCL_EMULATION_MODE sw_emu
Run GDB by executing the following:xgdb –-args idct krnl_idct.xclbin
Enter the following on thegdb
prompt:run
- In the third terminal, attach the software emulation or hardware
emulation model to GDB to allow stepping through the design. Here, there
is a difference between running software emulation and hardware
emulation. In either flow, start up another
xgdb
:xgdb
- For debugging in software emulation:
- Type the following on the
gdb
prompt:file <XILINX_VITIS>/data/emulation/unified/cpu_em/generic_pcie/model/genericpciemodel
Note: Because GDB does not expand the environment variable, you must specify the path to the Vitis software platform installation as represented by<XILINX_VITIS>
- Type the following on the
- For debugging in hardware emulation:
- Locate the
xrt_server
temporary directory: /tmp/sdx/$uid. - Find the
xrt_server
process ID (PID) containing the DWARF file of this debug session. - At the
gdb
prompt, run:file /tmp/sdx/$uid/$pid/NUM.DWARF
- Locate the
- In either case, connect to the kernel process:
target remote :NUM
Where
NUM
is the number returned by thexrt_server
as the GDB listener port.
At this point, debugging the host and kernel code can be done as usual with GDB, with the host code and the kernel code running in two different GDB sessions. This is common when dealing with different processes.
Important: Be aware that the application might hit a breakpoint in one process before the next breakpoint in the other process is hit. In these cases, the debugging session in one terminal appears to hang, while the second terminal is waiting for input. - For debugging in software emulation:
- In the first terminal, start the XRT debug server,
which handles the transactions between the host and kernel
code: