Using the Vitis IDE

The Vitis™ tool flow, as described in Integrating the Application Using the Vitis Tools Flow, is also available in the Vitis IDE. The different steps involved in building the system project, with an AI Engine graph, PL kernels, and PS application, are described in the following sections.

Before using the Vitis IDE, you must first set up the development environment, as described in Setting Up the Vitis Tool Environment.

Creating the AI Engine Graph Project and Top-Level System Project

The Vitis integrated development environment (IDE) is available for building, running, and debugging AI Engine programs. This section provides screen captures that correspond to the command-line steps previously described.
  1. Start the Vitis IDE by entering vitis from the command line. When starting for the first time, you must specify a workspace directory to store your projects. You can also specify the workspace when launching the tool:
    vitis -workspace ./myWorkspace
  2. Create a new AI Engine project by selecting File > New > Application Project.
    TIP: If this is your first time launching the Vitis IDE, a Welcome screen opens. In this case, click on Create Application Project.

    The New Application Project wizard opens with an introductory page that describes the flow used to create a new project. Select Next to open the Platform selection page as shown in the following figure.



    Select the xilinx_vck190_base_202110_1 platform and click Next.

  3. The Application Project Details page opens as shown in the following figure.

    Here you specify the Application project name. Under System project, you can select an existing system project to add your application project to (if one exists), or let the Vitis IDE create a new system project. When creating a new system project, the name is automatically generated based on the application project name you specified. However, you can enter a new name in the Project name field.

    Next you specify the Processor to associate with your new project. In this example an AI Engine graph project is being created. Select the ai_engine Processor, and click Next.

  4. The Domain page opens as shown in the following figure.

    On the Domain selection page you can specify a processor domain for your new application project. In this example, because the aiengine Processor is already specified, there is only one domain listed and it is preselected. Click Next to proceed.

  5. The Templates page opens, as described in Vitis Tools Template Examples.

    In this example you are creating a new custom project. Select Empty Application template (default), and click Finish to create the project. The new AI Engine graph project is created and the Vitis IDE opens the project in the Design perspective.



Importing Source Files

With the AI Engine graph project open in the IDE, you can import the required source files and configure your project.
  1. To import sources for your AI Engine project, select the project in the Explorer view. Expand the folders, select the src folder, and click the Import Sources command () to open the dialog box shown in the following figure.

    IMPORTANT: The key to this dialog box is to ensure the Into folder field points to the src folder of your graph project, as shown for the aie_graph project.

    Use the Browse command to navigate to the folder containing the source files for your AI Engine graph. Select the graph and header files required for your graph application, and click Finish.

  2. Import data files required for your graph application using a similar process. Instead of the src folder, import files into the data folder of your AI Engine graph project.
    TIP: Data files can include input source files to exercise your graph or golden output data files to compare the results of simulation.
  3. After importing source and data files, you need to define the top-level of your graph. On the right side of the Project Editor window, click the Click to select Graph File link to open the File Selection dialog box as shown in the following figure. Navigate through the application project hierarchy, to the src folder and select the C/C++ code file containing your graph application.

The project is now ready to build.
TIP: The previous steps apply to both single kernel and multiple kernel programming. A Pipeline view is available in the Vitis IDE to provide single kernel debug (see Pipeline View for Single Kernel Debug).

Vitis Tools Template Examples

The last page of the New Application Project wizard in the Vitis IDE (shown in the following figure), displays a list of application templates that can be used for your design. Selecting a template creates a sample AI Engine graph application, and imports the necessary source code to let you build and examine different elements of the application simulation design.

Figure 1: AI Engine Application Templates


The template projects illustrate the basic features of AI Engine programming. You can study these templates, use them as a starting point for your own projects, or mix and match the features to create your own complex computation graphs. The following table describes some of the templates.

