Examples

This chapter presents examples to illustrate particular debug techniques and flows.

Complete Command Line Debug Example

To get familiar with the command line flow in the SDx™environment, take the IDCT exampleavailable from the Xilinx GitHub repository and compile it manually (no makefile) for debugging.
  1. In a terminal, set up your environment by sourcing theSDxenvironment setting file to build the accelerated application:
    • C Shell:source /settings64.csh
    • Bash:source /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
  2. Clone the completeSDAccel ExamplesGitHub repository to acquire the example code:
    git clone https://github.com/Xilinx/SDAccel_Examples.git
    This creates an SDAccel_Examplesdirectory which includes the IDCT example. Move into the example directory:
    cd SDAccel_Examples/vision/idct/

    The host code is fully contained insrc/idct.cppand the kernel code is part ofsrc/krnl_idct.cpp.

  3. Compile the kernel software, using the option-t sw_emuto specify compilation for software emulation. In general, no additional options are required for hardware emulation, except for changing the-toption tohw_emu.
    1. The next step is to compile the kernel object file for debugging. The kernel is compiled using thexocccompiler:
      xocc -g -c -k krnl_idct -t sw_emu --platform  -o krnl_idct.xo src/krnl_idct.cpp

      The-goption ensures that the code is compiled for debugging. The-coption instructs the compilation of the kernel, which is implemented by thekrnl_idctfunction (-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 thespecified through--platformoption. The generated Xilinx object file is calledkrnl_idct.xoand is specified with the-ooption. The file to be compiled is the last argument.

    2. 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  --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-goption is provided for debugging followed by the-loption to instructxoccto perform object linking. The target and platform need to be presented again and need to be aligned with the compile step. The provided--xpoption is an example of how to control the downstream tools such as HLS with arguments (in most cases, this is not required).

      The--spoption 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--nkoption is used to specify multiple instances of a kernel. In this case, only one instance ofkrnl_idctis implemented in the final bitstream. The name of the bitstream is defined by the-ooption before the different kernel object files are listed as the last argument.

  4. Compile and link the host code for debugging. The host code is compiled with the GNU compiler chain, although it is wrapped underxcpp. Thus, separate compile and linking phases can also be performed. The host compilation is completely independent of the final target.
    1. Compile host code C++ files:
      xcpp -c -I${XILINX_XRT}/include -g -o idct.o src/idct.cpp

      The-coption specifies a compile-only run, which creates an object file. The name of the object file is specified by the-ooption. The-Ioption is using the runtime environment variableXILINX_XRTto specify the location of the common header files used by the host code. The-goption states that a debug compile is initiated. The final argument is the source file to be compiled in this step.

    2. Link the object files:
      xcpp -g -lOpenCL -lpthread -lrt -lstdc++ -L${XILINX_XRT}/lib/ -o idct idct.o

      Linking is performed again using the-goption to ensure debug information is included. Because the example uses theOpenCL™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-Loption. Finally, the name of the executable is specified by the-ooption and the previously generated object file is provided through the last argument.

  5. Prepare the emulation environment. The following command is required for emulation runs:
    emconfigutil --platform 
    The actual emulation mode ( sw_emuor hw_emu) then needs to be set through the XCL_EMULATION_MODEenvironment variable. In C-shell this would be as follows:
    setenv XCL_EMULATION_MODE sw_emu
  6. 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 theSDAccel™environment as described in the first section of this description.
    1. In the first terminal, start theSDxdebug server:
      ${XILINX_VIVADO}/bin/sdx_server --sdx-url
    2. In a second terminal, set the emulation mode:
      setenv XCL_EMULATION_MODE sw_emu
      Create an sdaccel.inifile in the rundirectory with the following content:
      [Debug] app_debug=true
      Run GDB by executing the following:
      xgdb –-args idct krnl_idct.xclbin
      Enter the following on the gdbprompt:
      run
    3. 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 anotherxgdb:
      xgdb
      • For software emulation:
        • Type the following on thegdbprompt:
          file /data/emulation/unified/cpu_em/generic_pcie/model/genericpciemodel
          Note:Because GDB does not expand the environment variable, it is easiest to replace with the actual value of $XILINX_SDX.
      • For hardware emulation:
        1. Locate thesdx_servertemporary directory:/tmp/sdx/$uid.
        2. Find thesdx_serverprocess ID (PID) containing the DWARF file of this debug session.
        3. At thegdbprompt, run:
          file /tmp/sdx/$uid/$pid/NUM.DWARF
      • In either case, connect to the kernel process:
        target remote :NUM

        Here,NUMis the number returned by thesdx_serveras the GDB listener port.

      At this point, debugging of thesw_emuandhw_emucan 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.