Vivado design with standalone Processing System
Introduction
As we have previously stated, the programmable logic and the processing system reside in different power domains on the Zynq UltraScale+ MPSoC.
In order to have a first approach to the MPSoC architecture, we will use Vivado to build a minimal hardware design in which only the Processing System is used.
First, we enter the terminal and create a folder to host our Vivado projects, e.g.:
mkdir -p ~/soc-course/vivado
Then, we load the environment for Vitis and introduce the locale fix (your installation path my differ, adjust the command properly):
source /tools/Xilinx/Vitis/2019.2/settings64.sh
export LC_ALL="C"
After we have done this, we can launch Vivado:
vivado
Once done, we will see the Vivado opening page:
Project Creation
To create a new hardware design, just click on Create Project and the following screen will pop-up:
We click next and, in the next screen, we need to chose the folder path we created to store our Vivado projects and introduce the name for this project, i.e. ultra96v2_standalone:
Once done, we click Next and a screen will appear in which we are asked for the type of project we want to create. Make sure RTL is selected and click Next again:
Now, the Add Sources screen appears. For this project, we don't need to add any HDL sources, but we need to choose the desired default HDL Language. In the design flow, Vivado will automatically generate some HDL sources from our design selections, so we need to choose Verilog or VHDL. For this project, there is not any functional difference, but we select VHDL as this is the most used HDL language at CERN and then click on Next:
The next screen asks for design constraints files. In this case, this is not necessary, so we just leave that empty and click Next:
Now, a screen will appear in which we can choose the default part for our project:
In this case, we won't use the default part, but will select the appropriated predefined board. In the initial bring-up, we included the procedure to provide support for Ultra96-V2 in Vivado, so this board should appear in the board selection tab. If this is the case, we just select this board entry and click Next:
Finally, as the last part of the project creation procedure, a Project Summary screen will appear in which our previous selection can be reviewed. After a quick look to check that everything is correct, we can click Finish to create the project:
If the process is successful, the Vivado GUI will appear with the initial contents for our fresh project:
Block Design
The core element in a Zynq UltraScale+ MPSoC design built with Vivado is the Block Design. In this way, we need to create a new block design from the Flow Navigator tab in the left of the GUI. Specifically, we need to click on:
- IP INTEGRATOR
- Create Block Design
Once done, a dialog window will pop-up in which we can select the name of our design. We can left that with the design_1 default without problems and click OK:
After doing this, Vivado will create an empty Diagram in which we can add IP components from the integrated default libraries:
Processing System Block
Now, as a first step, we need to add the Zynq UltraScale Processing System IP block in the diagram. In order to do that, we push in the + icon in the diagram and a menu with the list of the available IPs will appear:
In order to filter the available IPs, we can write zynq in the search field and this will limit the available IPs to the only one that matches the criteria, i.e. the Zynq UltraScale+ MPSoC:
After we push Enter to choose the MPSoC IP, the diagram will be updated and the default Processing System block will appear:
Now, by double-clicking in the MPSoC IP block, a Re-customize IP dialog will appear. In this dialog, we can find a map in which reviewing all of the different elements we expect to find in the Zynq UltraScale+ MPSoC, plus a Page Navigator menu panel that we can use to customize the Processing System to our needs:
If we click in the Switch to Advanced Mode, we will see that the block map become more detailed and that more entries are added to the Page Navigator menu tab:
Board Preset
Before tweaking any element in the PS by hand, we can re-customize the system with the pre-defined defaults for our board. In order to do that, we just press Cancel and go back to the design screen. If we take a look to the top of the design area, we will see a message stating that the Designer Assistance is available. In order to access to this assistance wizard, we just need to click in the Run Block Automation link and this screen will appear:
In this dialog, we just make to be sure that Apply Board Preset option is checked and click OK. By doing this, all of the customizations in the MPSoC will be overridden by the defaults defined for the Ultra96-V2, as this is the board we selected when creating the project.
After the board presets has been applied, the Designer Assistance will disappear and we will see that the external block aspect for the MPSoC has been modified and new AXI bus interfaces have been added:
But the changes generated by the presets are actually deeper, and we can check them by double-clicking the MPSoC IP Core again and re-entering the Re-customize IP dialog:
Now, in the PS block design map we can see that the following interfaces have been enabled:
- Low Power Domain:
- GPIO
- USB 0, USB 1
- SD/eMMC 0, SD/eMMC 1
- I2C 1
- UART 0, UART 1
- Full Power Domain:
- Display Port
Processing System Customization
In our very simple standalone design for the Ultra96-V2, we don't need graphical features. For this reason, we will use the re-customize menu to disable the Display Port peripheral. In order to do that, we can navigate the menu in the I/O Configuration or, alternatively, we can click the Display Port element in the Block Diagram map to access the specific configuration entry (we can configure all of the elements highlighted in green color). Once there, we will see that the Display Port is checked and the information about the used I/O is showed:
In order to disable this interface, we just need to un-check the Display Port entry:
Once this has been done, we can go back to the PS UltraScale+ Block Design and we will check that the Display Port is now not marked as used:
Finally, as we previously stated, for this standalone design we are just going to use the Processing System and not the Programmable Logic, so we do not need to establish any PS-PL interface.
In order to disable the AXI interfaces, we must go to the PS-PL Configuration menu by either using the Page Navigator or clicking in the associated Block Design element. Once done, we will need to expand the following entries to access the AXI Master interfaces enabled by default in the Ultra96-V2 presets:
- PS-PL Interfaces
- Master Interface
- AXI HPM0 FPD
- AXI HPM1 FPD
- Master Interface
In that configuration entry, we must un-check both of the interfaces as showed in this image:
In order to disable the Interrupts from PL to PS and the Fabric Reset, we need to access the General menu in PS-PL Configuration. We can check that these are the only signals enabled by the Ultra96-V2 presets in this menu:
We need to modify these settings as showed in following image, i.e.:
- Select 0 interrupts for IRQ0[0-7]
- Uncheck the Fabric Reset Enable
Finally, we need to disable the clock from the PS to the PL included in the Ultra96-V2 preset. In order to access this menu, we can accessing the Clock Configuration menu in the Page Navigator or by clicking in the Clocking element in the PS UltraScale+ Block Design map. In this menu, we can identify the following 100MHz from the PS to the PL:
- Output Clocks
- Low Power Domain Clocks
- PL Fabric Clocks
- PL0
- PL Fabric Clocks
- Low Power Domain Clocks
In order to disable this clock, we need to uncheck the associated entry:
Once all of the PS to PL stuff has been disabled, we can just click on OK to accept the re-customized changes and the block diagram design will be updated accordingly. Here, we can check that the Zynq UltraScale+ MPSoC IP Core has not any external interface in the block design screen in Vivado:
Block Design Validation
To verify that everything is OK in our block design, we can click in the Validate Block Design button or use the F6 keyboard shortcut:
If everything is correct, we will see the following message:
Finally, to save the changes in our block design, just click the Save Block Design icon in the Vivado toolbar or use the Ctrl + S keyboard shortcut.
Source Files Generation
Once we have finished and validated our standalone block design, we need to generate the source files associated to this design so that the Vivado tool is able to create our design.
If we take a look to the Sources panel Vivado in the Hierarchy tab, we can find our design_1.bd file:
Output Products
As a first step, we need to generate the Output Products for our block design, i.e. the generated files produced for an IP based design block and its customization. They can include HDL, constraints, and simulation targets and many other stuff. Is important to note that the generated HDL files will use the default HDL language (Verilog or VHDL) we set for our Vivado project. In order to do this, just click with the secondary mouse button in the design_1.bd file and select Generate Output Products in the contextual menu:
Once done, a menu dialog will appear with the output products generation configuration and will ask for confirmation. Just click on Generate and the process will start:
After a while, a message dialog will appear stating that the generation process will be continue in an Out-of-Context way. This means that we will have access to Vivado while the process is being executed in the background:
In this way, in order to know when the project has actually finished, we need to observe the information messages that will appear in the top-right side of the Vivado GUI, e.g.:
When the process has finished, the message will be Ready.
HDL Wrapper
Now, we need to create the HDL Wrapper for our design, i.e. the file that will act as the top level HDL file for our design. Once again, the HDL language for this file will be the one we selected as default for our project (VHDL). In order to launch this process, just click with the secondary mouse button on the design_1.bd and select Create HDL Wrapper in the contextual menu:
Once done, a dialog will appear asking for the way in which we want to manage the HDL wrapper. Be sure that the Let Vivado manage wrapper and auto-update is selected and click OK:
Once the process has finished, we can check the Sources panel in the Hierarchy tab that the design_1_wrapper.vhd HDL file is now the top of the hierarchy and the design_1.bd appears just below it:
Exporting the Hardware
As we are not going to use the Programmable Logic, there is no need to synthesize, implement and generate a bitstream.
In this case, for our standalone design, we can now export the hardware for using it in future software development. In order to do this, we need to select the following option from the Vivado menu:
- File
- Export
- Export Hardware
- Export
After doing this, the Export Hardware dialog will appear. In this dialog, we will change the default name to ultra96v2_standalone. Also, as we have not generated a bitstream, we don't need to select the include bitstream checkbox:
When this process has finished, we will have a file called ultra96v2_standalone.xsa in our project that can be used for software design in standalone mode, i.e. using only the Zynq UltraScale+ MPSoC Processing System.