Table 1. Application Template Examples
Template Name Description Further Information
AI Engine, PL and PS System Design This design demonstrates integrating the AI Engine array with the Programmable Logic and the Processing System in a system. It performs hardware co-simulation and hardware implementation. Integrating the Application Using the Vitis Tools Flow
Async Buffer A graph to demonstrate asynchronous window APIs. Asynchronous Window Access
Async RTP Control Iterative A graph to demonstrate simple use of asynchronous RTP update and run with specified test iterations. Graph Execution Control
C++ template example An example demonstrating C++ templated data types and state encapsulation. C++ Template Support
GMIO Bandwidth A graph to demonstrate GMIO performance profiling. GMIO Attributes
Mapping Placement A templated graph with relocatable mapping and location constraints for kernels. Location Constraints
Shim Constraints A graph to demonstrate physical channel allocation constraints on the AI Engine to PL interface boundary. AI Engine/Programmable Logic Integration
Simple A simple 2-kernel graph with window based data communication. Window-based Access
Simple 128 Bit Interface A graph to demonstrate 128-bit interface between the AI Engine and PL. PLIO Attributes
Simple 64 Bit Interface A graph to demonstrate 64-bit interface between the AI Engine and PL. PLIO Attributes
Simple Bypass A graph demonstrating the use of bypass for kernels. Kernel Bypass
Simple Chained A simple 2-kernel graph with triggered array parameter communication between the kernels. Chained Updates Between AI Engine Kernels
Simple Margin A graph demonstrating the use of margin in windows (overlapping windows). Window-based Access
Simple Packet Split Merge A graph to demonstrate simple split and merge of packet stream data. Explicit Packet Switching
Simple Param A simple 1-kernel graph with scalar parameter update using external trigger. Specifying Run-Time Data Parameters
Simple Single Buffer A graph demonstrating single buffer constraint on connections. Buffer Allocation Control
Single Node Graph A simple single node graph with demonstration window (single buffer and double buffer), stream and RTP array connections. Single Kernel Development
Stream Switch FIFO A graph to demonstrate use of stream switch FIFO to avoid deadlocks with reconvergent streams. FIFO Depth

Building the AI Engine Graph

Take a look at your project in the Assistant view. It initially includes three projects: the top-level system project that is created by the Vitis IDE when you define an application project, the application project itself, and a hw_link project that links the AI Engine domain and the PL region domain into a single device binary (XCLBIN) or platform file (XSA).

The application project in this case is your AI Engine graph application. When you created the graph project, the Vitis IDE created the top-level system project, and the hw-link project, which is discussed further in Configuring the HW-Link Project.

Expand the AI Engine graph application project to see that it contains three build targets:

Emulation-SW
The functional simulation build target. Compiled by the AI Engine compiler, run in the x86simulator.
Emulation-AIE
The hardware emulation build. Compiled in the AI Engine compiler, and run in the AI Engine SystemC simulator (aiesimulator).
Hardware
The hardware build, compiled by the AI Engine compiler for use in the actual device.

All of these build targets are built by the AI Engine compiler tool as described in Compiling an AI Engine Graph Application, and simulated by the AI Engine simulator or the x86simulator as described in Simulating an AI Engine Graph Application.

If you select one of these build targets in the Assistant view, and select the Settings command (), you can see that there are no build settings for the compiler. The Vitis IDE configures the AI Engine compiler as required for the build.

Build the target by making it active in the Assistant view, or the Project Editor view, and click the Build icon ().

Viewing Microcode

After the build is complete, you can view the microcode produced by the AI Engine compiler by right-clicking the project in the Explorer view and selecting Open Disassembly View. In the Select Active Core dialog box, select the core (AI Engine). This opens the LST (.lst) file which is microcode that corresponds to the kernel code scheduled to be executed on that AI Engine tile. The kernel code is embedded in the LST file after the main end function. You can select parts of the microcode and cross-probe to the corresponding line in the kernel source file. This allows you to examine the number of cycles taken by specific lines of kernel code and see where further optimizations and efficiencies can be made. In the following image you can see the microcode in the LST file in the center left and the corresponding kernel code file to the right. Clicking in either view shows the corresponding code in the other view.

Figure 2: Cross-Probe View


Running and Analyzing the Graph

