|
|
# Vivado design with standalone Processing System
|
|
|
|
|
|
- [Introduction](#introduction)
|
|
|
- [Project Creation](#project-creation)
|
|
|
- [Block Design](#block-design)
|
|
|
- [Processing System Block](#processing-system-block)
|
|
|
- [Board Preset](#board-preset)
|
|
|
- [Processing System Customization](#processing-system-customization)
|
|
|
- [Block Design Validation](#block-design-validation)
|
|
|
- [Source Files Generation](#source-files-generation)
|
|
|
- [Output Products](#output-products)
|
|
|
- [HDL Wrapper](#hdl-wrapper)
|
|
|
- [Exporting the Hardware](#exporting-the-hardware)
|
|
|
|
|
|
## 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:
|
|
|
|
|
|
![vivado_starting_page](uploads/e4f55264988eff9df96ee4930f7e47f2/vivado_starting_page.png)
|
|
|
|
|
|
## Project Creation
|
|
|
|
|
|
To create a new hardware design, just click on **Create Project** and the following screen will pop-up:
|
|
|
|
|
|
![vivado_create](uploads/96621603f15ec8dc26a88e6a15c20155/vivado_create.png)
|
|
|
|
|
|
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**:
|
|
|
|
|
|
![vivado_project_name_standalone](uploads/1a4dd22cfa3b565257b47fcaf5ea3995/vivado_project_name_standalone.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_project_type](uploads/8917fe6fe35cce070ae93b4f075eaa0a/vivado_project_type.png)
|
|
|
|
|
|
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*:
|
|
|
|
|
|
![vivado_project_add_sources](uploads/31993c421ecbe8185662644cd5ea2f3b/vivado_project_add_sources.png)
|
|
|
|
|
|
The next screen asks for design constraints files. In this case, this is not necessary, so we just leave that empty and click *Next*:
|
|
|
|
|
|
![vivado_project_add_constraints](uploads/8cbba224b97c20f75b0ee45c60dee17d/vivado_project_add_constraints.png)
|
|
|
|
|
|
Now, a screen will appear in which we can choose the **default part** for our project:
|
|
|
|
|
|
![vivado_project_default_part](uploads/700f28564789fd443838c1945c02b66e/vivado_project_default_part.png)
|
|
|
|
|
|
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*:
|
|
|
|
|
|
![vivado_project_default_part_ultra96v2](uploads/f3339f237763a7af2f883223b21fc6bb/vivado_project_default_part_ultra96v2.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_project_summary_standalone](uploads/d44bb54901cdb34b479fa5e85c0b36ab/vivado_project_summary_standalone.png)
|
|
|
|
|
|
If the process is successful, the Vivado GUI will appear with the initial contents for our fresh project:
|
|
|
|
|
|
![vivado_project_fresh_standalone](uploads/866c453ca9b59aa29978b88a1541fe43/vivado_project_fresh_standalone.png)
|
|
|
|
|
|
## 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*:
|
|
|
|
|
|
![vivado_create_block_design](uploads/8647429c54048b3357bacedc9a04bba6/vivado_create_block_design.png)
|
|
|
|
|
|
After doing this, *Vivado* will create an empty *Diagram* in which we can add IP components from the integrated default libraries:
|
|
|
|
|
|
![vivado_standalone_blank_diagram](uploads/12cf0cd3a014551e863391ddf0e0dddd/vivado_standalone_blank_diagram.png)
|
|
|
|
|
|
### 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:
|
|
|
|
|
|
![vivado_diagram_ip_search](uploads/399bf05d2eef28b627fcbcb56bd51675/vivado_diagram_ip_search.png)
|
|
|
|
|
|
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**:
|
|
|
|
|
|
![vivado_diagram_ip_search_zynq](uploads/e156c5241d73dd26a9797e1a5aa3084d/vivado_diagram_ip_search_zynq.png)
|
|
|
|
|
|
After we push *Enter* to choose the MPSoC IP, the diagram will be updated and the default Processing System block will appear:
|
|
|
|
|
|
![vivado_diagram_default_mpsoc](uploads/c0f26718540149332c2eecdfcd1718cd/vivado_diagram_default_mpsoc.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_design_default_mpsoc_recustomize](uploads/53f0801977fc68ed871ef0d4c1106ded/vivado_design_default_mpsoc_recustomize.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_design_default_mpsoc_recustomize_advanced](uploads/04c89f974c9d475245c2fb8ee28ca200/vivado_design_default_mpsoc_recustomize_advanced.png)
|
|
|
|
|
|
### 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:
|
|
|
|
|
|
![vivado_design_run_block_automation](uploads/0fa9484e392fb7aaf204babee1960839/vivado_design_run_block_automation.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_design_default_mpsoc_preset](uploads/df3272f85d80bad36c516af6149b9c21/vivado_design_default_mpsoc_preset.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize](uploads/c77718e2d089acbe8846507337ab4b7b/vivado_design_preset_mpsoc_recustomize.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize_dp_enabled](uploads/b0b57f4543b1903362c14c9ec7108ecc/vivado_design_preset_mpsoc_recustomize_dp_enabled.png)
|
|
|
|
|
|
In order to disable this interface, we just need to **un-check the Display Port** entry:
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize_dp_disabled](uploads/17208dbf20dd53f79fbc86b8e36f6246/vivado_design_preset_mpsoc_recustomize_dp_disabled.png)
|
|
|
|
|
|
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**:
|
|
|
|
|
|
![vivado_design_preset_mpsoc_dp_disabled_block](uploads/6679f2e0a515f92f35853762030ab028/vivado_design_preset_mpsoc_dp_disabled_block.png)
|
|
|
|
|
|
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*
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize_axi_enabled](uploads/2c6c3488e1216d12d1dc58c689116e34/vivado_design_preset_mpsoc_recustomize_axi_enabled.png)
|
|
|
|
|
|
In that configuration entry, we must un-check both of the interfaces as showed in this image:
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize_axi_disabled](uploads/afc18a3a2e86459434f05ad4b5997e8a/vivado_design_preset_mpsoc_recustomize_axi_disabled.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize_general_enabled](uploads/bab2fa12f1b31684da01e3c9093f7656/vivado_design_preset_mpsoc_recustomize_general_enabled.png)
|
|
|
|
|
|
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
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize_general_disabled](uploads/7e11957ce410fb64a372b46b7008c12f/vivado_design_preset_mpsoc_recustomize_general_disabled.png)
|
|
|
|
|
|
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*
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize_clocking_enabled](uploads/27126b22ffd7f963333c19c549b3c88d/vivado_design_preset_mpsoc_recustomize_clocking_enabled.png)
|
|
|
|
|
|
In order to disable this clock, we need to uncheck the associated entry:
|
|
|
|
|
|
![vivado_design_preset_mpsoc_recustomize_clocking_disabled](uploads/59b1d39a60924a3084a32966db824b07/vivado_design_preset_mpsoc_recustomize_clocking_disabled.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_design_standalone_mpsoc_ip](uploads/400a68784b63cc4996e251bf4e9c13c7/vivado_design_standalone_mpsoc_ip.png)
|
|
|
|
|
|
### 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:
|
|
|
|
|
|
![vivado_validate_design](uploads/ed5a7a8bc3caf1e1148424da62e10699/vivado_validate_design.png)
|
|
|
|
|
|
If everything is correct, we will see the following message:
|
|
|
|
|
|
![vivado_design_validation_successful](uploads/0afdf4d2f48e00559a8b67f7c2b45e4c/vivado_design_validation_successful.png)
|
|
|
|
|
|
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.
|
|
|
|
|
|
![vivado_save_block_design](uploads/0fa39360519407fc0ed57a839e2c78a3/vivado_save_block_design.png)
|
|
|
|
|
|
## 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:
|
|
|
|
|
|
![vivado_standalone_sources_hierarchy_clean](uploads/944b69e265ae080e059ef3ffc5ab1e52/vivado_standalone_sources_hierarchy_clean.png)
|
|
|
|
|
|
### 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:
|
|
|
|
|
|
![vivado_sources_hierarchy_output_products](uploads/fc63da9b4919ffa72e553158daf4188a/vivado_sources_hierarchy_output_products.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_generate_output_products](uploads/5f202c2af226dc01bdf155d93f43179f/vivado_generate_output_products.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_generate_output_products_ooc_run](uploads/dc0e2b1e5fa3188973e978cd88be5c25/vivado_generate_output_products_ooc_run.png)
|
|
|
|
|
|
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.:
|
|
|
|
|
|
![vivado_generate_output_products_running](uploads/a302c6acf70b2ace83c9788baf011df3/vivado_generate_output_products_running.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_sources_hierarchy_hdl_wrapper](uploads/8657ac5a2c197286c980c7040bed2e4c/vivado_sources_hierarchy_hdl_wrapper.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_create_hdl_wrapper](uploads/6a0813e317072c8fd079740031981f7b/vivado_create_hdl_wrapper.png)
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_sources_hierarchy_hdl_wrapper_ready](uploads/86399c5201f97946b093dd7adb0ab18f/vivado_sources_hierarchy_hdl_wrapper_ready.png)
|
|
|
|
|
|
## 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
|
|
|
|
|
|
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:
|
|
|
|
|
|
![vivado_export_hardware_standalone](uploads/8e52908108b42132dd9a8c96549aac4e/vivado_export_hardware_standalone.png)
|
|
|
|
|
|
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. |