# How to Build PYNQ v2.6 for Ultra96

In this post we’re going to setup a virtual machine with the tools for building PYNQ and we are going to build PYNQ release v2.6 (tool version 2020.1) for the Ultra96 board. We’re going to start with the virtual machine that we setup in the previous post How to Install PetaLinux 2020.1. That VM has Vitis 2020.1 and PetaLinux 2020.1 installed, both of which we will need to build PYNQ. If you want to avoid issues along the way, I highly recommend that you follow that post and recreate the same VM with exactly the same tool versions and OS.

You don’t actually have to do this step, but the build process is very long and if you don’t want to sit at the terminal the whole time, entering the root password at various stages throughout the build, then I suggest you set this up.

1. Edit the sudoers file with nano by running this command in the terminal: sudo nano /etc/sudoers
2. At the end of the file, add this new line: jeff ALL=(ALL) NOPASSWD: ALL (replace jeff with your user name).
3. Press Ctrl-O to save the changes, accept the filename then Ctrl-X to exit nano.

In v2.6, the PYNQ SD build process will produce an image for these boards: PYNQ-Z1, PYNQ-Z2 and ZCU104. The image for the ZCU104 requires the HDMI IP core, so if you don’t have a license for it, the build will fail. In this post, we’re actually going to bypass the build for ZCU104 so we don’t need the license, but I’ve included the steps below for those who do want to build for ZCU104.

We’re going to get a license that is node-locked to our VM, so we’re going to start by getting the right information to identify our host (the VM).

1. Run Vivado License Manager 2020.1 on the VM by clicking on “Activities” and then searching with the keyword “license”.
2. Click on “View Host Information”.
3. The License Manager will show you the information that you can use to identify the VM when requesting a node-locked host. Write down the values of these two items:
• Host name - for example, mine is ubuntu18044, I specified this when creating the VM)
• Network Interface Card (NIC) ID - a 12 digit hexadecimal number corresponding to the MAC address of the VM’s Ethernet interface (eg. 01234567abcd)
4. On the VM, open Firefox and visit the Xilinx Product Licensing Site. You will have to log in using your Xilinx account details.
5. On the Product Licensing page, on the “Create New Licenses” tab, click “Search Now” to search for the HDMI IP evaluation license. Type “HDMI” as the search term and click on the “LogiCORE, HDMI, Evaluation License”.
8. Click “Generate Node-Locked License”, this allows you to create a license file containing all of the licenses that you ticked above.
9. Under “System Information”, click on the Host ID dropdown and select “Add a host”. Enter the host information that you got earlier from the Vivado License Manager (ie. host name and NIC ID).
10. Click “Next”. Review your license choices, it should contain the licenses that you ticked off, and the host information you entered. Click “Next” if everything is as you expected.

A license file called Xilinx.lic will be emailed to you. Open your email on the VM, and copy the license file into the ~/.Xilinx directory on the VM. As this is a node-locked license, you can only use it on this VM.

### Step 3: Clone and setup the Ultra96 PYNQ repository

1. We’ll keep all of our PYNQ related stuff inside a directory in home called ~/pynq. Create this directory and clone the Ultra96 PYNQ Git repository into it with these commands:
mkdir ~/pynq
cd ~/pynq
git clone https://github.com/Avnet/Ultra96-PYNQ.git
cd Ultra96-PYNQ
git checkout -b image_v2.6.0 origin/image_v2.6.0

1. In Firefox, open the list of Ultra96 PYNQ Releases, scroll down to the v2.6 release and then from the list of assets, download the Ultra96 BSP for the board version that is appropriate for you (v1 or v2). I’ll download the BSP for the Ultra96 v2 because that’s the board that I want to build PYNQ for.
2. The ultra96v2_bsp.zip file should end up in the ~/Downloads directory. In the terminal window type the following command to extract the contents of the file into the ~/Downloads directory:
unzip ~/Downloads/ultra96v2_bsp.zip -d ~/Downloads

1. The table below shows the files that you just extracted into ~/Downloads/ultra96v2 and where they now need to be copied:
File Where to put it
sensors96b_v2.bsp ~/pynq/Ultra96-PYNQ/Ultra96
sensors96b.bit ~/pynq/Ultra96-PYNQ/Ultra96/sensors96b
sensors96b.hwh ~/pynq/Ultra96-PYNQ/Ultra96/sensors96b