After the build is successfully finished, you can run the Emulation-SW build, or Emulation-AIE build in the Vitis IDE. You can examine various reports generated by the compiler and simulate your design. For the hardware build, you can copy the SD card output for instance and then use it to boot and run the application on the hardware card.
  1. In the Assistant view expand a specific build target, right-click the Compile Summary (graph) and select Open in Vitis Analyzer. This opens the Compile Summary report as described in Viewing Compilation Results in the Vitis Analyzer.
  2. Find additional compiler-generated reports in the Explorer view by navigating from your project and select Emulation AIE > Work > Reports.
  3. To run the program for hardware emulation, in the Assistant view click the Run button () and select Run Configurations. This opens the Run Configurations dialog box to create a new run configuration or edit an existing one as shown.

    • You can specify a name for the configuration, which allows you to create multiple configurations to apply at different times, or to different build targets as your design flow progresses.
    • You can enable Generate Trace, and enable event trace for the emulation build using --dump-vcd in the AI Engine simulator. See Performance Analysis of AI Engine Graph Application for more details.
    • You can enable Generate Profile to specify the --profile option in the AI Engine simulator and trigger a profile for all AI Engine processors or selected tiles. Reports are generated in the project ./Emulation-AIE/aiesimulator_output directory.
      TIP: Clock cycle count reports are generated with this option enabled for the selected tiles.
    • To add additional AI Engine simulator options, select the Arguments tab and enter the option as you would from the command line.

    When ready to run emulation, select Apply > Run.



  4. To debug the program, right click on the application and select Debug As > Launch AIE Emulator. The simulator starts in debug mode with the AI Engines stopping at their respective main(). You can set breakpoints, single-step, and resume execution, as well as examine registers, local variables, and memory data structures. See Hardware Emulation Debug from the Vitis IDE for more information.


Single Kernel Development

To achieve the highest performance on the AI Engine, the primary goal of single kernel programming is to ensure that the use of the vector processor approaches its theoretical maximum. Vectorization of the algorithm is important, but managing the vector registers, memory access, and software pipelining are also required. Because the vector processor is capable of an operation every clock cycle, the programmer must strive to make the data for the next operation load during the current operation. When implementing an algorithm for the AI Engine, it is important to start vectorization based on the data types and the vector intrinsic functions that operate on those data types. Depending on the data type, the various intrinsic functions operate on two or more elements at the same time. When the inner loop has sequential or loop carried dependencies it might be possible to unroll an outer loop and compute multiple values in parallel. There are many creative ways to use the vector intrinsic functions to solve problems. When implementing an algorithm for a Versal™ ACAP, it is important to understand what the AI Engine does well and what would be better implemented in the other engines, for example, the Scalar, Adaptable and DSP engines.

To support AI Engine single kernel development, the Vitis IDE supports AI Engine kernel development in addition to traditional processor support. The Vitis IDE provides a single node graph example that can be used as a starting point for single kernel development. The Vitis IDE has a debug view which displays registers, variables, available breakpoints, variables to register/memory mapping, internal/external memory contents, and an instruction pipeline (pipeline view) for each individual kernel.

TIP: Clock cycle count reports are generated with the --profile option enabled after the emulation run.

Adding a PL Kernel Project to the System

After creating the AI Engine graph project, which also creates the top-level system project, and a hw-link project, you can create PL kernel projects to add your system. You need to create a PL application project and add it to your system project using the following process.
  1. In the Explorer view, select the top-level system project to create a new PL project to add to it. Right-click on the system project and select the Add Hw Kernel Project command, as shown in the following figure.

  2. This displays the Hw Kernel Project Details page of the New Vitis IDE Project wizard as shown in the following figure.

    Make sure the project is assigned to the existing system project, which also contains your AI Engine graph project. Specify the HW Kernel project name. Click Next to proceed.

  3. This creates the PL kernel project and adds it to the hierarchy of the top-level system project. Next you must add the source code for your kernel. In the Explorer view, select the src folder of the PL kernel and click the Import Sources command () to open the dialog box shown in the following figure.

    Browse to and select the necessary source files for your PL kernel. Click Finish to import the source files to your HW kernel project.

  4. With the source files added to the project, you must define the HW function to place into the PL region. In the Project Editor window, select the Add Hardware Function command () and specify the name of the function to implement in the PL region.
With the PL kernel project created and the HW function defined, you can build the kernel project for the Emulation-SW, Emulation-HW, or Hardware targets. You can build these targets directly in the PL kernel project or as part of building the top-level system project. The top-level project uses an incremental build approach that recognizes the state of the sub-projects and only rebuilds projects that need to be updated.

Configuring the HW-Link Project

