Examples
This chapter presents examples to illustrate particular debug techniques and flows.
Complete Command Line Debug Example
- In a terminal, set up your environment by sourcing the SDx environment setting file to build the
accelerated application:
- C Shell:
source <SDX_INSTALL_DIR>/settings64.csh
- Bash:
source <SDX_INSTALL_DIR>/settings64.sh
Starting from 2018.3, debugging requires you to source the runtime environment, which is installed separately:
- C Shell:
source /opt/xilinx/xrt/setup.sh
- Bash:
source /opt/xilinx/xrt/setup.sh
- C Shell:
- Clone the complete SDAccel Examples GitHub repository to acquire the
example
code:
git clone https://github.com/Xilinx/SDAccel_Examples.git
This creates an SDAccel_Examples directory which includes the IDCT example. Move into the example directory:cd SDAccel_Examples/vision/idct/
The host code is fully contained in src/idct.cpp and the kernel code is part of src/krnl_idct.cpp.
- Compile the kernel software, using the option
-t sw_emu
to specify compilation for software emulation. In general, no additional options are required for hardware emulation, except for changing the-t
option tohw_emu
.- The next step is to compile the kernel object file for
debugging. The kernel is compiled using the
xocc
compiler:xocc -g -c -k krnl_idct -t sw_emu --platform <DEVICE> -o krnl_idct.xo src/krnl_idct.cpp
The
-g
option ensures that the code is compiled for debugging. The-c
option instructs the compilation of the kernel, which is implemented by thekrnl_idct
function (-k
). The targetsw_emu
(-t
) determines that the output of this compilation is used for software emulation. The output of the compilation is intended to run on the<DEVICE>
specified through--platform
option. The generated Xilinx object file is calledkrnl_idct.xo
and is specified with the-o
option. The file to be compiled is the last argument. - Link the kernel object file. Linking allows multiple
kernels to be combined, and provides the means to specify implementation
directives. The following is the example link line for the
IDCT:
xocc -g -l -t sw_emu --platform <DEVICE> --xp "prop:solution.hls_pre_tcl=src/hls_config.tcl" --sp krnl_idct_1.m_axi_gmem0:bank0 --sp krnl_idct_1.m_axi_gmem1:bank0 --sp krnl_idct_1.m_axi_gmem2:bank1 --nk krnl_idct:1 -o krnl_idct.xclbin krnl_idct.xo
Similarly to the compile line, the
-g
option is provided for debugging followed by the-l
option to instructxocc
to perform object linking. The target and platform need to be presented again and need to be aligned with the compile step. The provided--xp
option is an example of how to control the downstream tools such as HLS with arguments (in most cases, this is not required).The
--sp
option is used to specify port bindings to specific DDR banks and PLRAMs. For optimization purposes, it is good to consider port binding for any larger designs. Each port can be bound individually to a DDR/PLRAM, and you are required to adhere to this same binding in the host code when allocating buffers.The
--nk
option is used to specify multiple instances of a kernel. In this case, only one instance ofkrnl_idct
is implemented in the final bitstream. The name of the bitstream is defined by the-o
option before the different kernel object files are listed as the last argument.
- The next step is to compile the kernel object file for
debugging. The kernel is compiled using the
- Compile and link the host code for debugging. The host code is
compiled with the GNU compiler chain, although it is wrapped under
xcpp
. Thus, separate compile and linking phases can also be performed. The host compilation is completely independent of the final target.- Compile host code C++
files:
xcpp -c -I${XILINX_XRT}/include -g -o idct.o src/idct.cpp
The
-c
option specifies a compile-only run, which creates an object file. The name of the object file is specified by the-o
option. The-I
option is using the runtime environment variableXILINX_XRT
to specify the location of the common header files used by the host code. The-g
option states that a debug compile is initiated. The final argument is the source file to be compiled in this step. - Link the object
files:
xcpp -g -lOpenCL -lpthread -lrt -lstdc++ -L${XILINX_XRT}/lib/ -o idct idct.o
Linking is performed again using the
-g
option to ensure debug information is included. Because the example uses the OpenCL™ interfaces and the runtime library, several additional libraries are included in the link process (-l
) which are picked up in addition to the default library path from the path specified by-L
option. Finally, the name of the executable is specified by the-o
option and the previously generated object file is provided through the last argument.
- Compile host code C++
files:
- Prepare the emulation environment. The following command is
required for emulation runs:
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
- Run the debugger on host and kernel. As stated in the earlier
chapter, running the debugger is best performed in the IDE. The following steps
guide you through the command line debug process which requires three separate
terminals, all prepared by sourcing the SDAccel™ environment as described in the first section of this
description.
- In the first terminal, start the SDx debug
server:
${XILINX_VIVADO}/bin/sdx_server --sdx-url
- In a second terminal, set the emulation
mode:
setenv XCL_EMULATION_MODE sw_emu
Create an sdaccel.ini file in the run directory with the following content:[Debug] app_debug=true
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 software emulation:
- Type the following on the
gdb
prompt:file <XILINX_SDX>/data/emulation/unified/cpu_em/generic_pcie/model/genericpciemodel
Note: Because GDB does not expand the environment variable, it is easiest to replace<XILINX_SDX>
with the actual value of$XILINX_SDX
.
- Type the following on the
- For hardware emulation:
- Locate the
sdx_server
temporary directory: /tmp/sdx/$uid. - Find the
sdx_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
Here,
NUM
is the number returned by thesdx_server
as the GDB listener port.
At this point, debugging of the
sw_emu
andhw_emu
can be done as usual with GDB. The only difference is that the host code and the kernel code are debugged in two different GDB sessions. This is common when dealing with different processes. It is most important to understand that a breakpoint in one process might be hit before the next breakpoint in the current process is hit. In these cases, the debugging session appears to hang, while the second terminal is waiting for input. - For software emulation:
- In the first terminal, start the SDx debug
server: