Using Digilent Pmod IPs in Vivado and Vitis (Under Construction)

Under Construction

This guide has only been partially tested in Vivado and Vitis 2020.1. Not all Pmod IPs have been updated for 2020.1. Use at your discretion. No timeline is currently available for when this guide and all Pmod IPs will be updated.

Overview

This guide will work you through the process of setting up a project to use a Pmod IP core. These cores provide a simple way to interface between a processor and a Pmod, by way of an AXI connection. While this guide only covers the use of a single Pmod IP, the same workflow can be extended to create a design that uses multiple Pmods, your own custom hardware components, and the board's other peripherals. By the end of this guide, you will have created a design in both hardware and software that supports a Pmod and console-based standard output.

Note: Screenshots presented in this guide may not have been taken with your version of the tools. The workflow presented here has been verified in Vivado and Vitis 2020.1. While there are some differences between 2020.1 and older versions of the tools, screenshots taken in 2019.2 have been checked, and contain the same user interfaces that are seen in 2020.1.


Inventory and Design Requirements

  • A Digilent FPGA Development Board
    • USB Programming cables, USB UART cables, and Power Supply, as required by the board.
  • Vivado and Vitis installations
  • One or more supported Digilent Pmods
    • See the Pmod IP Design Requirements tables for more information on which Pmods are supported by a Pmod IP core. Keeping this page open in another tab while following this guide is recommended, as additional design requirements of your Pmod/s are included.

Guide

Launch Vivado

Select the dropdown corresponding to your operating system, below.

Windows

Open Vivado through the start menu or desktop shortcut created during the installation process.

Linux

Open a terminal, and change directory (cd) to a folder where log files for your Vivado session can be placed, then run the following commands:

source <install_path>/Vivado/<version>/settings64.sh
vivado


Create a Vivado Project

In Vivado's welcome screen, several options are presented:

  • Create Project: Opens a wizard used to begin creating a Vivado project from scratch, which will be used here.
  • Open Project: Can be used to open a Vivado project (defined by an XPR file) that has been previously created or downloaded from the internet.
  • Open Hardware Manager: Can be used to program an FPGA development board with a bitstream, without opening the associated project.

Note: Various other options are available, but are not described here.

For the purposes of this guide, click the Create Project button.


The first page of the New Project wizard summarizes the steps involved in creating a project. Click Next.


The first step is to set the name for the project. Vivado will use this name when generating its folder structure.

Important: Do NOT use spaces in the project name or location path. This will cause problems with Vivado. Instead use an underscore, a dash, or CamelCase.

Pick a memorable location in your filesystem to place the project.

Checking the Create project subdirectory box will create a new folder in the chosen location to store the project's files. This is recommended.

Click Next to continue.


At the Select Project Type screen, choose RTL Project and check the Do not specify sources at this time box. Advanced users may want to use the other options on this screen, but they will not be covered here.

Click Next to continue.


Next, a part or a board must be chosen for the project to target. The project will only be usable with the chosen device (though the selection can later be changed through the project's Settings).

Selecting a board over a part is recommended, as the board files provide additional configuration information for a variety of peripherals and components in a design. Click the Boards to open the board tab.

Search for your board and select it from the list.

Important: If your board does not appear in the list, Digilent's board files have not been installed. Review Installing Vivado, Vitis, and Digilent Board Files for instructions on installation of these files.

Click Next to continue.


Important: If you have Vivado 2022.2, there is an extra step to Refresh the list and install the target board.

Click Next to continue.


The last screen of the New Project wizard summarizes what was chosen in the previous screens. Click Finish to open your project.


Add Digilent's Vivado Library to a Vivado Project

First, download and extract the master.zip ZIP file.


Open the project settings, by clicking the Settings button in the Project Manager dropdown of Vivado's Flow Navigator pane.


In the window that pops up, navigate to the Project Settings → IP → Repository screen. Click the Add button to add a new IP repository to the project.


Navigate to your copy of vivado-library, click it to highlight it, and click the Select button.


The dialog that opens lists all of the IP cores and interfaces that were added to the project. Click OK to continue.


Your copy of vivado-library will now be displayed in the list of IP Repositories. Note: If vivado-library is later changed (while the project is open), the Refresh All button can be used to detect any changes and reload the set of IP definitions that the project has access to. Click the OK button to save the changes to the project settings.

Create a Block Design

Click the Create Block Design button in the IP Integrator dropdown of Vivado's Flow Navigator pane. A block design provides a visual representation of your hardware design, and can be used to easily connect and configure IP cores.


In the dialog that pops up, give your block design a name (or use the default “design_1”).

Important: Do NOT use spaces in the block design name. Instead use an underscore, a dash, or CamelCase.

The other two fields should be left as defaults. Directory can be used to place the block design's source files outside of the project directory, and Specify source set can be used to create block designs that are not part of the normal Design Sources, which are used to build the project.

Click OK to continue.

Add a Processor to a Block Design

The process of adding a processor to your design is very different depending on the processor used. The Microblaze dropdown should be selected only if using a board that does not have a Zynq device.

Add a Microblaze Processor to a Block Design

The Microblaze soft-core processor IP can be used to instantiate a processor within your FPGA design. This processor can be very useful for controlling and configuring hardware components. This section discusses how you can add a Microblaze processor and several useful components, including UART for standard output and DDR memory support, to your block design.

Note: This section is intended for use with boards without a Zynq chip. For Zynq boards, the Zynq7 Processing System should be used instead.

Note: If you aren't sure whether your board has DDR memory, check the Memory column of the specification table on this site's Programmable Logic page.

Follow the steps in this dropdown for boards without DDR memory

First, an external clock should be added to the block design, so that it can be used to generate any other clocks required by the design. Open the Board tab, and find the system clock. Right-click on it and select Connect Board Component.


In the Connect Board Component dialog, select the CLK_IN1 of a new Clocking Wizard IP. This will add a clocking wizard to the design, which can be used to easily configure the board's MMCMs and PLLs to generate any required clocks. Click OK to continue.


Next, an external reset port should be added to the design that can be used to reset the entire system. Click the Run Connection Automation button in the green Designer Assistance toolbar.


In the Run Connection Automation dialog, in the list on the left side of the dialog, make sure that the Clocking Wizard's reset box is checked. The Select Board Part Interface dropdown lists any options for resets that are specified in your board's board files. For most boards, only one option will be available. Click OK to continue.


Note: Depending on the polarity of the reset button (active high or active low), a Utility Vector Logic IP may be inserted between the reset port and the Clocking Wizard. This is used to ensure that the active high reset pin of the IP is provided with the correct polarity of reset signal, and that the design will not be held in reset while the reset button is not pressed.


Your design will require at least one clock from the clocking wizard. If your design requires more clocks, then they must be added through the Clocking Wizard.

Double click on the Clocking Wizard IP core to edit its settings. Navigate to the Output Clocks tab. Additional clocks are added to the Clocking Wizard by checking a box in the Output Clock column, and specifying a Requested Output Frequency. Additionally, if desired, the ports can be named according to their intended purpose.

If your design requires additional clocks (such as for an ext_spi_clock pin), they should be added now.

Click OK to confirm your changes to the Clocking Wizard's settings.

If you aren't sure that you have all of the clocks you need, don't worry, you can always come back and add them by reconfiguring this IP. This task can be performed whenever in the design process it becomes necessary.


Next, use the Add IP button () to add the MicroBlaze IP to the design. The block that is added represents the core of the Microblaze processor.


Next, block automation will be run so that additional supporting infrastructure can be added to the design. Click Run Block Automation in the green Designer Assistance bar.

Note: The screenshot to the right is not representative for a design not using DDR, as these designs will not contain a MIG IP core.


In the Run Block Automation dialog, several settings can be specified for how the Microblaze IP will be connected to the rest of the design:

  • Local Memory specifies how much block RAM memory will be dedicated to the processor. DDR-less designs require more memory, and the amount of memory necessary depends heavily on the size of the software application being run. 32KB is enough for many small applications.
  • Cache Configuration can help the speed of designs using DDR memory. It should be enabled when using DDR and disabled otherwise.
  • Debug Module allows you to specify the capabilities of the debugger. The default Debug Only option is recommended.
  • Peripheral AXI Port enables or disables the AXI master interface of the processor. It must be enabled to allow the processor to be connected to hardware peripherals.
  • Interrupt Controller specifies whether the processor can be interrupted by its peripherals. Whether or not it needs to be enabled depends on your design requirements. If any IP that you intend to connect to the processor must have interrupts to function correctly, the box must be checked.
  • Clock Connection specifies the processor's clock. Designs using DDR should use the MIG's ui_clk pin, while designs without DDR should use the Clocking Wizards clk_out1 pin.

Note: Settings not present in this list are out of the scope of this guide, and can safely be left as their default.

Confirm that the settings meet your design requirements. It should be noted that while it is possible to change these settings manually later (for example, by manually adding an AXI INTC IP and connecting it to the processor), the easiest way to do so will be to clear the Microblaze processor out of your block design and restart the process of adding the processor. This is to say, the settings chosen here are important. Getting them right the first time will save you time in the long run.

Click OK to continue.


Next, in order for the software design to be able to print to a serial console on a host computer, a UART peripheral must be connected. Find the USB UART interface in the Board tab, right click on it, and select Connect Board Component.


In the dialog that pops up, select a new AXI Uartlite IP's UART interface, and click OK to add the block to the diagram.


To connect all remaining AXI cores that have not yet been connected to the processor, click the Run Connection Automation button in the green Designer Assistance bar. Check the All Automation box in the list on the left side of the window to select all of the remaining AXI cores. The dropdown settings available for each core can safely be left as their default values. Click OK to automatically connect them to the processor.

Follow the steps in this dropdown for boards with DDR memory

The user Viktor Nikolov posted a tutorial on the Digilent Forum with an alternate architecture for clocking the DDR interface for Digilent boards. It works around several errors that may occur in the flow presented here and is recommended for new users to go through. Digilent is considering updating this and other guides and reference material to use the revised flow. Find more information and a comprehensive guide here: https://forum.digilent.com/topic/27389-arty-a7-microblaze-ddr3-tutorial/.

When creating a design with DDR, it's best to add the DDR interface first, as it is typically also used to generate the clock or clocks that will be used by the rest of your design.

In the Board tab, right click on the DDR interface and select “Auto Connect”. This process will add a MIG (Memory Interface Generator) and the external DDR interface to the design. Two clock pins are also created, which will need to be modified.


Delete the “clk_ref_i” pin. This can be accomplished either by right-clicking on the pin and selecting delete or by selecting and pressing the delete key.


Verify that the “ui_addn_clk_0” pin has a frequency near 200 MHz by selecting it and looking at the “Frequency” value in the “Block Pin Properties” pane.


Manually connect the “ui_addn_clk_0” pin to the “clk_ref_i” pin by clicking and dragging from one to the other.


It's important to note that the “sys_clk_i” pin will not be constrained by the board files, and you will need to add a constraint file to map it to the corresponding pin location on the FPGA.

If your project doesn't contain the master Xilinx Design Constraint (XDC) file for your board, the dropdown below details how to add it. This file contains the constraints that your board places on designs using it - specific interfaces wired up to specific pins, clock frequencies, and FPGA bank voltages, for some examples. Click the dropdown below for a walkthrough of how to add this file to your project.

Add a Master XDC File to a Vivado Project

Download and extract digilent-xdc-master.zip. This file includes all of the latest template XDC files released for Digilent's boards, which are available on Github in the digilent-xdc repository.


Returning to Vivado, click the Add Sources button in the Project Manager section of the Flow Navigator pane. This will launch a dialog that you can use to add a variety of types of source files to the project (or create new ones).


On the first screen, select Add or create constraints. Click Next to continue.


In the next screen, make sure that the constraint set specified (the one that the master XDC will be added to) is set to constrs_1, and that it is the active set. Click the Add Files button.


In the dialog that pops up, navigate to the folder that the digilent-xdc-master.zip file was extracted into. Highlight the XDC file for your board, then click OK to continue.


Back in the Add Sources dialog, make sure that your chosen constraint file appears in the table. Also, make sure that the Copy constraint files into project box is checked. If this box is unchecked, the file will be linked by your project, and any modifications made within the project will affect the version you downloaded. Since you may need to use this file again in other projects, copying the constraint file is recommended, so that you can always work from a fresh copy.

Click Finish to add the constraint file to your project.


Once added, the XDC file will appear in the Sources tab (in the same pane as the Board tab). Double click it to open the file.


Find the set_property and create_clock constraints for your board's 100 MHz input clock, uncomment them by removing the # at the start of each line, and change the name of the port that they are constraining to sys_clk_i, to match the name of the port in the block design.

If your board has multiple clocks, the 100 MHz one can be determined by observing that the create_clock constraint specifies a 10.000 ns period, as seen in the screenshot to the right.

Make sure to save your changes.


Next, the MIG's reset pin will be connected to the board's reset button. Click “Run Connection Automation” in the green bar at the top of the window.


In the list to the left side of the dialog that pops up, make sure that the “sys_rst” box is checked. Click OK to connect the reset to the corresponding board part interface.


The MIG block may have other ports which will need to be connected to ensure that it works correctly. This section discusses each of those ports.

Open this dropdown if your MIG has a "device_temp_i" port

If your MIG block has a “device_temp_i” port, it means that the MIG is not using the chip's XADC analog-to-digital converter feature. We'll ground this port to prevent any warnings that it may throw. Add a “Constant” IP to the design.


Double click on the block to open it's configuration wizard and modify it to have a Value of “0” and a Width of “12”.


Connect its output port to the “device_temp_i” port on the MIG.


If your design requires more clocks than just the ui_clk provided by the MIG, you will need to add a clocking wizard IP that is driven by the MIG's ui_clk.

Use the Add IP button to search for and add a Clocking Wizard to the design.


Manually connect the Clocking Wizard's clk_in1 and reset ports to the MIG's ui_clk and ui_clk_sync_rst ports, respectively.


Finally, double-click on the Clocking Wizard to open and configure it. The third tab, Output Clocks contains all of the settings required to specify how many clocks you need, and of what frequencies. The screenshot to the right shows the wizard configured to create a 100 MHz clk_out1 and a 50 MHz clk_out2.

If your design requires additional clocks (such as for an ext_spi_clock pin), they should be added here.

Note: If you aren't sure that you have all of the clocks you need, don't worry, you can always come back and add them by reconfiguring this IP. This task can be performed whenever in the design process it becomes necessary.


At the end of this process, the block design will look something like this:



Next, use the Add IP button () to add the MicroBlaze IP to the design. The block that is added represents the core of the Microblaze processor.


Next, block automation will be run so that additional supporting infrastructure can be added to the design. Click Run Block Automation in the green Designer Assistance bar.

Note: The screenshot to the right is not representative for a design not using DDR, as these designs will not contain a MIG IP core.


In the Run Block Automation dialog, several settings can be specified for how the Microblaze IP will be connected to the rest of the design:

  • Local Memory specifies how much block RAM memory will be dedicated to the processor. DDR-less designs require more memory, and the amount of memory necessary depends heavily on the size of the software application being run. 32KB is enough for many small applications.
  • Cache Configuration can help the speed of designs using DDR memory. It should be enabled when using DDR, and disabled otherwise.
  • Debug Module allows you to specify the capabilities of the debugger. The default Debug Only option is recommended.
  • Peripheral AXI Port enables or disables the AXI master interface of the processor. It must be enabled to allow the processor to be connected to hardware peripherals.
  • Interrupt Controller specifies whether the processor can be interrupted by its peripherals. Whether or not it needs to be enabled depends on your design requirements. If any IP that you intend to connect to the processor must have interrupts to function correctly, the box must be checked.
  • Clock Connection specifies the processor's clock. Designs using DDR should use the MIG's ui_clk pin, while designs without DDR should use the Clocking Wizards clk_out1 pin.

Note: Settings not present in this list are out of the scope of this guide, and can safely be left as their default.

Confirm that the settings meet your design requirements. It should be noted that while it is possible to change these settings manually later (for example, by manually adding an AXI INTC IP and connecting it to the processor), the easiest way to do so will be to clear the Microblaze processor out of your block design and restart the process of adding the processor. This is to say, the settings chosen here are important. Getting them right the first time will save you time in the long run.

Important! When working with multiple clocks in a design (as happens to always be the case when working with the MIG) it is important to verify that you are picking the correct Clock Connection from the dropdown. In the screenshot to the right, the 100 MHz clk_out1 from a clocking wizard is chosen. You may instead wish to run your design off of ui_clk itself. Do not select the system clock input to the MIG.

Click OK to continue.


Next, the MIG's AXI interface must be connected to Microblaze's cache ports, in order to allow data to move back and forth between processor and DDR memory.

To connect the MIG's AXI interface to the processor, click the Run Connection Automation button in the green banner at the top of the block design.


In the dialog that pops up, you will be presented with several options for interfaces that can be connected to other interfaces. Both the Microblaze's IC and DC ports, as well as the MIG's AXI port will appear. You should only run connection automation for one side of the connection - the S_AXI port, as shown in the screenshot to the right. Make sure that its box is checked. Check that the Master interface is set to “/microblaze_0 (Cached)”, indicating that the microblaze local memory will act as a cache for the DDR memory, then click OK to make the connections.


Next, in order for the software design to be able to print to a serial console on a host computer, a UART peripheral must be connected. Find the USB UART interface in the Board tab, right click on it, and select Connect Board Component.


In the dialog that pops up, select a new AXI Uartlite IP's UART interface, and click OK to add the block to the diagram.


To connect all remaining AXI cores that have not yet been connected to the processor, click the Run Connection Automation button in the green Designer Assistance bar. Check the All Automation box in the list on the left side of the window to select all of the remaining AXI cores. The dropdown settings available for each core can safely be left as their default values. Click OK to automatically connect them to the processor.


Add a Zynq Processor to a Block Design

The Zynq7 Processing System IP represents the non-FPGA components of a Zynq chip, referred to as the Processing System, or PS. It must be used in a block design that wants to connect anything to the processor, and to configure PS-side peripherals, clocks, and other settings.

Note: This section only applies to boards with a 7-series Zynq chip.


In the block diagram pane's toolbar, click the Add IP button ().


In the pop up, search for and double click on ZYNQ7 Processing System.


Click Run Block Automation in the Design Assistance banner (the green bar).


In the dialog that pops up, leave all settings as defaults. Apply Board Preset should be checked.


The needs of your project may require that you change some of the default settings of the Zynq PS. To edit its settings, double click on it to open the configuration wizard.

Two specific cases are highlighted below:


The Zynq PS can generate multiple clocks that are then provided to the FPGA fabric. These clocks are referred to as FCLKs, and can be found in the Clock Configuration tab of the Zynq PS configuration wizard. They are located under the PL Fabric Clocks dropdown. They can be enabled (or disabled) with a checkbox, the hardware used to drive the clock can be changed, and the frequency can be modified.

All board files for Digilent Zynq boards enable a single Zynq PL clock by default, which is intended to be used with peripherals connected to the Zynq's M_AXI_GP0 port.

Some designs may require additional clocks of specific frequencies be added to your design. In these cases, enable a second clock and specify the needed frequency, as seen in the image to the right.

Note: This section can always be returned to later, as the addition of an additional clock can be performed any time before the hardware is built.


Zynq devices can also use interrupts generated in FPGA fabric to trigger interrupts within the Processing System. Interrupt-related settings can be changed within the configuration wizard's interrupts tab. These interrupts typically use the IRQ_F2P port, which can be found under the Fabric Interrupts → IRQ_F2P dropdown. To enable this port, both the Fabric Interrupts and IRQ_F2P ports must be enabled.


While interrupts can be directly connected to the IRQ_F2P port (by clicking and dragging from one port to another), some designs may require multiple interrupt sources. In these cases, add a Concat IP to your block design, and manually connect it to the IRQ_F2P port. Additional input ports can be added to a Concat block through its configuration wizard (opened by double clicking on the IP).


Add a Pmod IP to a Block Design

Use the Add IP () button to add the IP for your Pmod to your block design.

Check the Pmod IP Design Requirements page to determine whether your Pmod is supported. Most Pmod IPs support the Pmod that they are named after, however, there are several exceptions - for example, the Pmod LED is supported by the PmodGPIO IP.


To connect your Pmod IP to a Pmod Port, navigate to the Board tab in the pane to the left of the block diagram. Digilent FPGA board files provide Pmod interfaces in this tab. Scroll down to find a Pmod connector you want to connect your Pmod to, right click on it, and select Connect Board Component.

Important: The Pmod connector you select here is the one that you must connect it to when running the design on your board.


In the dialog that pops up, select your Pmod IP's Pmod_out interface under the Connect to existing IP dropdown, then click OK.


Click Run Connection Automation in the green Designer Assistance bar. This will allow you to easily connect the Pmod's AXI interface/s to your processor.


In the dialog that pops up, make that each box corresponding to your Pmod IP's AXI interfaces is checked.

Review the Clocking Requirements for Pmod IPs Table. If your Pmod IP specifies requirements for its AXI clock frequency, use the Clock source for Slave interface dropdown to select an appropriate clock. If an appropriate clock is not present in the design, you may need to return to the Add a Processor to a Block Design section of this guide.

Click OK to continue. This process will add several additional IP to the block design, including an interconnect, that can be used to route multiple AXI connections, and a processor reset system, which is used to synchronize reset signals for AXI IP.


If all ports on your IP are now connected to something (in the diagram's Default View), you are done, and can skip to the next section.


If your Pmod IP has an ext_spi_clk port, it should be connected to an additional clock of a frequency specified in the Clocking Requirements for Pmod IPs Table. Adding additional clocks to your design was discussed previously, in the Add a Processor to a Block Design section of this guide.

If your Pmod IP has one or more interrupt ports, they can be connected to your processor's interrupt system. Review the Interrupt Requirements for Pmod IPs Table to determine whether an interrupt pin is required to run the software example for your Pmod. Enabling or adding interrupt support to your processor was discussed previously, in the Add a Processor to a Block Design section of this guide. Interrupts that are not required can safely be left disconnected.

Each of these connections must be manually made by clicking and dragging from one pin to another. Pictured is a 50 MHz output clock being connected to a Pmod ACL2's external SPI clock.


Edit the Address Map

In the unlikely event that Vivado fails to correctly assign addresses to each AXI IP connected to your processor, you may need to manually set their addresses. If this occurs, errors will pop up during validation of the block design, and the bitstream will not be able to be generated.

The Address Editor can be accessed through its tab in the Diagram pane. Addresses can be assigned to unmapped peripherals by typing the desired address into the peripheral's Master Base Address column.

It should be noted that addresses must be aligned in the memory space - for instance, an address with a range of 4K (bytes) takes up a range of 0x1000 addresses, and must have three trailing zeros. Address ranges for different segments cannot overlap.

Assigning an segment to address 0 may result in assertions in some software drivers and should be avoided.

After manually assigning addresses, the block design should be re-validated.


Validate a Block Design

Before the Vivado project can be built, the block design must be validated. This step runs an automatic check of the block design to see if there are any potential issues with it. Click the Validate Design button () in the Diagram pane's toolbar (or press the F6 key).

If the design has issues, a dialog will pop up that lists them. It should be noted that most Warnings can be ignored, as can some Critical Warnings. These issues can also be viewed in the Messages tab of the pane at the bottom of the window.

If there are no issues, a dialog will pop up that will tell you so. Click OK to continue.

Note: Some Zynq boards may produce critical warnings at this stage relating to PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY parameters. These warnings are ignorable and will not affect the functionality of the project. See the Hardware Errata section of your board's reference manual for more information.


Create an HDL Wrapper

Additionally, an HDL wrapper must be created for the block design. This process translates the block design into a source file that can be read by the Vivado tools, and is used to build the actual design.

Open the Sources pane and locate the block design file (.bd) under the Design Sources dropdown. Right click on it and select Create HDL Wrapper.

In the dialog that pops up, you can decide whether to let Vivado edit the wrapper file itself. Let Vivado manage wrapper and auto-update is recommended, as a user rarely needs to manually edit the wrapper file. Click OK to continue.


Build a Vivado Project

At this point, the Vivado Project is ready to be built, by running it through Synthesis and Implementation, and finally generating a bitstream. Click the Generate Bitstream button in the Program and Debug section of the Flow Navigator pane at the left side of the window.


A dialog will pop up with several options for how Synthesis and Implementation should be run. Most should be left as defaults. Of particular importance is the Number of jobs dropdown, which is used to specify how much of the resources of your computer should be dedicated to the build. A larger number of jobs will dedicate more resources, which will allow the build to be completed faster. It is recommended to choose the highest available number.

Note: Critical warnings about how IPs included within another IP were packaged with a different board value can be safely ignored. The same is true for warnings related to negative CK-to-DQS delays seen on some Zynq boards.

Depending on the complexity of the design, the board used, and the strength of your computer, the process of building the project can take between 5 and 60 minutes.


When complete, a dialog will pop up that presents several options for what to do next:

  • Open Implemented Design can be used to view the actual hardware design that has been implemented and will be placed onto the chip.
  • View Reports can be used to view additional information about the design, including how much of the resources of the FPGA will be used by the design.
  • Open Hardware Manager can be used to go directly to Vivado's Hardware Manager, which can be used to program a hardware design onto a board. This is typically used for designs that do not involve a software component.
  • Generate Memory Configuration File can be used to create a file for programming an FPGA-only design into flash memory.

If none of these options are desired, click Cancel to continue.


Export a Fixed Post-Synthesis Hardware Platform

Once the project has been built, the design must be exported from Vivado so that Vitis has access to information about the hardware that a software application is being developed for. This includes the set of IP connected to the processor, their drivers, their addresses, and more. Exporting hardware after the bitstream has been generated allows you to program your board directly from within Vitis.


To export the hardware design, click Export → Export Hardware in the File menu.


The wizard that pops up guides you through the options available for hardware export. The first screen allows you to select a Fixed or Expandable platform. In this case, choose a Fixed platform and click Next to continue.

This screen is not present in Vivado 2022.1, proceed to the next


The Output screen allows you to select whether only the hardware specification (Pre-synthesis) should be exported, or whether the bitstream should be included. Since the bitstream has already been generated, it should be included in the platform so that Vitis can automatically figure out where it is when programming a board. Select Include bitstream and click Next to continue.


The Files screen gives you the option to choose a name for the Xilinx Shell Architecture (XSA) file, and provide a path to a folder that the file will be placed within. Give your XSA file a name, and choose a memorable location to place it in. This file will later be imported into Vitis, so take a note of where it is placed and what it is called.

Important: Do not use spaces in the file name or export path. Underscores or camelCase are recommended instead.

Click Next to continue.


The final screen of the wizard summarizes the options you selected. Click Finish.


Launch Vitis

Select the dropdown corresponding to your operating system, below.

Windows

Open Vitis through the start menu or desktop shortcut created during the installation process.

Linux
Open a terminal and run the following commands. The install path is /opt/Xilinx by default.
source <install_path>/Vitis/2020.1/settings64.sh
vitis

Note: Regardless of OS, if Vivado is open, Vitis can also be launched through the Tools → Launch Vitis toolbar option.


Upon launching Vitis, a dialog will appear where a workspace must be chosen. The workspace is the directory where all of the projects and files for the application being developed will live. If a folder that does not currently exist is chosen, it will be created. Choose a workspace and click Launch to finish launching Vitis.


Create a New Application Project for Pmod Example Software

Check the Programming Language for Pmod Software Examples table to determine which programming language the example was written in.


With Vitis open, an application project must be created to hold your source files. In creating an application project, a hardware platform will also be created from an XSA file previously exported from Vivado.


On Vitis' welcome screen, click Create Application Project. The wizard that launches will be used to create and configure a new application.


The first screen of the wizard is a welcome page, which summarizes what each of the components of a software design are. Click Next to continue.


Next, the platform that the application targets must be created. Open the Create a new platform… tab.


Browse your file system to find the Xilinx Shell Architecture previously exported from Vivado. With the XSA file highlighted, click Open to select it and return to the Platform screen of the wizard.


Once you have found the XSA file and opened it, make sure that it is selected in the Hardware Specification list. Give your platform a name (the default uses whatever the name of the XSA file is and will work fine). The Generate boot components box can be used to automatically build all of the additional components necessary to boot the application from flash memory or an SD card. Leaving this box checked is recommended. Click Next to continue.


The next screen is used to set some options for the application project and the system project. The names of both projects can be set, as well as which processor core will be used to run the application. All settings can be left as defaults. Click Next to continue.

Note: A system project can contain multiple application projects, which can all be run at once.


Next, the domain that the application project operates in will be defined. In this case all default settings will be used. Click Next to continue.


Lastly, a template project will be chosen. Each template pre-configures the application project for a different purpose. Depending on the whether your application will be written in C or C++, choose Empty Application or Empty Application (C++). You will be adding an example main source file later, as opposed to working from and editing an example.

Click Finish to finish creating the project.


Add a Pmod Software Example to an Application Project

Pmod IPs provide software examples, as well as the drivers necessary to control the IPs through an AXI interface. The example files can be found in the platform (“_wrapper”) project's hw/drivers/<pmod>/examples folder. Some IPs provide multiple examples to work from. Multiple examples may be provided as multiple (single) files in the examples folder, or as subfolders which contain multiple files for each example. Use your judgement to determine which files are needed for the example.


Copy and paste the necessary files from the examples folder into your application project's source folder, which is located at <system project>/<example project>/src.

Once the example has been pasted, it can be opened, reviewed, edited, and extended as necessary to fit your needs.

Note: If you want to modify the drivers, they should be edited within a domain's libsrc folder, rather than in the hw/drivers folder, as they are copied out of the drivers folder automatically before the user has a chance to edit them. Projects with multiple domains may require that the drivers be edited within each domain. Additionally, users should take care to copy any edited files out of the platform prior to resetting BSP sources, as this may overwrite any changes that have been made.


Build a Vitis Application

Once an application project has been set up and includes all necessary sources, it should be built. To build the project and all of its dependencies, select the [System] project in the Assistant pane, and either click the Build button (), or press Ctrl-B on your keyboard.

Note: There are three types of build targets in the Assistant pane, Platforms, Systems, and Applications. Building the application will not trigger any other applications in the system to be built, but will build the wrapper as a dependency. Building the platform will only build the platform, as it has no dependencies. Building the system causes each application in the system, as well as the platform, to be built.

This process may take several minutes to complete. When done, the Console tab at the bottom of the window will display a “Build Finished” message.


It's time to program the application project onto your board! Plug your board into your computer through its USB programming and USB UART port/s, connect an external power supply (if necessary), and turn on the board.


Launch a Vitis Baremetal Software Application

Make sure your board is set to boot from JTAG before it's powered on. JTAG programming can override other boot modes on some devices, but it's easier to tell when a project is programmed into the board if there isn't already one in there.

First, many applications require that a serial console is connected to the board, so that standard output (from print statements) can be viewed. For this purpose, a serial terminal should be used. Use a serial terminal application to connect to the board's serial port. Unless otherwise stated, Zynq designs use a baud rate of 115200 and Microblaze designs with an AXI UART Lite IP use a baud rate of 9600. Flow control should be set to NONE.

Note: While Vitis has a built in serial terminal included in its Debug view, it sends characters to a board on a line-by-line basis. Some software examples require the use of character-by-character reception of data. Tera Term or PuTTY are recommended if you are not sure what will work.


In the Explorer pane at the left side of the screen, right click on the application or system project that is to be run, and select Run as → 1 Launch on Hardware (Single Application Debug). The FPGA will be programmed with the bitstream, the ELF file created by the software build is loaded into system memory, and the application project will begin to run. You will need to click back over to the Vitis Serial Terminal from the Console tab.

Note: Once the project has been run at least once, you can use the green run button () in the toolbar at the top of the screen to program the board instead.


At this point, your application is running, and printed messages can be seen. Congratulations, you have finished this guide!!!