With the various domain application projects added to the top-level system project, only the connections between the AI Engine graph and the PL kernels need to be defined using the hw_link project. This project is automatically generated during the creation of the AI Engine graph project.

  1. Open the hw_link project by double-clicking on the project in the Explorer view. Right-click on the binary_container in the Hardware Functions window, and select the Edit V++ Options command.

  2. Edit the V++ Options field. It is important to add the correct path to the config file because the v++ command needs it for the Vitis IDE workspace.

  3. Import the specified config file into the hw_link project folder.

    TIP: The system configuration file is added to the hw_link project folder and not to a src folder.

    As explained in Linking the System, for AI Engine graph applications the Vitis compiler needs some instruction on how to connect PL kernels to the graph. The number of kernels to be instantiated is already configured in the IDE. However the definition of the connections between the PL kernels and the graph must be specified.

    For the Vitis IDE the following is an example configuration file:

    [connectivity]
    stream_connect=mm2s_1.s:ai_engine_0.DataIn1
    stream_connect=ai_engine_0.clip_in:polar_clip_1.in_sample
    stream_connect=polar_clip_1.out_sample:ai_engine_0.clip_out
    stream_connect=ai_engine_0.DataOut1:s2mm_1.s
    [advanced]
    param=compiler.addOutputTypes=hw_export

The connectivity sc option defines connections between the ports of the AI Engine graph and streaming ports of PL kernels. Connections can be defined as the streaming output of one kernel connecting to the streaming input of a second kernel, or to a streaming input port on an IP implemented in the target platform.

The system.cfg file has some differences between the Vitis IDE and the command-line flow as described in Linking the System. The primary difference is that the IDE provides the connectivity nk options of the config file, instantiating a specified number of compute units (CUs) per kernels, as specified in the build settings. In addition, the IDE uses a naming convention for CUs in the form <kernel>_#, where # indicates the CU instance. In the case where there is only one CU instance, it has the _1 extension. This means that for the Vitis IDE, the system.cfg should not specify the nk option, and the sc option should use the CU instance name from the IDE.

Adding a PS Application to the System

Your top-level system project can also have an application to run in the PS domain of the Versal ACAP to load and run the AI Engine graph and PL kernels. Use the following process to create a PS application project and add it to your system project.
  1. In the Explorer view, right-click on the system project and select the Add Application Project command, as shown in the following figure.

  2. This displays the Application Project Details page as shown in the following figure.

    Make sure the project is assigned to the existing system project, which also contains your AI Engine graph project. Specify the Application project name.

    Select the Cortex®-A72 processor core, and click Next to proceed.

  3. This displays the Domain page of the project wizard as shown below.

    Because you have selected the Cortex®-A72 processor core, the XRT domain is the only available option. This indicates the domain includes the Linux operating system and the XRT library. You must also specify the following three elements of the embedded platform:

    • Sysroot
    • Root FS
    • Kernel Image

    These items are required for loading and booting the operating system and run-time drivers. These files are available from the Embedded Platforms download page. Specify the files and click Next to proceed.

  4. The Templates page opens for the PS Application project, as shown in the following figure.

    In this case, where you are creating a new PS project, select the Empty Application template (default), and click Finish to create the project. The new PS project is created and added to the top-level system project that you have been working on.

  5. Add the source code for the PS application. In the Explorer view, right-click the src folder of the PS project and click the Import Sources command (). Browse to and select the necessary source files for your PS application. Click Finish to import the selected source files.
  6. Add include directories, link libraries, C++ standard, and build configurations, as required, by right-clicking on the PS project and selecting C/C++ Build Settings. You can configure the project properties for the PS project.

With the PS application project created, as well as the AI Engine graph and the PL kernels, your top-level system project is almost ready to build from the top-down.

Building and Running the System

With the top-level system project defined, the AI Engine graph application added, the PL kernels added, the PS application added, and the HW-Link project configured, you are now ready to build and run the system.

