The next element that I need to tackle for my embedded vision project is the creation of accelerated vision processing IP using Vivado HLS and the xfOpenCV function library. That would allow me to create a component that I could include in my design. There are a lot of examples of this but it was much harder to accomplish process than I expected. I found a Hackster project that essentially demonstrated what I wanted to do Accelerating Image Processing with Ultra96 https://www.hackster.io/dhq/accelerating-image-processing-with-ultra96-caebe6 but I soon discovered that it was missing a lot of detail for an inexperienced user (me).
Accelerating Image Processing with Ultra96
This Hackster project runs through creating the Filter2D IP from the Xilinx xfOpenCV library https://github.com/Xilinx/xfopencv. This seemed like it would be a good tutorial on using Vivado HLS but it proved to be a very frustrating experience. As I expected mismatches in tools versions and libraries and environment make learning really painful.
The first issue was that if you look at the xfOpenCV examples, there is no Filter2D example. It turns out it is in the customconv (custom convolution) example but you actually have to drill down into the C++ code to find the Filter2d_accel function. Not sure why they chose to obfuscate it like this. The example tcl script provided for building the IP with Vivado_HLS is for the dilation function so you need to edit it for each different example.
The example script is fairly simple. In addition to changing the ip and function names, you also need to set the correct part (for the ultra96 it is xczu3eg-sbva484-1-e) and specify the test image.
############################################################ ## Copyright (C) 1986-2019 Xilinx, Inc. All Rights Reserved. ############################################################ open_project dilation_project set_top ip_accel_app add_files ./xf_ip_accel_app.cpp -cflags "-D__SDSVHLS__ -I../../include --std=c++0x" add_files ./xf_dilation_accel.cpp -cflags "-D__SDSVHLS__ -I../../include --std=c++0x" add_files -tb ./testcase55.jpg add_files -tb ./xf_dilation_tb.cpp -cflags "-D__SDSVHLS__ -I../../include --std=c++0x" open_solution "solution1" set_part {xczu9eg-ffvb1156-2-i} -tool vivado create_clock -period 10 -name default #source "./dilation_color/solution1/directives.tcl" csim_design -argv {testcase55.jpg} -clean -compiler gcc csynth_design cosim_design -argv {testcase55.jpg} #export_design -format ip_catalog
My first try at running the script failed because I was missing the libOpenCL and libjpeg62 libraries. I installed those libraries but then the build failed for an "unknown error". I was puzzled until I realized that the repository had been updated to the 2019.1 version of xfOpenCV and I am still using 2018.3. Luckily it is easy to back up to an earlier version of the repository and I downloaded the latest 2018.3 version. Finally I was able to get a successful build. Quite a demoralizing experience for something that should have been extremely simple. I'm now thinking that it might be worth learning SDSoC because that will not just generate the IP but it will also interconnect it.
I decided that I needed to do something more satisfying and I found a couple of articles by Adam Taylor on using the DisplayPort on the Ultra96v2. Finally an example that can be used directly.
MicroZed Chronicles: DisplayPort Controller
https://www.hackster.io/news/microzed-chronicles-displayport-controller-part-one-25734db13fad
https://www.hackster.io/news/microzed-chronicles-displayport-controller-part-two-1fa042f7a242
Code on github: https://github.com/ATaylorCEngFIET/Ultra96V2_DisplayPort
This example uses the Test Pattern Generator (TPG) IP to send test patterns to the display port. I had some fun trying out the different patterns and I made a short video showing a few of them.