See Vivado™ Development Environment on amd.com
|
Version: Vivado 2024.1
This tutorial covers creating a simple Vivado design with one reconfigurable partition and three reconfigurable modules. This design is then used to create a PetaLinux project which will make use of fpgautil and libdfx to program the PL and load the device tree overlays with the relevant driver information.
- Vivado and PetaLinux 2024.1
- Access to a VCK190 board
- A micro SD card
- Xilinx VCK190 BSP
First, for the commands in this project to work, you must source the Vivado and PetaLinux 2024.1 settings.
source <xilinx_install>/Vivado/2024.1/settings64.sh
source <xilinx_install>/Petalinux/2024.1/settings.shSecond, after having downloaded the BSP, move it to this project's top-level directory.
Finally, edit <install_directory>/Linux-based-partial-image-delivery/code/libdfx/files/Makefile line 7, changing <INSTALL_DIR> to the absolute path leading to the top-level directory for this project.
- Creating the Vivado Design & Exporting XSAs
- Creating the PetaLinux Project
- Preparing Micro SD Card for Boot
- Booting the Project
- Loading RMs and Drivers in Linux
If you wish to automate steps 1 one and 2 of this tutorial, execute the following:
makeTo clean up the outputs for the project, execute:
make cleanTo automate this portion of the tutorial, execute:
make vivado_prjOr, to see what happens step-by-step:
- Navigate to the project's top directory.
cd <install_directory>/Linux-based-partial-image-delivery/- Launch Vivado.
vivado- Create the reconfigurable modules.
source ./scripts/create_rp1rm1.tcl
source ./scripts/create_rp1rm2.tcl
source ./scripts/create_rp1rm3.tcl- Create the top BD.
source ./scripts/create_top_bd.tcl- Launch synthesis, implementation, and PDI generation. This script will also automatically export the needed XSAs to a new directory Linux-based-partial-image-delivery/xsa.
source ./scripts/run_impl.tclVivado will automatically close once this script it done running.
To clean the outputs from this part of the project, execute:
make clean_vivado_prjIn this section, we will be creating a PetaLinux project based on the Vivado design completed in the previous section.
To automate this portion of the tutorial, execute:
make versal_dfxAlternatively, to do everything step-by-step:
- Create the PetaLinux project based on the VCK190 BSP.
petalinux-create project -n versal-dfx -s ./xilinx-vck190-v2024.1-05230256.bsp- Navigate to the PetaLinux project directory.
cd versal-dfx- Configure the project based on the full XSA file you generated in the previous section.
petalinux-config --get-hw-description ../xsa/design.xsaUse arrow keys to navigate up/down the menu.
- Navigate to FPGA Manager and press <ENTER>
- Press <Y> to enable Fpga Manager
- Press <TAB> and <ENTER> to go back to main config menu
- Navigate to Image Packaging Configuration and press <ENTER>
- Navigate to Root filesystem type (INITRD) and press <ENTER>
- Navigate to EXT4 (SD/eMMC/SATA/USB) and press <ENTER>
- Exit the config menu by pressing <TAB + ENTER> twice
- When asked if you want to save the configuration, select Yes (press <ENTER>)
Enabling Fpga Manager enables a built-in command line tool called fpgautil and allows us to create apps with the fpgamanager_dtg and fpgamanager_dtg_dfx templates. These apps are used with fpgautil to load and unload PDIs and partial PDIs from the Linux console.
For the automated flow, in order to skip having to open the config menu (which requires user input), we have instead copied over all of the files that would have been generated by steps 2.1-2.3.
- Create the static app based on the static XSA file you generated in the previous section.
petalinux-create apps --template dfx_dtg_versal_static -n static-app --enable --srcuri "../xsa/static.xsa"- Create the rprm apps based on the RPRM XSA files you generated in the previous section.
petalinux-create apps --template dfx_dtg_versal_partial -n rp1rm1-app --enable --srcuri "../xsa/rp1rm1.xsa" --static-pn static-app
petalinux-create apps --template dfx_dtg_versal_partial -n rp1rm2-app --enable --srcuri "../xsa/rp1rm2.xsa" --static-pn static-app
petalinux-create apps --template dfx_dtg_versal_partial -n rp1rm3-app --enable --srcuri "../xsa/rp1rm3.xsa" --static-pn static-app- Create the libdfx app and copy over the source code, Makefile, and bitbake file.
petalinux-create apps -n libdfx-app --enable
cp -r ../code/libdfx/* ../versal-dfx/project-spec/meta-user/recipes-apps/libdfx-app/- Build the project.
petalinux-build- Navigate to the /images/linux/ directory and create the boot image.
cd ./images/linux/
petalinux-package boot --u-boot- Copy necessary files to a new directory Linux-based-partial-image-delivery/sdcard.
mkdir ../../../sdcard
cp BOOT.BIN boot.scr image.ub rootfs.tar.gz ../../../sdcardFollow the instructions detailed in UG1144, Preparing the SD Card.
In this section, we will be using the micro SD card to boot our project onto the board. Make sure you have a way to monitor serial ports, Tera Term is a good free option.
- Set your VCK190 board to SD boot mode (SW1, Callout #6).
Switch 1 - ON
Switch 2 - OFF
Switch 3 - OFF
Switch 4 - OFF - Insert the micro SD card.
- Plug in USB-C cable into the board and the other end into your machine.
- Plug in the power cable.
- Check your Device Manager to see which COM ports your board is using.
- Open Tera Term or other equivalent app.
- Select the COM port corresponding to your board, and make sure the following settings are configured:
Speed/Baud Rate - 115200
Data - 8-bit
Parity - None
Stop bits - 1 bit
Flow control - None
Open the app and select a COM port related to your board (in red).
Open the settings for the serial port.
Change the settings to the following:
- Power on your board.
- When prompted for your login information, use petalinux as your username and set your own password.
In this section, we will be demonstrating how to load and unload full and partial PDIs using fpgautil and libdfx. We will also be showing how to load and unload a device driver in Linux.
Fpgautil is a built-in command line tool. To enable fpgautil, you need to turn on Fpga Manger in the PetaLinux config menu (see step 2.3) before building a given project. Fpgautil also requires that you build PetaLinux apps with the template fpgamanager_dtg for the static region and fpgamanager_dtg_dfx for the reconfigurable region(s) (see steps 2.4 & 2.5).
Libdfx, on the other hand, is an API that you can bake into a C app of your choosing. Libdfx requires the static library libdfx.a, which you can build yourself by following the instructions in the libdfx git repository. The libdfx repository also comes with an example app at libdfx/apps/libdfx_app.c, and you can also check this repository's Linux-based-partial-image-delivery/code/libdfx/files/libdfx-app.c for a similar example.
Unlike fpgautil, you do not need to build specific apps for libdfx to work. However, you will still need to have the relevant PDIs (static and partial) as well as the relevant DTBO files. For example, you'd need a filestructure that looks something like:
-->static_folder
|
|-->static.pdi
|-->static.dtbo
|
|-->rp1rm1_folder
| |
| |-->rp1rm1.pdi
| |-->rp1rm1.dtbo
|
|-->rp1rm2_folder
|
|-->rp1rm2.pdi
|-->rp1rm2.dtboYou will then need to let the libdfx API know where to look for each of these folders. Conveniently, creating apps with the fpgamanager_dtg and fpgamanager_dtg_dfx templates creates this filestructure for us under /lib/firmware/xilinx/. You can see how we've used this to our advantage in Linux-based-partial-image-delivery/code/libdfx/files/libdfx-app.c.
Before the beginning the demo, start a sudo shell (some of the commands we need to run require sudo priviledges).
sudo -sWe will start with demonstrating how to use fpgautil since it is a step-by-step process while running libdfx only requires us to execute a file. If you wish to skip straight to running libdfx, go to substep 9 of this section.
- Load the static PDI.
fpgautil -b /lib/firmware/xilinx/static-app/static-app.pdi -o /lib/firmware/xilinx/static-app/static-app.dtbo -f Full -n fullYou will see that you get several messages that read: "WARNING: memory leak will occur if overlay removed".
These messages are completely normal and nothing to worry about, so long as you follow the correct procedure for loading and unloading PDIs. Always load the static image before any partial images are loaded in. If you wish to swap out a partial images in the same reconfigurable region, you must first unload the current partial image before loading in the new one. Finally, if you want to unload the static image, make sure all reconfigurable regions are unloaded.
- Among the boot messages, you will be able to find that a DFX Decoupler has been loaded with a memory address of 0xA4400000. Its default state is disabled (not decoupling), so we want to make sure it is enabled before loading in a partial PDI.
devmem 0xA4400000We should see all 0s at this address, this means the decoupler is disabled.
devmem 0xA4400000 32 1This will write a 1 to the decoupler, which enables it. The 32 in this command is the width of the register we are writing to (execute devmem -help for more information).
- We can now load the partial PDIs containing rms 1, 2, and 3, making sure to remove the previous image before loading the next one. To load any of the 3 images, execute:
fpgautil -b /lib/firmware/xilinx/static-app/rp1rm1-app/rp1rm1-app.pdi -o /lib/firmware/xilinx/static-app/rp1rm1-app/rp1rm1-app.dtbo -f Partial -n PR0fpgautil -b /lib/firmware/xilinx/static-app/rp1rm2-app/rp1rm2-app.pdi -o /lib/firmware/xilinx/static-app/rp1rm2-app/rp1rm2-app.dtbo -f Partial -n PR0fpgautil -b /lib/firmware/xilinx/static-app/rp1rm3-app/rp1rm3-app.pdi -o /lib/firmware/xilinx/static-app/rp1rm3-app/rp1rm3-app.dtbo -f Partial -n PR0You can see that, compared to loading the static image, we've changed the following options:
-f Full --> -f Partial
-n full --> -n PR0
These flags let fpgautil know that the images we are attempting to load are partial PDIs and that we are targeting the dynamic region PR0 (if we had more than one reconfigurable region, they'd be denoted as PR0, PR1, PR2, ...etc).
Before we can send instructions to these RMs, we need to disable the decoupler. To do so, execute:
devmem 0xA4400000 32 0This reverts the decoupler to its default state by changing the 1 we wrote to it earlier back to a 0.
Once you've confirmed that the above commands worked, to properly unload the current partial image before loading the next one, execute:
devmem 0xA4400000 32 1
fpgautil -R -n PR0This re-enables to decoupler and then tells fpgautil to unload the image in the reconfigurable region PR0.
Once you are comfortable loading and unloading the various partial PDIs, move on to the next step.
- To verify that RM1 is working, load it and execute:
devmem 0xA4420000This is the memory address for a GPIO. We are expecting to read a value of 0xFACEFEED.
- To verify that RM2 is working, load it and execute:
devmem 0xA4420000This is the memory address for a GPIO (note that this is the same memory address as the GPIO for RM1). This time, we are expecting to read a value of 0xC0000000.
- Verifying RM3 is a little more complicated as there is a Uartlite instead of a GPIO. This Uartlite is in loopback with another Uartlite that is in the static region. Before we begin verification, make sure that RM3 is loaded.
If you look in /dev/, you should now be able to see two Uartlites, ttyUL0 & ttyUL1. ttyUL0 is the Uartlite in the static region and ttyUL1 is the one in RM3. To verify that these Uartlites are in loopback, begin by monitoring the inputs of ttyUL0.
cat /dev/ttyUL0 &This will show us the data that comes into ttyUL0. We can now write a simple message to ttyUL1 and see if it gets passed along.
echo Hello ttyUl1! > /dev/ttyUL1You will see that you get a console message displaying "Hello ttyUL1!", which is from the cat command you ran earlier. This means that the output of ttyUL1 feeds into the input of ttyUL0, which is what we expect. You can now kill the cat command.
killall -9 catWe can now run the same test, but swap which Uartlite we read from and write to.
cat /dev/ttyUL1 &
echo Hello ttyUl0! > /dev/ttyUL0
killall -9 catYou should now see a message displaying "Hello ttyUl0!", confirming that the output of ttyUL0 feeds into the input of ttyUL1.
- To unload the partial and static images, execute:
devmem 0xA4400000 32 1
fpgautil -R -n PR0
fpgautil -R -n fullThis command is similar to the one for unloading the static region, but we've replaced "PR0" with "full" which tells fpgautil to unload that region instead.
- To test that libdfx works as intended, execute:
/usr/bin/libdfx-appThis app runs through the exact same steps we just went through with fpgautil, but uses the libdfx API instead.
Copyright © 2020–2023 Advanced Micro Devices, Inc