The system project supports two different build targets: Emulation-HW and Hardware. You can build the top-level system project using the following steps:

  1. Double-click the <project>.sprj file in the Explorer view to open the system project in the editor area.
  2. Set the Active build configuration in the Project Editor window to either Emulation-HW or Hardware to select a specific build target.
  3. In the Assistant view, select the top-level project and click the Settings command () to display the System Project Settings dialog box and make any needed changes prior to the build.
  4. Click the Build command () in the toolbar menu to start the build process for the active build configuration. The build process in the Vitis IDE is incremental and will only build elements of the project that have been updated and need to be rebuilt after the last build. You can build the individual elements of the system project, such as the AI Engine graph or PL kernels, and the tool recognizes whether these elements need to be rebuilt.
    Note: The build process for hardware takes considerably longer to run than the build for emulation. This is why it is important to debug your design in the emulation build before moving on to the hardware build.
  5. When the build completes, examine the contents of the Emulation-HW or Hardware build folders in the Explorer view. You can select and expand the folders of the build directories. You can see the output files of the Vitis compiler package process (v++ --package) in the output hierarchy. The build process generates the emulation data and boot files needed for the system, and writes them to the sd_card folder.
    Note: Two folders are created under the Hardware folder, package and package_no_aie_debug. The sd_card.img file within the package folder is for hardware debug purposes whereas the sd_card.img file in the package_no_aie_debug folder is for regular application execution.
    IMPORTANT: In an AI Engine system project you can debug and run the system-level project, or debug and run the AI Engine project. You cannot debug and run the PS or PL projects except as part of the top-level system project.
  6. For hardware emulation builds, start the QEMU emulation environment by selecting the Xilinx > Start/Stop Emulator command.

    This launches the emulator and then waits until Linux is booted within the QEMU. The Emulation console shows a transcript of the QEMU launch and Linux boot process. You can tell when the process has completed when the progress dialog closes and the qemu% prompt is black. You can examine the transcript for details of this process.

    When launching hardware emulation, you can specify options for the AI Engine simulator that runs the graph application, as described in Simulator Options for Hardware Emulation. The options can be specified in the Emulator Arguments field shown in the preceding figure by specifying the following command:

    -aie-sim-options ../aiesim_options.txt
  7. From the Run Configurations dialog box, select Run to proceed.

Building a Bare-metal AI Engine in the Vitis IDE

