Recently, I upgraded to the latest version of AMD's Vitis Unified IDE with version 2023.2. With the transition from the Vitis Classic IDE that we've know from versions 2019.2 to 2023.1, to this new Vitis Unified IDE I decided a good exercise would be to re-do my getting started series on the Arty Z7 to highlight the new workflow. As usual, this getting started series is broken up into three parts with this first part covering the hardware workflow in Vivado. Then the next two highlight the software design flow in Vitis and PetaLinux.
As previously stated, the workflow in 2023.2 is different than previous versions so these tutorials are not applicable to earlier versions. Scroll through my project history to find tutorials for previous versions.
Create New Vivado ProjectLaunch Vivado and select the Create Project option from the start screen. This will bring up the project creation wizard.
Give the project the desired name and specify the desired directory. The option to Create project subdirectory simply creates another director with the specified project's name to place the project within.
On the next screen, select RTL Project for Project Type and check the option for Do not specify sources at this time. This allows for a blank/empty project to be created without needing HDL source files ahead of time.
The option Project is an extensible Vitis platform adds the hooks in the Vivado project for a hardware acceleration design (offloading software tasks into HDL to run in the programmable logic of the FPGA), and is not needed for regular FPGA designs. This tutorial is a regular design for a bare-metal/no-OS application, so I left the option unchecked.
The next screen is to select the target FPGA chip (the Parts tab) or development board (the Boards tab) for the project.
Switch to the Boards tab and type "Arty z7" in to the search bar. If no results return from the search, click the Refresh button. This will tell Vivado to pull all of the latest board files from the AMD repository on the backend (so a network connection is necessary).
Once the Arty boards show up in the search result, a little download symbol will appear in the Status column. Click the download symbol to download the board preset files for the Arty Z7 board locally. There are two versions of the Arty Z7 board, the difference being one has more programmable logic than the other. I am using the version with more programmable logic, the Arty Z7-20.
Click the row of the target Arty Z7 board, then click Next for a summary page of the project selections before launching into the project, or click Finish to launch straight into the new project.
There are two main workflows that can be followed in Vivado: the graphical IP block route with the block design, or a purely RTL design with only HDL source files specified/written by the user. The block design workflow has several helpful tools such as connection automation, so it is what I usually use.
Select Create Block Design from the Flow Navigator and specify a name for the block design:
Once the block design file is generated, it will open automatically:
The first thing to add to a block design typically is the processor that is going to be used.
Since the Arty Z7 uses a Zynq-7000 FPGA which has a physical ARM-core processor built into the programmable logic of the FPGA, the Zynq Processing System IP is what provides the hooks to that ARM processor to the rest of the design to access it.
Click the + button to bring up the IP Catalog and type "Zynq" into the search bar. Double-click on ZYNQ7 Processing System to add it to the diagram.
After a moment, a green banner will appear at the top of the diagram window with the option to run block automation. This option appears when the Vivado project targets an FPGA development board versus just an FPGA part because Vivado is seeing the settings of how the ARM-core is configured for the development board from the board preset files and is offering to automatically configure the Zynq Processing System IP with those settings.
Click the hyperlink in the green banner to Run Block Automation and a window will pop up giving a summary of what the block automation. Ensure that the Apply Board Preset option is checked then click OK to run the block automation.
After a few moments, the Zynq Processing System IP will update and the green banner will disappear. Once complete, feel free to double-click on the Zynq IP to open its configuration window and view the updated settings for the Arty Z7.
With the Zynq Processing System in place, the next step is to add the desired peripherals to the design. There is a handy was to expedite this process using the Board tab in the Block Design when targeting an FPGA development board like the Arty Z7.
Again, pulling from the board preset files for the Arty, the Board tab will display the available hardware peripherals on the board. Right-click on the desired peripheral and select Connect Board Component.
This will bring up a list of the compatible peripheral IPs for the selected hardware peripheral in the IP Catalog in Vivado.
I started with the 4 regular LEDs and chose to connect them to an AXI GPIO IP:
After the AXI GPIO IP populates in the diagram with an external port for the LEDs, the green banner will appear again but with the option to run connection automation. This is Vivado detecting the unconnected AXI interface from the AXI GPIO IP and seeing the available master AXI port on the Zynq Processing System.
Click the hyperlink in the green banner to Run Connection Automation to see the summary of how Vivado wants to connect everything and route the necessary clocks. A good majority of the time, users don't need to change what Vivado wants to do automatically here as it is optimized to meet timing.
Click OK to allow Vivado to automatically connect the AXI interfaces in the block design.
I went ahead and connected all of the GPIO peripherals in the Board tab to their own AXI GPIO IP as I've found that this is one of the most flexible hardware designs for a wide range of software applications:
Once everything is connected in the block design as desired, the design can be validated as a preliminary check for any major errors/critical warnings before moving on.
Click the icon of a check box at the top of the diagram window to run validation. Fix any errors and/or critical warnings before saving the block design and moving to the next step.
Once the block design is complete, a top level HDL file needs to be created for it to instantiate the block design in the project. This HDL file is how the constraints file is able to find the external ports in the block diagram to be able to route them to the specified package pin of the FPGA.
Switch back to the Sources tab and right-click on the block design file. Select the option to Create HDL Wrapper...
Select the option to Let Vivado manage wrapper and auto-update unless adding custom edits to the HDL wrapper:
After a few moments, the HDL file will be generated and the hierarchy of the project will update to look like the following:
This provides a sort of visual reference for how the HDL wrapper is instantiating the block design in the project.
Constraints File for PinoutNext, the constraints file needs to be created to specify the package pins each signal in the design is to be routed/connected to.
Select Add Sources from the Flow Navigator. Then select Add or create constraints in the window that pops up.
In this case, I am creating a new file so I selected Create File and gave it the desired name. If importing an existing constraints file, select Add Files and browse to the location of the file. Most of the time, the option to Copy constraints files into project should be checked.
Click Finish:
Digilent provides master constraints files for their boards here. I simply copy+pasted the relevant signals for the GPIO peripherals I connected in my block design then renamed them to what the HDL wrapper titled them.
This is super important: the names of the signals in the top level HDL wrapper MUST match the corresponding signal names exactly (including letter case) in the constraints file. Otherwise, a DRC routing error will be thrown during bitstream generation.
Generate BitstreamWith the design complete, the next step is to start synthesizing the whole design. In the block design in particular, synthesis needs to be ran for each IP within it. The option in the Flow Navigator to Generate Block Design will take care of generating the necessary output products for each IP for synthesis, implementation, simulation, etc. and running their respective out of context synthesis.
Once completed, run synthesis for the project as a whole.
Select Run Synthesis from the Flow Navigator. Click OK in the runs option window that pops up.
Once synthesis is complete the design needs to be placed & routed (ie implementation). A pop up will appear after synthesis has successfully completed, asking to run implementation next. Click OK.
Again, after implementation completes successfully, a pop up window will appear asking to generate a bitstream. Click OK.
Once a bitstream has been successfully generated, the final step is to export the hardware design in AMD's compressed XSA file format for Vitis/PetaLinux to import and build software on top of.
Select File > Export > Export Hardware...
This will bring up the Export Wizard.
On the second page, select the option to Include bitstream:
By default, the exported XSA file will be given the same name as the top level HDL wrapper in the Vivado project, but any desired name can be given. The default export location is in the top level directory of the Vivado project, which I personally stick to to keep everything organized.
Review the export selections and click Finish to export the XSA file.
At this point, a software application can be developed in the Vitis Unified IDE (tutorial here) and/or a full embedded Linux image generated using the PetaLinux command line tools (tutorial here). This highlights the forethought that should be put into the hardware design as to what the final software target might be that is going to be developed for it.
Comments