It's no secret that I have a particular soft spot for the Raspberry Pi 2 form-factor FPGA development board from Trenz Electronic, the Zynqberry, so when Trenz announce another Raspberry Pi form-factor FPGA board, I was immediately excited. I even wrote a brief article covering its launch.
Well after an unfortunately long amount of time, I finally got my hands on this Raspberry Pi Zero form-factor FPGA board. And I started with the same thing that I do with every new FPGA board I get: creating a base hardware design utilizing most (if not all) of the peripherals on the board to serve as the starting point to develop custom embedded C applications, embedded Linux images, and add any custom hardware to the programmable logic. While Trenz is pretty good about providing reference designs and source files/IP for their boards, the base design for the ZynqberryZero threw me for a few loops.
You can download the source files for the ZynqberryZero from Trenz site here. This zip folder contains the source files that I reference throughout this project.
First things first, install board preset files for the ZynqberryZero in Vivado by copying the TE0727_10_1C directory from /zbzerodemo1/board_files/ to /<Vivado installation path>/data/boards/board_files
~$ sudo cp -R ./zbzerodemo1/board_files/TE0727_10_1C/ /<Vivado installation path>/data/boards/board_files/
Launch Vivado and create a new project selecting the ZynqberryZero as the target board:
Once the Vivado project is generated and the project directory now exists, copy over the Trenz IP library folder for ZynqberryZero.
~$ sudo cp -R ./zbzerodemo1/ip_lib/ /<Vivado project directory>/zynqberry_zero_prj/
Install the Trenz IP library for ZynqberryZero in the Vivado project by selecting Settings from the Flow Navigator window and navigating to IP > Repository and clicking the + button. Point to the Trenz IP library copied into the Vivado project directory in the previous step. Click Apply when you return to the Settings widow before clicking OK to close it.
The block design for the ZynqberryZero can be recreated from a TCL script. Copy over to the Vivado project directory.
~$ sudo cp -R ./zbzerodemo1/block_design/zsys_bd.tcl /<Vivado project directory>/zynqberry_zero_prj/
Return to the Vivado project and create block design from tcl script by running the following command from the TCL console:
source ./zynqberry_zero_prj/zsys_bd.tcl
You'll probably get the initial error from the script:
Simply comment out lines 4 - 6 to nix the version control stuff if not using it and resolve the error when trying to run the script. Save the block design TCL script and return to the TCL console to run it again with the same command.
Run the resulting connection automation after block design is generated from TCL script, as this particular TCL script does not cover all of the connections between the IP blocks.
Re-customize the Zynq Processing System (double-click on the IP block) to add the high-speed AXI ports, HP0 & HP1, for the video in and out interfaces for the mini HDMI port on the board. Click OK to save and close the Zynq PS IP window and then run the connection automation that results from enabling the two ports.
You'll get the following memory address error, click OK for now and we'll address this a little bit later:
Re-customize Zynq PS again to add PL-PS interrupts, enable FCLK_CLK1 at 200MHz, & connect I2C0 to the EMIO:
Click OK to save and close the Zynq PS IP window then connect the IIC_0 port on Zynq PS to IIC_A pin.
Now there are a few things that the auto-connection got wrong that need to be fixed. First, delete gpio_rtl pin and expand GPIO port on axi_gpio_1 IP block. Connect gpio_io_0[31:0] to control[31:0] on the video_in hierarchy IP block.
Then disconnect M02_ARESETN and M03_ARESETN on the ps7_0_axi_periph AXI Interconnect IP.
A typo in the TCL script for the block design causes an extra master interface to be generated which throws off the autoconnections. Manually change them to match the diagram below (deleting the second master interface on the video_in hierarchy interface is optional, it is ok to just leave it unconnected):
Override the connections for interconnect_aresetn from the rst_ps7_0_100M Processor System Reset IP with the following connections:
Verify the connections of peripheral_aresetn of the rst_ps7_0_100M Processor System Reset IP:
To fix the memory address error that appeared earlier, rename AXI Video DMA IP in the video_in hierarchy. The TCL script that creates the block diagram has another typo that names both the AXI Video DMA blocks in the design (one is in the video_in hierarchy and the other is in the video_out hierarchy). They are both named axi_vdma_0, which causes Vivado to try to map them to the same address space in the DDR. I opened the video_in hierarchy and renamed its AXI Video DMA to axi_vdma_1 since it is connected to the HP1 port of the Zynq Processing System IP.
Switch over to the address editor and right-click on the S_AXI_HP0 line entry that still exists under video_in/axi_vdma_1 and select the option to Unmap Segment which will effectively delete it. The resulting address editor should now look something like this:
Many of the connections must manually be made despite the provided TCL script and running subsequent connection automation. The final block design should now look like this:
After getting everything connected, run validation on the design. The two following critical warnings will appear, but they can be ignored for now.
Create the top level HDL wrapper by right-clicking on the block design file in the Sources window and selecting Create HDL Wrapper..., then choose the option to allow Vivado to auto-manage it. The critical warning about the AXI reset lines not being connected will appear again, but they can be ignored.
Add the constraints files for the Zynqberry from the Trenz source files located in /zbzerodemo1/constraints/
Set the vivado_target.xdc as the target constraints file by right-clicking on it in the Sources window and selecting Set as Target Constraint File.
Run synthesis, implementation, & generate a bitstream using the controls from the Flow Navigator window.
After running implementation, it appears that there are some timing violations in the video_out hierarchy block, specifically on the peripheral reset line. After digging into it a bit, I didn't see a simple straightforward fix, so I'll have to come back to this later. While I don't see a simple way to fix it, I also don't see the meta-stability it could cause having too much of a negative impact since it's on the reset line. But I guess I'll find out once I create the PetaLinux project and the Desktop environment for it to output over the HDMI port this video_out hierarchy block is driving.
Once a bitstream has been successfully generated, export the hardware platform for use in Vitis and/or PetaLinux by selecting File > Export > Export Hardware...
Be sure to check the box in the following pop up window to include the bitstream in the hardware platform being exported. The default export location of the hardware platform (.XSA file) is the top level Vivado project directory. I personally just use this default location to export to, but you can change it if desired.
And that's it for the hardware design for the Zynqberry Zero. While the design files from Trenz do include a pre-built hardware platform (.XSA file), it would not be possible for you to add any custom hardware if so desired. And if that timing violation on the video_out driver does end up affecting the performance of the HDMI, the base Vivado project would still need to be built out like this so the fixes can be made and an updated hardware platform file generated.
This is just an example of how sometimes you can't blindly trust source files you might receive from a vendor and how to dig through them if need be!
Comments