Building a bare-metal system requires a deviation from the standard application flow previously described. The branch in the process occurs at the Configuring the HW-Link Project step, with the bare-metal system requiring an addition to that step and then following a new process. The specific steps required are detailed below.
  1. For bare-metal systems you must follow the process described in Configuring the HW-Link Project with the added step of enabling the Export Hardware (XSA) option for Emulation-HW and Hardware builds. This triggers the creation of a fixed-XSA file used for building a bare-metal platform using data found in the AI Engine graph and PL regions of the design.
    IMPORTANT: The fixed-XSA matches the specified build target of the Vitis compiler. So a hardware emulation capable fixed-XSA is generated from the hw_emu build target, and a hardware capable fixed-XSA is generated from the hw build target.
    After enabling this option, build the emulation or hardware build as usual. The fixed-XSA file will be written to the output folder for the build.

  2. Create a bare-metal platform. Building bare-metal applications requires a platform with a bare-metal domain. Because the xilinx_vck190_base_202110_1 base platform does not have one, you must create a custom platform with a bare-metal domain using the fixed-XSA file exported during the build process described above.
    1. Select the File > New > Platform Project command in the Vitis IDE. This opens the New Platform Project wizard as shown.

    2. Specify a Platform project name and click Next to proceed. This displays the Platform page of the wizard where you specify an XSA to create the new platform. Use the binary_container_1.xsa exported from the HW_Link project as described in Step 1.

    3. After you select the XSA, the Vitis IDE reads the file, determines the Operating system and Processor for the domain defined by the XSA, and populates it in the dialog box. Click Finish to create the platform project.
      TIP: The bare-metal platform is valid for either hardware emulation or hardware builds depending on the fixed-XSA selected for the platform.
    4. Click the Build command to build the platform. A copy of the completed platform is written to the export folder of the project, and shows in the Explorer view for the project. As shown in the following figure, the exported platform has the platform.xpfm meta-data file, as well as the ./hw and ./sw folders for the different elements of the platform.

    The Vitis IDE automatically adds the new platform to your platform repository making it available to use in new projects. You can also add the file location to your $PLATFORM_REPO_PATHS environment variable. This makes the platform accessible to the Vitis IDE, or allows you to specify the platform in command-lines by referring to the platform name rather than the whole path.

    IMPORTANT: The generated platform will be used only for building the bare-metal PS application and is not used any other places in the flow.
  3. Create a new PS application project.
    1. Select the File > New > Application Project command in the Vitis IDE. This opens the New Application Project wizard.
    2. Click Next to skip past the first page, and display the Platform page as shown.
    3. Select the baremetal_platform you created in the last step, and click Next to proceed.

    4. Provide an Application project name and click Next.
    5. Review the Domain page and click Next to proceed.
    6. On the Templates page, select Empty Application and click Finish to create the project. The project is opened in the Vitis IDE.
    7. Add the source code for the PS application, main.cpp, platform.cpp, and associated files written specifically for the bare-metal project. Select the project in the Explorer view, expand the folders, right-click the src folder, and click the Import Sources command () to open the dialog box shown in the following figure. Select the files to add and click Finish.

    8. You must also add the bare-metal AI Engine control file (aie_control.cpp), which is created by the aiecompiler command, and can be found in the ./Work/ps/c_rts folder. Select the src folder again, and click the Import Sources icon () to open the dialog box and add the aie_control.cpp file to the project.
    9. Finally, you must add to the Include paths for your project. Right-click the bare-metal application project and select C/C++ Build Settings as shown.

      This selection opens the Build Settings dialog box, as shown in the following figure. Select the Directories option as shown, and select the Add command () to add the new include paths. You will need to add an entry for the source files for your original AI Engine graph application. This is the src folder for the project described in Creating the AI Engine Graph Project and Top-Level System Project. This should point to a folder containing your AI Engine graph source files. Click Apply and Close to finish defining the include path.



      With the updated Include path, select the Build () icon to build your project. When the build completes, you should see the ELF file for your bare-metal application.



  4. Package the system.
    1. With the ELF file produced for the PS application, you are ready to build the system-level project, and package the system for the bare-metal platform. You must run the package process to generate the final bootable image (PDI), and write the SD card content for booting the device and running the application. See Packaging for more information.
    2. In the system project created that was created when you set up your AI Engine graph project as discussed in Creating the AI Engine Graph Project and Top-Level System Project, add the following to the Packaging options field:
      --package.ps_elf ../../baremetal_app/Debug/baremetal_app.elf,a72-0
      Note: For debugging both the AI Engine graph, together with the bare-metal PS application, you should not add the --package option specified in the previous example. If you want to debug only the AI Engine graph, then you need to add the option as described.
    3. For the hardware build of the bare-metal application system project you need to specify an XCLBIN file for the project in the Packaging options field as shown in the following figure.
      TIP: You can copy or reference the required file from the top-level system project, which is the source of the fixed-XSA described in Step 1.
    4. Now build () the top-level system project.

      This adds the ELF file you created in the bare-metal application project, assigns it to a processor core, and builds the system project. See the --package option in the Vitis Compiler Command in the Application Acceleration Development flow of the Vitis Unified Software Platform Documentation (UG1416) for more information.

      Note: In the Linux system, you added a PS application into the system project to build and debug as part of the system. Here you are building the PS application as part of a separate bare-metal project and adding it as a boot file for the package process in your top-level system.
Now that you have built the bare-metal system, you can continue to run or debug the application.
IMPORTANT: You cannot debug the hardware emulation build for bare-metal projects in the Vitis IDE.

Programming Device and Flash Memory

The Vitis IDE has a feature for programming the board/part using JTAG, allowing you to bypass the need to copy the contents of sd_card to an actual SD card to boot on the board.

Programming Flash

After successfully building a design for hardware, right-click System Project and select Program Flash. You should see a dialog box similar to the following:

Figure 3: Program Flash Memory Dialog Box

In this screen specify the Image File, which is generally the BOOT.BIN, any offset (if necessary for the flash memory), as well as the Init File. The Init File is the partial PDI from the platform you are targeting. To make sure the flash is programmed properly, check the Verify after flash check box to confirm it was programmed properly. If the flash memory already has existing data, you can do a more secure erase by checking the Blank check after erase check box to make sure it is fully erased before programming.

Make sure that the Packaging options in the System Project Settings window has --package.boot_mode=qspi set.

Programming the Device

If you do not want to program the flash memory and just want to program the device through JTAG, there is an option under the Xilinx menu to select Program Device.