Use the following commands to copy each of the extracted files to where they need to go:

cp ~/Downloads/ultra96v2/sensors96b_v2.bsp ~/pynq/Ultra96-PYNQ/Ultra96/.

1. Setup the soft links that ensure that the PYNQ build scripts refer to the board spec and BSP for the version of the Ultra96 that you are using (v1 or v2). Run the following commands:
cd ~/pynq/Ultra96-PYNQ/Ultra96
ln -s specs/Ultra96_v2.spec Ultra96.spec
ln -s petalinux_bsp_v2 petalinux_bsp


Note that if you are using the Ultra96v1, then you need to replace the _v2 with _v1 in the above commands.

### Step 4: Clone the PYNQ repository and setup the build environment

1. Clone the PYNQ repository into the ~/pynq directory:
cd ~/pynq
git clone https://github.com/Xilinx/PYNQ.git
cd PYNQ
git checkout origin/image_v2.6.0

1. The PYNQ repository contains a script that installs all of the PYNQ dependencies. Run the script with these commands:
cd sdbuild
./scripts/setup_host.sh

1. Reboot the VM. If you don’t reboot at this point, you will end up with an error in the steps below due to QEMU and CrossTool not being on the path.
2. Source the setting scripts for Vitis and PetaLinux 2020.1. Note that the location of the settings files will depend on where you installed Vitis and PetaLinux, so you may need to change the paths before running the commands below:
source ~/Xilinx/Vitis/2020.1/settings64.sh
source ~/petalinux/2020.1/settings.sh

1. Turn PetaLinux WebTalk OFF:
petalinux-util --webtalk off

1. When the script completes successfully, run the following command to make sure that all of the dependencies are installed. If it outputs a list of packages and NO error messages, then it’s a success.
make checkenv

If you come across errors during installation of the PYNQ dependencies, you will have to use the error messages to determine the package(s) that failed to install, and then try to manually install that package or look to internet forums for help. In order to avoid problems when actually building PYNQ, it is critical that ALL of the dependencies are installed correctly beforehand.

### Step 5: Build the PYNQ image for Ultra96

You should expect the build process to last for several hours. One reason why it takes so long is that by default it will build the PYNQ images for three extra boards: PYNQ-Z1, PYNQ-Z2 and ZCU104. According to this forum post, we have to build PYNQ for the PYNQ-Z2 but we can remove the other two boards from the repository to save on build time:

1. Use git rm to remove the PYNQ-Z1 and ZCU104 board files, and then locally commit the changes. Note that we need to locally commit the changes, because the build process uses the most recent git commit and ignores any uncommited changes to the repository.
cd ~/pynq/PYNQ/boards
git config --global user.email "jeff@email.com"
git rm -r Pynq-Z1
git rm -r ZCU104
git commit -m "removed board files for pynq-z1 and zcu104"

1. Run make to launch the build. The build script expects you to pass a variable called BOARDDIR whose value is the path to the board files for which you want to build PYNQ. In our case, this path must be set to the location of our Ultra96 PYNQ repository: ~/pynq/Ultra96-PYNQ. Run the following commands to launch the build:
make clean
make BOARDDIR=~/pynq/Ultra96-PYNQ


### Step 6: Write PYNQ image to SD card

If the build completes successfully, you will find an SD card image here: ~/pynq/PYNQ/sdbuild/output/Ultra96-2.6.img

1. Insert a blank SD card into a USB card reader that your VM can access
2. Find the SD card’s device name by running the dmesg command in the terminal. The SD card should be found at the end of the log, and it’s device name should be something like /dev/sdX where X is a letter such as a,b,c,d, etc. In the following commands, I will assume that the SD card is /dev/sdX, but you will need to replace the X with the right letter for your SD card.
3. Use the following command to write the PYNQ image to the SD card:
sudo dd if=~/pynq/PYNQ/sdbuild/output/Ultra96-2.6.img of=/dev/sdX status=progress bs=4M


#### Warning

When you run the above command, you must be absolutely certain that you are using the correct device name for the SD card. If you don’t use the correct device name, you risk writing over something else - such as your main hard drive. If you’re not sure, try running dmesg before and after plugging in the SD card, and watch for the change.

### Time to boot PYNQ!

Now all that is left to do is to plug the SD card into the Ultra96 and power it up. We’ll go through how to use PYNQ for Ultra96 in a future post, but for now you can read about it in the documentation.