The Zynqberry holds a special place in my heart as one of my favorite boards, so of course I had to pull it back out in my venture of updating to Vivado 2019.2 and Vitis. I also hadn't previously gotten the chance to create custom applications for it in PetaLinux, which is one of the best ways to take full advantage of the available processing power in the Arm cores and couple it with the FPGA fabric in the Zynq chip. So I needed to create this new base project for the Zynqberry to allow for new app development on it moving forward.
The Zynqberry has quite a bit of custom IP provided by its manufacturer, Trenz Electronics, for all of the peripherals on this little Raspberry Pi-like FPGA board. Along with this custom IP, Trenz also provides a TCL script to allow for user to recreate the Zynqberry's block design since it's not the most trivial deign to recreate from scratch. However, Trenz hasn't released a version of this custom IP nor block design TCL script past Vivado 2018.3. Fortunately, it's not very difficult to update IP between versions of Vivado this close together. You can find all of the example projects, source files, custom IP, TCL scripts, and pre-built images from Trenz for the Zynqberry here. There are three demo project folders available, I'm using the IP and block design TCL script from the zynqberrydemo1 as it seems to have the most IP in it.
Before reading this next section, know that you can find the 2019.2 version I've generated of the Zynqberry's IP and block design TCL script here, but I'm outlining the steps I took to update the IP since it's a good thing to know if you may use multiple versions of Vivado.
The first step in updating custom IP blocks is to create the project in the original Vivado version the IP was developed in (version 2018.3 in this case) using the IP library and the block design TCL script.
In Vivado 2018.3, install the board preset files in Vivado and create a new project targeting the Zynqberry board.
In the Project Manager, select the 'Settings' option towards the top then select 'Repository' under the IP heading. Point to the folder 'ip_lib' from the demo project folder from Trenz and click 'Apply'.
Once the IP repository is added to the project, run the block design TCL script from the TCL console (also from the demo project folder from Trenz, titled zynqberry_bd.tcl).
Save this new block design then close the Vivado 2018.3 project. Be sure the Zynqberry board preset files are also installed in Vivado 2019.2 and reopen the project in Vivado 2019.2. In the Report menu, select 'Report IP Status' run the update IP option.
I noticed I got a few warnings after all of the IPs finished updating, but don't seem to be a huge issue as I haven't encountered any issues or errors in the rest of the project flow.
To create a 2019.2 version of the block design TCL script for future projects, run the write_bd_tcl command from the TCL console.
write_bd_tcl /<desired file output path>/<desired file name>.tcl
At this point, you can continue on using the 2019.2 project that you updated from 2018.3 or if you are starting at this point in 2019.2 using my 2019.2 files I linked above, just create a new project targeting the Zynqberry board and follow the same steps above to add the IP repository to it and generate the block design from the TCL script.
Run validation as a sanity check, then save & close the block design.
With the block design in place, create an HDL wrapper just like normal (right click on the block design in the Sources menu and select 'Create HDL Wrapper...'). The demo project folder from Trenz also contains a full constraints set that needs to be imported into the project. Use the 'Add Sources' option to import constraints from zynqberrydemo1. Once, imported right click on the constraints file titled 'Vivado target' and select 'Set as target'.
At this point, you are free to add any custom RTL to the project if you so chose, but the hardware design is complete otherwise. Run synthesis, implementation, and generate bitstream. Then export hardware (including bitstream) to use in Vitis (File > Export > Export Hardware).
As I've outlined in my previous Vitis blogs, I like to create a folder in the Vivado project directory for the Vitis workspace that I point to when launching Vitis (Tools > Launch Vitis).
Create a new platform project from the custom XSA file exported from Vivado and build all after. (Be sure the 'Generate boot components' options is selected)
I always like to have a bare metal 'hello world' application to use as a baseline/sanity checker.
Create a new application project targeting the custom XSA exported from Vivado and use the Hello World template.
Run another build all (control+B) then you can close Vitis and open a Terminal window to create a new PetaLinux project. I've covered how to create a PetaLinux project for a design done in Vivado/Vitis 2019.2 a couple of times now so refer back to my last couple of blogs if you're not sure how to create a new project and import the hardware exported from Vivado.
The System Configuration editor (brought up when the hardware is imported into the PetaLinux project) is where the settings can be accessed for what medium the embedded Linux image will be booting from, which in our case will be partially from the on-board QSPI flash and then from the SD card.
The Zynq boot image (boot.bin) and the u-boot environment will live in the on-board QSPI flash of the Zynqberry and will copy the kernel and device tree into the DDR at boot time. The kernel will then take over and run the root file system from the SD card.
The kernel needs a few things tweaked from the defaults generated upon the project creation. To access the configuration editor run:
petalinux-config -c kernel
I have a list posted in the repository of my project here that can be used with the search function in the editor (accessed by typing '/' at any time) to find the path to the setting and if it's either currently enabled or disabled.
To add packages to the root filesystem, run:
petalinux-config -c rootfs
There a few packages that need to be enabled under the Filesystem Package tab which you can find the list for in my previous post here at the end of Step 10. I also like to add a few package groups from the PetaLinux Package Groups tab. My preferred packages to add are the networking-debug, networking-stack, and python-modules packages.
In order for the kernel to see the hardware in the block design of Vivado, the user-editable device tree file (found in the PetaLinux project under /<PetaLinux project directory>/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi) needs to have the appropriate nodes added to it. Find a copy of mine here.
As a final step, a boot image needs to be generated in PetaLinux using the petalinux-package command:
petalinux-package --boot --fsbl ../vitis_workspace/zynqberry_0/export/zynqberry_0/sw/zynqberry_0/boot/fsbl.elf --fpga ../vitis_workspace/zynqberry_0/export/zynqberry_0/hw/zsys_wrapper.bit --u-boot
This boot image is loaded into the Zynqberry's QSPI flash via Vitis with the Program Flash option (Xilinx > Program Flash). Since we're not loading a bare metal application, the Project Type is System, and the Image File is the boot image generated by PetaLinux (located in <PetaLinux project directory>/images/linux). There is no memory offset in the flash to load the image into, so that is set to zero. The Flash Type is qspi-x4-single, and it's good to check the option to verify after flash.
When loading files into the flash memory of a board, the FSBL is needed to boot the board to a point that the flash is powered on (thus why the Program Flash tool has you specify it). For the Zynqberry, the boot mode for normal operation is to boot from the QSPI flash, a separate FSBL is needed to tell the board to boot from JTAG for the flash operation. In my previous Zynqberry blogs, I was able to create this separate FSBL, but for some reason Vitis just wasn't agreeing with me. Luckily, I was able to use the JTAG FSBL from my old project with I included in the project's repository here. (I will figure this out and let you know the solution in a future post)
I've covered how to prep & load the SD card for an embedded Linux image several times, and that process hasn't changed at all in PetaLinux 2019.2 so Step 14 in my previous Zynqberry blog can still be directly followed for configuring the SD card.
With the boot image loaded into the flash and the SD card inserted into the board, it's time to boot up the Zynqberry! If you didn't change it in the System Configuration editor in PetaLinux, the username and password to login are both 'root'. I then ran the 'ifconfig' command just to show that the Linux image does indeed recognize the Ethernet port on the board.
Since this is my base level project for the Zynqberry in Vivado/Vitis 2019.2, keep an eye on my repository for it here, as it will evolve with my future projects and posts!