SDSoC Debug Features
This section provides details on debugging in theSDx™environment using theVivado® Design SuiteIDE or the command line.
SDx Environment Debug Tools
TheSDxenvironment includes theXilinxSystem Debugger (XSDB) for debuggingSDSoCenvironment designs.
Xilinx System Debugger (XSDB)
XilinxSystem Debugger (XSDB) uses theXilinxhw_server
as the underlying debug engine.
TheXilinxSoftware Development Kit (SDK)translates each user interface action into a sequence of Target Communication Frameworks (TCF) commands. It then processes the output from System Debugger to display the current state of the program being debugged. It communicates to the processor on the hardware usingXilinxhw_server
. You can debug multiple processors simultaneously with a single System Debugger debug configuration. This is the recommended debug engine forSDxenvironment designs. The System Debugger can either be launched on the hardware or the QEMU engine.
The workflow is made up of the following components:
- ELF file
- To debug your application, you must use an ELF file compiled for debugging. The debug ELF file contains additional debug information for the debugger to make direct associations between the source code and the binaries generated from that original source. Refer to Build Configurationsfor more information.
- Debug configuration
- To launch the debug session, you must create a debug configuration in the SDxenvironment. This configuration captures options required to start a debug session, including the executable name, processor target to debug, and other information. Refer to Setting Debug Configurationsfor more information.
- SDxdebug perspective
- Using the debug perspective, you can manage the debugging or running of a program in the SDxworkbench. You can control the execution of your program by setting breakpoints, suspending launched programs, stepping through your code, and examining the contents of variables.
You can repeat the cycle of modifying the code, building the executable, and debugging the program in theSDxenvironment.
Setting Debug Configurations
To debug, run, and profile an application, you must create a debug configuration that captures the settings for executing and debugging the application. To create a debug configuration, in the Assistant view, right-click on theDebugbuild configuration, and select from the menu. Alternatively, you can select the command from the main menu. The Debug Configurations dialog box opens as shown below.
In the Debug Configurations dialog box, select theXilinx SDx Application Debuggerto create a debug configuration for the project. A new debug configuration is created for the application project, and is opened with multiple tabs to manage the configuration.
Main Tab
Application Tab
The Application tab displays the compiled application .ELF file that is being downloaded to be run on the processor.
Target Setup Tab
For Linux applications, the Target Setup tab is blank. For standalone applications, the tab lets you specify the hardware platform, and whether to use the first stage boot loader (FSBL) flow for initialization (if you need to initialize devices on the platform).
Arguments Tab
In the Arguments tab, you can specify any variables that are needed for launching the debug session. ClickVariablesto display the Select Variable dialog box.
Environment Tab
In the Environment tab, you can set any environment variables for the debug configurations.
ClickNewto create and define a value for a new environment variable to add to the debug configuration. ClickSelectto display a list of existing environment variables that can be added to the debug configuration. These can be edited and set to specific values.
Remaining Debug Configuration Tabs
The Symbol Files, Source, Path Map, and Common tabs are for advanced debugging of application-specific functions that do not apply to XSDB, and can be safely ignored.
Target Connections
In theTarget Connectionsview, you can configure multiple remote targets. It displays connected targets, and you can add or delete target connections. TheSDxenvironment establishes target connections through the Hardware Server agent. In order to connect to remote targets, the hardware server agent must be running on the remote host, which is connected to the target.
Use theHardware Serverwhen the application is for standalone. The Hardware Server only requires a JTAG connection to the board. Use theLinux TCF Agentfor when the application is compiled to run on Linux for the SoC. TheLinux TCF Agentrequires an Ethernet connection from the machine to the board.
For more information, refer toConnecting to the Hardware.
Debug Linux Applications in the SDx IDE
In theSDxIDE, use the following procedure to debug your application:
- Set the platform to boot from the SD card, as specified in the User Guide for the selectedSDSoCplatform.
- In the SDx Application Project Settings window, set the Target toHardware, and enable theGenerate SD card imagecheckbox.
- In the Assistant view, right-click theDebugbuild configuration, and select theSet Activecommand.
- Click theBuild() button, in the Assistant view or the main menu, to build the Debug configuration.
- From a file browser, or command shell, copy the contents of theDebug/sd_cardfolder to an SD card.
- Insert the SD card into the card reader of the platform, and boot the card.
- Make sure the board is connected to the network, and note its IP address, for example, by executing
ifconfig eth0
on the board at the command prompt using a terminal communicating with the board over UART. - In the Assistant view, right-click theDebugbuild configuration, and select to create a new debug configuration.
- Double click or right-click and selectNewon theXilinx SDx Application Debugger.
- In the new configuration, click theNewbutton next toConnection: Linux Agent.
- In theTarget Connection Detailsspecify the target name and enter the IP address of the board. It is highly suggested to test the connection by click theTest Connectionbutton to make sure it can connect to the board.
- ClickApplyto save the changes and clickDebug.
- Switch to theSDSoCenvironment debug perspective, where you can start, stop, step, set breakpoints, examine variables and memory, and perform various other debug operations.
Debugging Standalone or FreeRTOS Applications in the SDx IDE
- In the Assistant view, right-click theDebugbuild configuration, and select theSet Activecommand.
- Click theBuild() button, in the Assistant view or the main menu, to build the Debug configuration.
- In the Assistant view, right-click theDebugbuild configuration, and select to create a new debug configuration.
- Optional:Switch to theSDSoCenvironment Debug Perspective, where you can start, stop, step, set breakpoints, examine variables and memory, and perform various other debug operations.
- Optional:In theSDxIDE toolbar, clickDebug, which provides a shortcut to the procedure described above.
Xilinx Software Command-Line Tool (XSCT)
Graphical development environments such as theSDxenvironment are useful for improving development for a new processor architecture. It helps to abstract away and group most of the common functions into logical wizards that even a novice can use. However, the scriptability of a tool is also essential for providing the flexibility to extend what is done with that tool. It is particularly useful when developing regression tests that are run nightly, or for running a set of commands that are used often by the developer.
XilinxSoftware Command-line Tool (XSCT) is an interactive and scriptable command line interface to theSDxenvironment. As with otherXilinxtools, the scripting language for XSCT is based on Tool Command Language (Tcl). You can run XSCT commands interactively or script the commands for automation. XSCT supports the following actions:
- Create hardware, board support packages (BSPs), and application projects.
- Manage repositories.
- Set toolchain preferences.
- Configure and build BSPs/applications.
- Download and run applications on hardware targets.
- Create and flash boot images by running Bootgen and
program_flash
tools.
For information on XSCT commands, see theXilinx Software Command-Line Tool (XSCT) Reference Guide(UG1208).
System Emulation
System emulation can be run on System Debugger using the Target Communications Framework (TCF) server.
Running System Emulation from the IDE
System emulation provides the same level of accuracy as the final implementation without the need to compile the system into a bitstream and program the device on the board. System emulation can be used for debugging applications without involving the actual hardware. It can also be used for identifying any bottlenecks in performance.
Enable System Emulation
- Set the Active build configuration toDebug.
- Set the Target toEmulation.
- Set the emulation model. There are two emulation model modes:
- Debug
- Builds the system through RTL generation, and the IP integratorblock design containing the hardware function, elaborates the hardware design, and runs behavioral simulation on the design, with a waveform viewer to help you analyze the results. You interact with the Vivadosimulator within the Vivado Design Suiteto analyze the waveforms.
- Optimized
- Runs the behavioral simulation in batch mode, returning the results without the waveform data. While the Optimized model can be faster, it returns less information than the Debug model.
Because emulation does not require a full system compile, the tool disables the generation of the bitstream and the Generate SD card image option to improve runtime and iteration time. Using system emulation allows you to verify and debug the system with the same level of accuracy as a full bitstream compilation.
- After specifying the emulation model, click theBuildbutton () to compile the system for emulation.
The duration of the build process depends on your application code, the size of your hardware functions, and the options you have selected. To compile the hardware functions, the tool stack includes theSDxenvironment, andVivadoHigh-Level Synthesis (HLS) tool, and theVivado Design Suite.
Run the System Emulator
- After building the emulation target, you can run the system emulator usingAssistantpanel, by right-clicking, and then selectingStart/Stop Emulator. . Alternatively, you can also select the application in the
- When the Start/Stop Emulator dialog box opens, the emulation mode is specified:
- If the emulation mode is Debug, you can choose to run the emulation with or without waveforms.
- If the emulation mode is Optimized, the Show Waveform check box is disabled, and cannot be changed.
The Start/Stop Emulator dialog box displays the Project name, the build Configuration, and has the Show Waveform option. Disabling theShow Waveformoption lets you run emulation with the output directed solely at the Emulation Console view, which shows all system messages including the results of any print statements in the source code. Some of these statements might include the values transferred to and from the hardware functions, or a statement that the application has completed successfully, which would verify that the source code running on the PS and the compiled hardware functions running in the PL are functionally correct. Enabling theShow Waveformoption provides the same functionality in the Console window, plus the behavioral simulation of the register transfer level (RTL), with a waveform window. The RTL waveform window allows you to see the value of any signal in the hardware functions over time. When usingShow Waveform, you must manually add signals to the waveform window before starting the emulation.
- Use the Scopes pane to navigate the design hierarchy.
- Select the signals to monitor in the Object pane, and then right-click to add the signals to the waveform pane.
- Click theRun Alltoolbar button to start updates to the waveform window. For more information about working with theVivadosimulator waveform window, refer toVivado Design Suite User Guide: Logic Simulation(UG900).
Note:Running with RTL waveforms results in a slower runtime, but enables detailed analysis into the operation of the hardware functions.TIP:
You can also start the system emulation by selecting the active project in the Project Explorer view, and then right-clicking to select one of the following menu commands:
Launching the emulator from the Debug As menu causes the perspective change to the debug perspective to arrange the windows and views to facilitate debugging the project.
View Emulation Output
- After you run the system emulator, you can see the program output in the console tab, and if theShow Waveformoption was selected, theVivadoIDE is launched with the simulator running.Add waveforms to the Waveforms window as desired. To start the simulation, click theRun Allbutton.
- To start a debug session with the emulator running, in the Assistant view right-click on the Debug build configuration and select .
- The Confirm Perspective Switch dialog box is displayed. ClickYesto switch to the Debug perspective.
- The application is started in the Debug perspective and the program execution is stopped at the main function. To resume the execution of the application code, clickResume.
This starts execution of the application code. The output of the application code can be seen in the Emulation Console, as shown in the following figure:
The status of different signals is displayed in theVivadoWaveform window. You also see any appropriate response in the hardware functions in the register transfer level (RTL) waveform. During any pause in the execution of the code, the RTL waveform window continues to execute and update, just like an FPGA running on the board.
- You can stop the emulation at any time using the menu optionStop.
TIP:For an example project to demonstrate emulation, create a new SDxenvironment project using the Emulation Exampletemplate. The README.txtfile in the project has a step-by-step guide for doing emulation on both the SDxIDE and the command line.
, and then selecting
Running System Emulation from the Command Line
TARGET
flag defines that the compilation should be done for emulation.
# FPGA Board Platform (Default ~ zcu102) PLATFORM := zcu102 # Run Target: # hw - Compile for hardware # emu - Compile for emulation (Default) TARGET := emu
-
debug
- Captures waveform data from the PL hardware emulation for viewing and debugging.
-
optimized
- Provides faster emulation without capturing hardware debug information.
# Target OS: # linux (Default), standalone TARGET_OS := linux # Emulation Mode: # debug - Include debug data # optimized - Exclude debug data (Default) EMU_MODE := optimized
Typemake
to build the program at the command prompt. If you want to view the waveform in the simulator, change directory to the level where you have the_sdsdirectory, then typesdsoc_emulator -graphic-xsim
. This starts theVivadoSimulator, as shown below.
Hardware Execution Features Available to All Platforms
- Full software debug using theXilinx System Debugger (XSDB)
- Co-debug of hardware and software using theXilinx System Debugger (XSDB)
- Event Tracing
Hardware Debugging in SDSoC UsingChipScope
After the final system image is generated and executed in theSDxenvironment, the entire system (including the embedded processor OS, the application code, and the accelerated hardware functions) can be validated to be executing correctly on the actual hardware, and any necessary debug activity can be performed. TheChipScope™feature is used to debug designs in hardware using theVivadoIDE. Cross-probing hardware and software requires an advanced understanding of theSDxenvironment and theVivadotool suite.
This debugging step can reveal issues relating to connecting to the target platform, booting the processor, and programming the hardware with the system image. It might also highlight problems with interactions between the application code and the hardware functions in the form of protocol violations, and with validating multiple hardware functions with the application code.
This step could also reveal system performance metrics that could shift your focus from debug to performance tuning. In theSDxenvironment, you can instrument the hardware to analyze transactions on the interfaces of the hardware accelerators and adapters. You can also debug the hardware portion of the design.
Using --dk to Enable Debugging the Accelerated Function
Visibility into a running design is crucial for debugging difficult situations, like when the application hangs. The System ILA debug core provides transaction-level visibility into an accelerated kernel or function running on hardware. AXI traffic of interest can also be captured and viewed using the System ILA core.
The System ILA core can be instantiated in the overall hardware of an existingSDxenvironment design to enable debugging features within that design, or it can be inserted automatically by the compiler.Thesds++
compiler provides the-–dk
switch to attach System ILA cores at the interfaces to the hardware functions for debugging and performance monitoring purposes.Use the-–dk
option to enable System ILA core insertion:
--dk arg <[protocol|chipscope|list_ports]::>
The following is an example of the-–dk
option in use:
sds++ -c --dk chipscope:vadd_cu0:s_axi_control --dk chipscope:vadd_cu0:m_axi_gmem
The following is an example of a Makefile to insert debug cores:
APPSOURCES = main.cpp mmult.cpp madd.cpp EXECUTABLE = mmultadd.elf PLATFORM = zc702 CLKID = DMCLKID = SDSFLAGS = -sds-pf ${PLATFORM} ${DMCLKID} \ -sds-hw mmult mmult.cpp ${CLKID} -sds-end \ -sds-hw madd madd.cpp ${CLKID} -sds-end \ -debug-port mmult:A \ -debug-port madd:C \ --dk chipscope:madd_1:A \ --dk chipscope:madd_1_if:ap_ctrl CC = sds++ ${SDSFLAGS} CFLAGS = -O3 -c CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" LFLAGS = -O3 OBJECTS := $(APPSOURCES:.cpp=.o) DEPS := $(OBJECTS:.o=.d) .PHONY: all clean ultraclean all: ${EXECUTABLE} ${EXECUTABLE}: ${OBJECTS} ${CC} ${LFLAGS} $^ -o $@ -include ${DEPS} %.o: %.cpp ${CC} ${CFLAGS} $^ -o $@ clean: ${RM} ${EXECUTABLE} ${OBJECTS} ${DEPS} ultraclean: clean ${RM} ${EXECUTABLE}.bit ${RM} -rf _sds sd_card
The–debug-port
option specifies a function name and argument name to insert a System ILA for accelerators. The lower level--dk
option specifies the tool command language (Tcl) file used to recreate the block design instance and port name, such as in the following example.
-debug-port mmult:A
is equivalent to--dk chipscope:mmult_1:A
, but thesds++
command determines what the instance and port names are in the Tcl file used to recreate the block design.Note:A Tcl file is used by the SDxenvironment to recreate a block design in the hardware platform including the accelerators in the Vivado Design Suite.--xp param:compiler.userPostSysLinkTcl=
, where <user_tcl_file
> containsIP integratorTcl commands for advanced users who need to perform post-processing of the System ILA in the block diagram after system linking and before synthesis.Note:Advanced users can change ILA settings using Tcl commands. It is often possible to enable additional probes and interfaces in an ILA and debug other signals in the same clock domain as needed. Doing this can save logic resources in the FPGA. You can also cross-trigger a chain of ILAs using this feature.
--dk
can be used to insert the System ILA for accelerator and adapter ports. You need to use this option to observe the adapter ports. Once the design is built, you can debug the design using theVivadohardware manager features, as described inVivado Design Suite User Guide: Programming and Debugging(UG908).
Add Flags to Build Settings
- From the Assistant view, right-click the Debug or Release build configuration, and select theSettingscommand.
- In the Build Configuration Settings dialog box, click theEdit Toolchain Settingslink.
- In the Tool Settings tab of the Properties for
dialog box, select . - Click in theLinker Flagsfield and add the debug flags as needed.
TIP:At the top of the Tool Settings tab, there is a Configuration field that lets you select the build to apply the settings to the Debug build, the Release build, or All builds.See theSDx Command and Utility Reference Guidefor more information on compiler and linker options.
Analyzing the Hardware Design
- To confirm which signals can be debugged, navigate toProject Explorer.
folder in the - Double-clickprj.xpr, which opens the design in theVivadoIDE.
- In theVivadoIDE, clickOpen Block Designin the Flow Navigator underIP integrator.
- In the Designs window, look for the instances of
system_ila_x
.
- Select the System ILA instance(s) in theDesignwindow to highlight the instances in the block design.
- Select the interface nets connected to the System ILA and ensure that they have been connected to the interfaces specified in theSDxIDE.
Debugging Designs UsingVivadoHardware Manager
- Launch theVivado Design Suite.
- SelectOpen Hardware Managerfrom theTasksmenu. An alternate method is to open theVivadoproject from theSDxIDE:
Then, from theVivadoFlow Navigator, click , as shown below./Debug/_sds/p0/vivado/prj/prj.xpr
- For either method you used to open the project, the Open New Hardware Target wizard is displayed as shown below. ClickNext.
- In Hardware Server Settings, connect to the correct target by clickingConnect to, and then selecting eitherRemote ServerorLocal Server. If you selectRemote Server, you need to add aHost nameand the correctPortnumber. The following example assumes that you are connected locally:
- ClickNext. The Select Hardware Target page opens which identifies the target(s) present on the board.
- ClickNext. The Open Hardware Target Summary page opens which summarizes the server name, the port it is connected to, and the correct target and operating frequency.
- ClickFinish. The Hardware Manager window opens as shown below.
- TheVivadohardware manager can now be used to connect to the ILA that is running on your design. Refer to theVivado Design Suite User Guide: Programming and Debugging(UG908)for more information on working with the tool.
Hardware/Software Event Tracing
Event tracing provides visibility into each phase of the hardware function execution, including the software setup for the accelerators and data transfers, as well as the hardware execution of the accelerators and data transfers. Tracing an application produces a log that records correlation between events for a duration of time. The goal of tracing is to help debug execution by observing what happened when, and how long events took.
Software event tracing automatically instruments the stub of the hardware function to capture software control events associated with a hardware function call. The event types that are recorded include the setup and initialization of the hardware accelerator, data transfers, and hardware-software synchronization events.
Hardware event tracing of accelerators with data transfers overAXI4-Streamconnections can also be enabled through the use of the-trace
option of thesds++
system compiler. When the linker is invoked with the-trace
option, it inserts hardware monitor IP cores into the RTL implementation of the hardware function to track the accelerator start and stop, and the duration of data transfers.
As with hardware debugging, event tracing requires you to connect theSDSoCenvironment platform to a host computer as described inConnecting to the Hardware. To run event tracing, execute the application using theSDxIDE from the host using a debug or release build configuration.
Hardware/Software System Runtime Operation
The system compiler implements hardware functions either by cross-compiling them into IP using theVivadoHigh-Level Synthesis (HLS) tool, or by linking them as C-callable IP, as described in theSDSoC Environment Platform Development Guide.
Each hardware function call site is rewritten to call a stub function that manages the execution of the hardware accelerator. The figure below shows an example of hardware function rewriting. The original user code is shown on the left. The code section on the right shows the hardware function calls rewritten with new function names.
The stub function initializes the hardware accelerator, initiates any required data transfers for the function arguments, and then synchronizes hardware and software by waiting at an appropriate point in the program for the accelerator and all associated data transfers to complete. For example, if the hardware functionfoo()
is defined infoo.cpp, you can view the generated rewritten code in_sds/swstubs/foo.cppfor the project build configuration. As an example, the stub code shown below replaces a user function marked for hardware. This function starts the accelerator, starts data transfers to and from the accelerator, and waits for those transfers to complete.
void _p0_mmult0(float *A, float *B, float *C) { switch_to_next_partition(0); int start_seq[3]; start_seq[0] = 0x00000f00; start_seq[1] = 0x00010100; start_seq[2] = 0x00020000; cf_send_i(cmd_addr,start_seq,cmd_handle); cf_wait(cmd_handle); cf_send_i(A_addr, A, A_handle); cf_send_i(B_addr, B, B_handle); cf_receive_i(C_addr, C, C_handle); cf_wait(A_handle); cf_wait(B_handle); cf_wait(C_handle);
Event tracing provides visibility into each phase of the hardware function execution, including the software setup for the accelerators and data transfers, as well as the hardware execution of the accelerators and data transfers. For example, the stub code below is instrumented for trace. Each command that starts the accelerator, starts a transfer, or waits for a transfer to complete is instrumented.
void_p0_mmult_0(float *A, float *B, float *C) { switch_to_next_partition(0); int start_seq[3]; start_seq[0] = 0x00000f00; start_seq[1] = 0x00010100; start_seq[2] = 0x00020000; sds_trace(EVENT_START); cf_send_i(cmd_addr,start_seq,cmd_handle); sds_trace(EVENT_STOP); sds_trace(EVENT_START); cf_wait(cmd_handle); sds_trace(EVENT_STOP); sds_trace(EVENT_START); cf_send_i(A_addr, A, A_handle); sds_trace(EVENT_STOP); sds_trace(EVENT_START); cf_send_i(B_addr, B, B_handle); sds_trace(EVENT_STOP); sds_trace(EVENT_START); cf_receive_i(C_addr, C, C_handle); sds_trace(EVENT_STOP); sds_trace(EVENT_START); cf_wait(A_handle); sds_trace(EVENT_STOP); sds_trace(EVENT_START); cf_wait(B_handle); sds_trace(EVENT_STOP); sds_trace(EVENT_START); cf_wait(C_handle); sds_trace(EVENT_STOP);
Software Tracing
Event tracing automatically instruments the stub function to capture software control events associated with the implementation of a hardware function call. The event types include the following:
- Accelerator setup and initiation
- Data transfer setup
- Hardware/software synchronization barriers (“wait for event”)
SeeSDSoC Environment Programmers Guide(UG1278)for more detail on these topics.
Each of these events is independently traced and results in a singleAXI4-Litewrite into the programmable logic, where it receives a time stamp from the same global timer as hardware events.
Hardware Tracing
TheSDSoCenvironment supports hardware event tracing of accelerators cross-compiled usingVivadoHigh-Level Synthesis (HLS) tool, and data transfers overAXI4-Streamconnections. Whensds++
is invoked with the-trace
option, it automatically inserts hardware monitor IP cores into the generated system to log the following event types:
- Accelerator start and stop, defined by
ap_start
andap_done
signals. - Data transfer start and stop, defined byAXI4-Streamhandshake and
TLAST
signals.
ap_start
and
ap_done
signals are not part of the IP interface:
#pragma HLS interface s_axilite port=foo
These debug cores use some hardware resources; less than 0.1% of the hardware resources available on a ZC706 board.
TheAXI4-Streammonitor core has two modes: basic and statistics. The basic mode does just the start/stop trace event generation. The statistics mode enables anAXI4-Liteinterface to two 32-bit registers. The register at offset 0x0 presents the word count of the current, on-going transfer. The register at offset 0x4 presents the word count of the previous transfer. As soon as a transfer is complete, the current count is moved to the previous register. By default, theAXI4-Streamcore is configured in the basic mode.
In addition to the hardware trace monitor cores, the output trace event signals are combined by a single integration core. This core has a parameterizable number of ports (from 1–63), and can thus support up to 63 individual monitor cores (either accelerator orAXI4-Stream). The resource utilization of this core depends on the number of ports enabled, and thus the number of monitor cores inserted.
On a ZC706 platform, this can use between roughly 0.1-1.0 percent of the available hardware resources, and up to approximately 10% of the memories with the integration logic.
Implementation Flow
During the implementation flow, when tracing is enabled, tracing instrumentation is inserted into the software code and hardware monitors are inserted into the hardware system automatically. The hardware system (including the monitor cores) is then synthesized and implemented, producing the bitstream. The software tracing is compiled into the regular user program.
Hardware and software traces are time-stamped in hardware and collected into a single trace stream that is buffered up in the programmable logic.