Edge Detection on Zybo Z7 with PCAM using Vitis HLS
Vivado Design Suite
The Vivado Suite consists of 3 main tools listed below:
- Vivado : This is the traditional Vivado application used for hardware prototyping and platform generation.
- Vitis IDE : The IDE is used for integrating a software application with a hardware platform. (The pcam drivers with the video processing pipeline in our case.)
- Vitis HLS : This High Level Synthesis tool is used to generate synthesizable hardware from a description of higher abstraction. (C++ vs SystemVerilog in our case.)
Getting Started
It is highly recommended to familiarize yourself with the general toolflow in Vivado and Vitis IDE. Go through the following tutorials to understand the toolflow and get a taste of prototyping using FPGAs.
- Vivado : https://digilent.com/reference/programmable-logic/guides/getting-started-with-vivado
- Vitis IDE : https://digilent.com/reference/programmable-logic/guides/getting-started-with-ipi
Setup Video Pipeline using PCAM
Follow the instructions from the official demo: https://digilent.com/reference/programmable-logic/zybo-z7/demos/pcam-5c
Make sure to download the right version of the demo from the above website(I am using version 2022.1) Each repository contains two zip files:
- Zybo-Z7-20-Pcam-5C-sw.ide.zip : This contains the entire system with the platform packaged along with the application. This can be directly imported to Vitis IDE to get the video pipeline working.
- Zybo-Z7-20-Pcam-5C-hw.xpr.zip : This is the hardware platform that was used to generate the above system. If the video pipeline is the end goal, this file is not required. But as we have to change the pipeline (to insert an edge detection IP) we will be using this file.
Vitis HLS : Creating Edge Detection IP
HLS Libraries
- Vitis HLS has a set of OpenSource libraries that are available on github.
- Download the above repository and include it while creating the HLS IP below.
Creating the IP
- The Source files found in this repo are the updated version from the Old Embedded Vision Demo updated to work with Vitis HLS (It was Vivado HLS/SDK back then)
- Create a new project and add the attached source files : edge_detection.cpp, edge_detection.h. (The dependencies can be added using the gcc flag -I)
- All the required directives are provided in-line within edge_detection.cpp
- Synthesize the design with 6.67ns time period.
- Export RTL as IP to be used in our video pipeline(This will be a .zip file)
Vivado : Add the HLS IP in our video pipeline and export Hardware Platform.
- untar the hardware platform file (*-hw.xpr.zip) downloaded from the pcam repository. This file has the definition of all the hardware components that exist in the video pipeline. It is mainly comprised of Vivado and digilent IPs. We will be integrating our video processing IP into this video pipeline.
- Open the untarred .xpr as a new project.
- Open Settings under the Project Manager menu in the flow navigator tab.
- Select IP then Repository, add the folder with the exported RTL from Vitis HLS. Click on Apply and OK.
- Open IP Catalog and confirm the edge_detection IP exists, if not right click on the "User Repository" corresponding to the IP path that was provided, and manually add the IP.
- Open the Block Design in the flow navigator to see the layout of the different constituent blocks.
- Right click at a vacant space in the Block Diagram and select "Add IP", search for the edge_detection module and add.
- Make the following connections:
a) M_AXIS_MM2S -> stream_in ; stream_out1 -> video_in
b) ap_clk -> clk_out2
c) ap_rst -> peripheral_aresetn[0:0]
- Generate Bitstream for the design. (This will automatically execute synthesis and implementation.)
- Select Export Hardware option from File and follow the prompts (Select include bitstream as we have already completed that step.)
- A .xsa file will be created, this is the final hardware platform description of our system.
Vitis IDE : Integrate the updated hardware platform into our System.
- Import the vitis project zip file (*-sw.ide.zip) [No need to untar this file]
- Right click on system_wrapper in the Explorer tab and select Update Hardware Specification. Select the exported *.xsa from the previous step.
- Change the default video format in main.cc in the src folder(from the explorer tab) to match the default hls video format.
Replace :
pipeline_mode_change(vdma_driver, cam, vid, Resolution::R1920_1080_60_PP, OV5640_cfg::mode_t::MODE_1080P_1920_1080_30fps);
With
pipeline_mode_change(vdma_driver, cam, vid, Resolution::R1280_720_60_PP, OV5640_cfg::mode_t::MODE_720P_1280_720_60fps);
You could also change the resolution after the system is up using the Serial Port.
- Build the project and Run it on the hardware platform (on Zybo.)
Result:
Utilization
Raw video pipeline (No edge detection)
+----------------------------+-------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+----------------------------+-------+-------+------------+-----------+-------+
| Slice LUTs | 7677 | 0 | 0 | 53200 | 14.43 |
| LUT as Logic | 7386 | 0 | 0 | 53200 | 13.88 |
| LUT as Memory | 291 | 0 | 0 | 17400 | 1.67 |
| LUT as Distributed RAM | 60 | 0 | | | |
| LUT as Shift Register | 231 | 0 | | | |
| Slice Registers | 10875 | 0 | 0 | 106400 | 10.22 |
| Register as Flip Flop | 10875 | 0 | 0 | 106400 | 10.22 |
| Register as Latch | 0 | 0 | 0 | 106400 | 0.00 |
| F7 Muxes | 669 | 0 | 0 | 26600 | 2.52 |
| F8 Muxes | 144 | 0 | 0 | 13300 | 1.08 |
+----------------------------+-------+-------+------------+-----------+-------+
Video pipeline with edge_detection IP
+----------------------------+-------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+----------------------------+-------+-------+------------+-----------+-------+
| Slice LUTs | 8370 | 0 | 0 | 53200 | 15.73 |
| LUT as Logic | 8076 | 0 | 0 | 53200 | 15.18 |
| LUT as Memory | 294 | 0 | 0 | 17400 | 1.69 |
| LUT as Distributed RAM | 60 | 0 | | | |
| LUT as Shift Register | 234 | 0 | | | |
| Slice Registers | 11843 | 0 | 0 | 106400 | 11.13 |
| Register as Flip Flop | 11843 | 0 | 0 | 106400 | 11.13 |
| Register as Latch | 0 | 0 | 0 | 106400 | 0.00 |
| F7 Muxes | 669 | 0 | 0 | 26600 | 2.52 |
| F8 Muxes | 144 | 0 | 0 | 13300 | 1.08 |
+----------------------------+-------+-------+------------+-----------+-------+
Troubleshooting
These are some of the common issues and how to solve them (Feel free to send a pull request if you would want something added):
Vitis HLS cannot find the necessary dependencies
Sometimes Vitis HLS cannot find the included header files even after linking them using -I. Press Ctrl and Left Click
on the file opens the right file in editor, but linker fails to locate the file. As a temporary solution I copied the necessary files to the folder and linked using relative paths.
Burning the final system binaries onto the FPGA fail in Vitis IDE
Simple retry resolves the issue.
Vivado does not synthesize with the error:
- [Common 17-69] Command failed: File '*/Zybo-Z7-20-Pcam-5C-hw_1.xpr/hw/hw.runs/synth_1/D:/WorkRaduV/Projects/Zybo-Z7/hw/proj/hw.srcs/utils_1/imports/synth_1/system_wrapper.dcp' does not exist.
Delete system_wrapper.dcp from Sources -> Utility Sources -> utils_1 -> Design Checkpoint -> system_wrapper.dcp and resynthesize.