本来写了一篇关于在HLS中使用xfOpenCV的记录,一步一步,但不小心删掉了。只能重新大致回忆下,肯定没有之前的全面。
我是在github上下载xfOpenCV https://github.com/Xilinx/xfopencv/tree/master/HLS_Use_Model 并仔细查看这个pdf文档。我跑了他这个例子,在HLS上跑起来了:
因为我是将整个xfOpenCV文件夹放在工程下面,所以这样填写CFLAGS!仿真综合都没有问题。
但这个pdf中有介绍 :
看文档这个cpp里应用了hls相应头文件中的hls::stream<ap_axiu> ,也应用了xfOpenCV的头文件中的Mat转xf::Mat的函数!但当我去example/dilation/xf_dilation_tb.cpp中看时,并不是这样写的!!!!!!而且我自己写了一个实例,即应用hls video function和xfOpenCV function 就会报错:"common/xf_axi_sdata.h:90:10: error: redefinition of ‘struct ap_axis<D, U, TI, TD>" !!! There is definition of ap_axis in "xf_axi_sdata.h" and there is the same definition of ap_axis "in hls_video.h" 因为两者头文件都定义了ap_axiu和ap_axis!后来网友建议我用opencv的函数代替hls的函数:https://github.com/Xilinx/xfopencv/issues/17 但他没直接回答是否 hls video function 不可和xfOpenCV function同用?!
我用opencv的函数替代hls的函数以后,出现:
xf_structs.h: In instantiation of ‘class xf::Mat<9, 1456, 1936, 8>’: ../../../src/test.cpp:21:65: required from here ../../../xfOpenCV/include/common/xf_structs.h:378:18: error: no type named ‘name’ in ‘struct DataType<9, 8>’
这是因为:
- XF_8UC3 is not yet supported, although it has been defined in the code. Please see UG1233 page 28 for the list of supported types. Zynq Ultrascale devices only support a maximum interface width of 128-bit. You need to take care of the size of the datatype being resolved for the declared xf::Mat. 原来这个XF_8UC3还不可以使用,后来我将XF_NPPC8替换成XF_NPPC1后,又出现 :
'error: no match for ‘operator>>’ (operand types are ‘RGB_IMAGE {aka xf::Mat<9, 1456, 1936, 1>}’ and ‘RGB_PIXEL {aka xf::Scalar<3, unsigned char>}’)' ! I think it cames from the following code:
这是因为xf::Mat中没有怎么获取像素值的函数,hls中就有>>与<<。所以只能自己写:
xf::Mat<XF_8UC4, MAX_HEIGHT, MAX_WIDTH, NPC1> img(MAX_HEIGHT, MAX_WIDTH);
xf::Scalar<4, unsigned char> src_data;
for(int i=0,i<4;i++){
src_data.val[i] = img.data[0].range(8*i+7,i*8);
}
后来又出现这个错误:
Starting C simulation ...
/opt/Xilinx/Vivado/2018.2/bin/vivado_hls /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/solution1/csim.tcl
INFO: [HLS 200-10] Running '/opt/Xilinx/Vivado/2018.2/bin/unwrapped/lnx64.o/vivado_hls'
INFO: [HLS 200-10] For user 'root' on host 'jumper' (Linux_x86_64 version 4.4.0-134-generic) on Thu Sep 13 10:17:14 CST 2018
INFO: [HLS 200-10] On os Ubuntu 16.04 LTS
INFO: [HLS 200-10] In directory '/home/jumper/FPGA_projects/HLS2018.2'
INFO: [HLS 200-10] Opening project '/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd'.
INFO: [HLS 200-10] Opening solution '/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/solution1'.
INFO: [SYN 201-201] Setting up clock 'default' with a period of 10ns.
INFO: [HLS 200-10] Setting target device to 'xc7z035ffg676-2'
INFO: [SIM 211-2] *************** CSIM start ***************
INFO: [SIM 211-4] CSIM will launch GCC as the compiler.
Compiling ../../../src/test.cpp in debug mode
Compiling ../../../src/XiangAnWO3.cpp in debug mode
Generating csim.exe
@E Simulation failed: SIGSEGV.
ERROR: [SIM 211-100] CSim failed with errors.
INFO: [SIM 211-3] *************** CSIM finish ***************
4
while executing
"source /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/solution1/csim.tcl"
invoked from within
"hls::main /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/solution1/csim.tcl"
("uplevel" body line 1)
invoked from within
"uplevel 1 hls::main {*}$args"
(procedure "hls_proc" line 5)
invoked from within
"hls_proc $argv"
Finished C simulation.
这个多半是因为以下原因引起的,但是我没找到我代码是哪里的问题,我只能先将申请内存的地方去掉简化代码:https://github.com/dgschwend/zynqnet/issues/15 https://forums.xilinx.com/t5/Vivado-High-Level-Synthesis-HLS/Simulation-failed-SIGSEGV-Do-not-understand-how-to-use-malloc/m-p/790786 其中这个网址还讲了综合时常会出现的警告原因:
WARNING: Hls::stream 'hls::stream<ap_axiu<24, 1, 1, 1> >.2' is read while empty, which may result in RTL simulation hanging.
this is because you're only buffering the pixel data itself - not the side-channel data that goes with it in the stream (TUSER and TLAST in particular). The AXIvideo2IplImage function probably relies on TUSER/TLAST to tell it where the ends of the image are; without those it's just reading forever (and causing the problem you describe). You will need to either buffer all the data (ie _buff should have type stream_24, not uint_24) or regenerate the side-channel data in the output loop. 我觉得很好。 记住:因为cv::Mat 不可以作为top函数的参数,更不能指定其INTERFACE为axis!后来修改后综合时又出现这个错误:
WARNING: [SYNCHK 200-23] /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_sobel.hpp:372: variable-indexed range selection may cause suboptimal QoR.
ERROR: [SYNCHK 200-11] /usr/local/include/opencv2/core/mat.inl.hpp:813: Argument 'this' of function 'release' (/usr/local/include/opencv2/core/mat.inl.hpp:813) has an unsynthesizable type (possible cause(s): structure variable cannot be decomposed due to (1) unsupported type conversion; (2) memory copy operation; (3) function pointer used in struct; (4) unsupported pointer comparison).
ERROR: [SYNCHK 200-11] /usr/local/include/opencv2/core/mat.inl.hpp:815: Argument 'this' has an unsynthesizable type 'Mat' (possible cause(s): pointer to pointer or global pointer).
ERROR: [SYNCHK 200-42] /usr/local/include/opencv2/core/mat.inl.hpp:815: pointer comparison is not supported.
ERROR: [SYNCHK 200-71] /usr/local/include/opencv2/core/mat.inl.hpp:816: function 'cv::Mat::deallocate()' has no function body.
ERROR: [SYNCHK 200-61] /usr/local/include/opencv2/core/mat.inl.hpp:820: unsupported memory access on variable 'this' which is (or contains) an array with unknown size at compile time.
ERROR: [SYNCHK 200-71] /usr/local/include/opencv2/core/mat.inl.hpp:796: function 'cv::Mat::create(int, int const*, int)' has no function body.
ERROR: [SYNCHK 200-72] /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_structs.h:636: unsupported c/c++ library function 'malloc'.
ERROR: [SYNCHK 200-41] /usr/local/include/opencv2/core/mat.inl.hpp:78: unsupported pointer reinterpretation from type 'Mat' to type 'Mat<0, 1456, 1936, 1>' on variable 'img1_0'.
ERROR: [SYNCHK 200-71] simpleXFopencv/src/XiangAnWO3.cpp:40: function 'cv::convertScaleAbs(cv::_InputArray const&, cv::_OutputArray const&, double, double)' has no function body.
ERROR: [SYNCHK 200-71] simpleXFopencv/src/XiangAnWO3.cpp:41: function 'cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int)' has no function body.
ERROR: [SYNCHK 200-22] /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_structs.h:591: memory copy is not supported unless used on bus interface possible cause(s): non-static/non-constant local array with initialization).
ERROR: [SYNCHK 200-71] /usr/local/include/opencv2/core/mat.inl.hpp:704: function 'cv::fastFree(void*)' has no function body.
INFO: [SYNCHK 200-10] 12 error(s), 1 warning(s).
ERROR: [HLS 200-70] Synthesizability check failed.
command 'ap_source' returned error code
while executing
"source /home/jumper/FPGA_projects/HLS2018.2/simpleXFopencv/solution1/csynth.tcl"
invoked from within
"hls::main /home/jumper/FPGA_projects/HLS2018.2/simpleXFopencv/solution1/csynth.tcl"
("uplevel" body line 1)
invoked from within
"uplevel 1 hls::main {*}$args"
(procedure "hls_proc" line 5)
invoked from within
"hls_proc $argv"
Finished C synthesis.
我将xilinx/Vivado/2018.2/include下的opencv和opencv2都拷贝到了/usr/local/include下,但竟然找不到函数体啊?!
为什么xfOpenCV的例子可以跑起来,这个就跑不起来?!我看了xfOpenCV的例子都是将opencv的函数用在testbeach中,难道是不能应用在source中?!然后我用debug调试:在快要退出之前有保存图像,就在保存图像那里报错:No source available for "icvCvt_BGR2RGB_8u_C3R() at 0x7ffff738f494" 然后我就将保存图像去掉:
#include "XiangAnWO3.h"
int main (int argc, char** argv)
{
cv::Mat src = cv::imread("lena.jpg");
if(!src.data)
{
printf("imread image failed !\n");
return -1;
}
cv::Mat dst(src.rows,src.cols, CV_8UC3);
static xf::Mat<XF_8UC3, MAX_HEIGHT, MAX_WIDTH, NPC1> src_axi(MAX_HEIGHT,MAX_WIDTH);
static xf::Mat<XF_8UC1, MAX_HEIGHT, MAX_WIDTH, NPC1> src_axi2(MAX_HEIGHT,MAX_WIDTH);
src_axi.copyTo(src.data);
FindTarget(src_axi,src_axi2);
dst.data=src_axi2.copyFrom();
// cv::imwrite("result.jpg",dst);
return 0;
}
#ifndef _XIANGANWO3_H_
#define _XIANGANWO3_H_
//#include "hls_video.h"
//#include "hls_opencv.h"
#include <ap_int.h>
#include "hls_stream.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_sw_utils.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_axi.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_infra.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_dilation.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_erosion.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_sobel.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_threshold.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/core/xf_magnitude.hpp"
typedef ap_uint<1> uint1;
typedef ap_uint<11> uint11;
// maximum image size
//#define MAX_WIDTH 1936
//#define MAX_HEIGHT 1456
#define MAX_WIDTH 512
#define MAX_HEIGHT 512
typedef xf::Scalar<4, unsigned char> RGB_PIXEL;
typedef xf::Scalar<1, unsigned char> GRAY_PIXEL;
#define NPC1 XF_NPPC1
typedef xf::Mat<XF_8UC3, MAX_HEIGHT, MAX_WIDTH, NPC1> RGB_IMAGE;
typedef xf::Mat<XF_8UC1, MAX_HEIGHT, MAX_WIDTH, NPC1> GRAY_IMAGE;
void FindTarget(RGB_IMAGE& srcImage,GRAY_IMAGE& dstImage);
#endif
#include "XiangAnWO3.h"
void FindTarget(RGB_IMAGE& srcImage,GRAY_IMAGE& dstImage)
{
#pragma HLS DATAFLOW
GRAY_IMAGE img1_1(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img2(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img3(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img4(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img5(MAX_HEIGHT, MAX_WIDTH);
//#pragma HLS INTERFACE register port=srcImage
//#pragma HLS INTERFACE register port=dstImage
//#pragma HLS STREAM variable=img1_1 depth=1 dim=1
//#pragma HLS STREAM variable=img2 depth=1 dim=1
//#pragma HLS STREAM variable=img3 depth=1 dim=1
//#pragma HLS STREAM variable=img4 depth=1 dim=1
//#pragma HLS STREAM variable=img5 depth=1 dim=1
cv::Mat img1(srcImage.rows,srcImage.cols,CV_8UC1);
cv::Mat img1_0(srcImage.rows,srcImage.cols,CV_8UC3);
//#pragma HLS STREAM variable=img1 dim=1
//#pragma HLS STREAM variable=img1_0 dim=1
img1_0.data=srcImage.copyFrom();
cv::convertScaleAbs(img1_0,img1_0,1.5);
cv::cvtColor(img1_0, img1, CV_BGR2GRAY);
img1_1.copyTo(img1.data);
xf::Threshold<XF_THRESHOLD_TYPE_BINARY,XF_8UC1,MAX_HEIGHT, MAX_WIDTH,NPC1>(img1_1,img2,38,255,0);
xf::erode<XF_BORDER_CONSTANT,XF_8UC1,MAX_HEIGHT, MAX_WIDTH,NPC1>(img2,img3);
xf::erode<XF_BORDER_CONSTANT,XF_8UC1,MAX_HEIGHT, MAX_WIDTH,NPC1>(img3,img4);
xf::erode<XF_BORDER_CONSTANT,XF_8UC1,MAX_HEIGHT, MAX_WIDTH,NPC1>(img4,img5);
xf::Mat<XF_8UC1, MAX_HEIGHT, MAX_WIDTH, NPC1> dsty(MAX_HEIGHT,MAX_WIDTH);
xf::Mat<XF_8UC1, MAX_HEIGHT, MAX_WIDTH, NPC1> dstx(MAX_HEIGHT,MAX_WIDTH);
xf::Sobel<XF_BORDER_CONSTANT,3,XF_8UC1,XF_8UC1,MAX_HEIGHT,MAX_WIDTH,NPC1>(img5, dstx,dsty);
xf::magnitude<XF_L1NORM,XF_8UC1,XF_8UC1, MAX_HEIGHT,MAX_WIDTH,NPC1>(dstx, dsty,dstImage);
}
基本什么都没有加,但调试时在快退出时还是报错:No source available for "__libc_start_main() at 0x7ffff6505830" 但直接仿真却没报错,然后我综合,综合报错“common/xf_axi.h:146:16: error: case value evaluates to 2147483656, which cannot be narrowed to type 'int' [-Wc++11-narrowing]” 于是我去掉了-std=c++0x这个,综合时又是出现:
ERROR: [SYNCHK 200-11] /usr/local/include/opencv2/core/mat.hpp:364: Argument 'Mat.data' of function 'release' (/usr/local/include/opencv2/core/mat.hpp:364) has an unsynthesizable type (possible cause(s): pointer to pointer or global pointer).
ERROR: [SYNCHK 200-42] /usr/local/include/opencv2/core/mat.hpp:350: pointer comparison is not supported.
ERROR: [SYNCHK 200-71] /usr/local/include/opencv2/core/mat.hpp:353: function 'cv::Mat::create(int, int const*, int)' has no function body.
ERROR: [SYNCHK 200-72] /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_structs.h:636: unsupported c/c++ library function 'malloc'.
ERROR: [SYNCHK 200-61] /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_structs.h:645: unsupported memory access on variable which is (or contains) an array with unknown size at compile time.
ERROR: [SYNCHK 200-71] simpleXFopencv/src/XiangAnWO3.cpp:27: function 'cv::_InputArray::_InputArray(cv::Mat const&)' has no function body.
ERROR: [SYNCHK 200-71] simpleXFopencv/src/XiangAnWO3.cpp:27: function 'cv::_OutputArray::_OutputArray(cv::Mat&)' has no function body.
ERROR: [SYNCHK 200-71] simpleXFopencv/src/XiangAnWO3.cpp:27: function 'cv::convertScaleAbs(cv::_InputArray const&, cv::_OutputArray const&, double, double)' has no function body.
ERROR: [SYNCHK 200-71] simpleXFopencv/src/XiangAnWO3.cpp:28: function 'cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int)' has no function body.
ERROR: [SYNCHK 200-22] /home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_structs.h:591: memory copy is not supported unless used on bus interface possible cause(s): non-static/non-constant local array with initialization).
ERROR: [SYNCHK 200-41] /usr/local/include/opencv2/core/mat.hpp:278: unsupported pointer reinterpretation from type 'Mat' to type 'Mat' on variable 'img1_0.step.p'.
ERROR: [SYNCHK 200-71] /usr/local/include/opencv2/core/mat.hpp:278: function 'cv::fastFree(void*)' has no function body.
INFO: [SYNCHK 200-10] 12 error(s), 1 warning(s).
ERROR: [HLS 200-70] Synthesizability check failed.
command 'ap_source' returned error code
真是碰了鬼了。我觉得国内关于vivado HLS优化的论坛和讨论交流群要搞起来!!!这个报错很可能是因为我用的这两个opencv函数不支持综合?!那么我就再一次面临第一个问题了,用hls的函数代替这两个opencv函数,那hls_video.h和xfOpenCV/include/common/xf....h 中有重定义问题怎么解决?!!!!我是将xfOpenCV中定义ap_axiu和ap_axis的头文件定义语句删掉,换成#include "hls_video.h"即可。这样即不破坏通用性改动又最小,已仿真综合,无错误。
另外,不要将hls_opencv.h文件包含在source文件里!!!它只能在testBeach文件里!!!
#include "XiangAnWO3.h"
#include "hls_opencv.h"
int main (int argc, char** argv)
{
cv::Mat src = cv::imread("lena.jpg");
if(!src.data)
{
printf("imread image failed !\n");
return -1;
}
cv::Mat dst(src.rows,src.cols, CV_8UC3);
AXI_STREAM src_axi;
static xf::Mat<XF_8UC1, MAX_HEIGHT, MAX_WIDTH, NPC1> src_axi2(MAX_HEIGHT,MAX_WIDTH);
cvMat2AXIvideo(src, src_axi);
FindTarget(src_axi,src_axi2);
dst.data=src_axi2.copyFrom();
cv::imwrite("result.jpg",dst);
return 0;
}
#ifndef _XIANGANWO3_H_
#define _XIANGANWO3_H_
#include "hls_video.h"
#include <ap_int.h>
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_sw_utils.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_axi.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/common/xf_infra.h"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_dilation.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_erosion.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_sobel.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/imgproc/xf_threshold.hpp"
#include "/home/jumper/FPGA_projects/HLS2018.2/xiangAn_wd/xfOpenCV/include/core/xf_magnitude.hpp"
typedef ap_uint<1> uint1;
typedef ap_uint<11> uint11;
// maximum image size
//#define MAX_WIDTH 1936
//#define MAX_HEIGHT 1456
#define MAX_WIDTH 512
#define MAX_HEIGHT 512
typedef xf::Scalar<4, unsigned char> RGB_PIXEL;
typedef xf::Scalar<1, unsigned char> GRAY_PIXEL;
#define NPC1 XF_NPPC1
typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM;
typedef hls::Mat<MAX_HEIGHT, MAX_WIDTH, HLS_8UC3> HLS_RGB_IMAGE;
typedef hls::Mat<MAX_HEIGHT, MAX_WIDTH, HLS_8UC1> HLS_GRAY_IMAGE;
//typedef hls::stream<ap_axiu<8,1,1,1> > AXI_STREAM_GRAY;
typedef xf::Mat<XF_8UC3, MAX_HEIGHT, MAX_WIDTH, NPC1> RGB_IMAGE;
typedef xf::Mat<XF_8UC1, MAX_HEIGHT, MAX_WIDTH, NPC1> GRAY_IMAGE;
void FindTarget(AXI_STREAM& srcImage,GRAY_IMAGE& dstImage);
#endif
#include "XiangAnWO3.h"
void FindTarget(AXI_STREAM& srcImage,GRAY_IMAGE& dstImage)
{
#pragma HLS DATAFLOW
GRAY_IMAGE img1_1(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img2(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img3(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img4(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img5(MAX_HEIGHT, MAX_WIDTH);
//#pragma HLS INTERFACE register port=srcImage
//#pragma HLS INTERFACE register port=dstImage
//#pragma HLS STREAM variable=img1_1 depth=1 dim=1
//#pragma HLS STREAM variable=img2 depth=1 dim=1
//#pragma HLS STREAM variable=img3 depth=1 dim=1
//#pragma HLS STREAM variable=img4 depth=1 dim=1
//#pragma HLS STREAM variable=img5 depth=1 dim=1
HLS_RGB_IMAGE src(MAX_HEIGHT,MAX_WIDTH);
HLS_RGB_IMAGE img1(MAX_HEIGHT,MAX_WIDTH);
HLS_GRAY_IMAGE img1gray(MAX_HEIGHT,MAX_WIDTH);
hls::AXIvideo2Mat(srcImage, src);
hls::Scale(src,img1,1.5);
hls::CvtColor<HLS_BGR2GRAY>(img1, img1gray);
AXI_STREAM grayimg;
hls::Mat2AXIvideo(img1gray, grayimg);
xf::AXIvideo2xfMat(grayimg, img1_1);
xf::Threshold<XF_THRESHOLD_TYPE_BINARY,XF_8UC1,MAX_HEIGHT, MAX_WIDTH,NPC1>(img1_1,img2,38,255,0);
xf::erode<XF_BORDER_CONSTANT,XF_8UC1,MAX_HEIGHT, MAX_WIDTH,NPC1>(img2,img3);
xf::erode<XF_BORDER_CONSTANT,XF_8UC1,MAX_HEIGHT, MAX_WIDTH,NPC1>(img3,img4);
xf::erode<XF_BORDER_CONSTANT,XF_8UC1,MAX_HEIGHT, MAX_WIDTH,NPC1>(img4,img5);
xf::Mat<XF_8UC1, MAX_HEIGHT, MAX_WIDTH, NPC1> dsty(MAX_HEIGHT,MAX_WIDTH);
xf::Mat<XF_8UC1, MAX_HEIGHT, MAX_WIDTH, NPC1> dstx(MAX_HEIGHT,MAX_WIDTH);
xf::Sobel<XF_BORDER_CONSTANT,3,XF_8UC1,XF_8UC1,MAX_HEIGHT,MAX_WIDTH,NPC1>(img5, dstx,dsty);
xf::magnitude<XF_L1NORM,XF_8UC1,XF_8UC1, MAX_HEIGHT,MAX_WIDTH,NPC1>(dstx, dsty,dstImage);
}
至此,初次使用基本已经告一段落!
1,谨慎再谨慎,在vivado HLS中使用普通opencv函数,因为opencv函数源码你不能保证它直到最底层的实现没有包含动态分配内存、调用系统函数、使用不可综合的类型。。。这会让最后的综合报错!!!像cv::cvtColor就无法综合。
2,xfOpenCV/include/common/xf_..h的头文件像我那样修改后,不会再报重定义的错。可以愉快的和hls video function结合使用来完成用户功能!
3,cv::Mat类型不要用作为 top函数的参数!不过好像可以作为子函数的参数?!
**********************************************************************
************************************************************************
我刚刚试了一下在vivado HLS中使用opencv的cv::findContours() 函数,发现综合会出问题,即报“has no function body...”之类的问题,我想意思就是不可综合!?其实想想也是,如果这个函数是可综合的,那为什么hls video function里面没有,xilinx做这个hls video function library的应该是一个团队吧,人家没写进去,可能就是因为把这个函数变成可综合有难度吧!!!如果真是这样,那么能在vivado HLS中使用普通opencv又有什么意思呢?反正能在HLS下综合的opencv函数都被xilinx团队加入了hls video function 那么直接使用hls:: 对应的函数即可。如果hls::下没有的函数,那基本上不可综合的,那怎么用进来。?我知道了,现在vivado HLS中只有testBeach中可以使用opencv函数,而在source中不可以,因为source中的所有是要被综合的,只可以使用 xfOpenCV+hls video function !在Sdx中可以使用 opencv+xfOpenCV+hls video function ,其中opencv会自动在PS端执行,xfOpenCV+hls video function会在PL端执行。
但是我刚刚在Sdx中跑Sdx example没有问题,但跑一个xfOpenCV example或者就拿我上面那个xfOpenCV的小例子也会报错:其中我是应用Sdx GUI-xilinx-Sdx Libraries-add to project,编译时报了一堆错:类似:
/opt/Xilinx/Vivado/2018.2/include/etc/ap_private.h:1863:20: error: ‘fprintf’ was not declared in this scope
我刚刚发现:我将Sdx GUI-xilinx-Sdx Libraries-add to project,会在工程设置中出现很多头文件路径和库:
然而可以看到我根本没有这些环境变量,所以这些路径加了也是无用。就像这里自动加载的第7条路径,在我电脑上其实不是这样,而是/opt/Xilinx/SDK/2018.2/gnu/aarch64/lin/aarch64-linux/aarch64-linux-gnu/include/c++/7.2.1 !!!所以我要先把路径的事情解决。我对照自己的路径修改后:因为SYSROOT的路径我的确找不到,所以我将它删掉了。
编译,报错:
Performing accelerator source linting for FindTarget
ERROR: [Linting 83-3004] Linting: hls::stream is not supported! @ ../src/XiangAnWO3.h:44:17
ERROR: [SdsCompiler 83-5111] sdslint exited with non-zero code processing /home/jumper/FPGA_projects/sdsoc2018.2/cleanxfOpenCV/src/XiangAnWO3.cpp for accelerator FindTarget
make: *** [src/XiangAnWO3.o] Error 1
Please correct any compilation or sds++ compatibility issues.
sds++ log file saved as /home/jumper/FPGA_projects/sdsoc2018.2/cleanxfOpenCV/Release/_sds/reports/sds_XiangAnWO3.log
ERROR: [SdsCompiler 83-5004] Build failed
However remember that SDSoC does not support hls::stream as arguments to hw accelerated functions. So when you move the HLS code into SDSoC you would have to either
- remove the stream constructs from the top-level function interface (stream can still be used in lower-level functions).
- add a wrapper which handles the conversion to HLS stream.
I personally prefer writing a wrapper if my HLS code is already tested and verified.
原来Sdx不支持hls::stream作为硬件加速函数的参数!!!!
将hls::stream用xf::Mat转化后或者直接用xfOpenCV的例子后报错如下:
INFO: [DMAnalysis 83-4494] Analyzing hardware accelerators...
ERROR: [DMAnalysis 83-4432] An unsupported inferred interface type (ap_memory) was detected
for the port p_src_data_V_q0 (name maybe encoded) of accelerator dilation_accel. Near /home/jumper/FPGA_projects/sdsoc2018.2/cleanxfOpenCV/src/xf_dilation_accel.cpp:33
[SUGGESTION]: Please check the argument declaration. For array, we recommend linearized array type
or pointer type enhanced with pragmas as needed. Please refer to documentation on Pragma SDS data.
/opt/Xilinx/SDx/2018.2/bin/XidanePass: 行 14: gawk: 未找到命令
Data motion generation exited with return code 1
- errors detected
sds++ log file saved as /home/jumper/FPGA_projects/sdsoc2018.2/cleanxfOpenCV/Release/_sds/reports/sds.log
ERROR: [SdsCompiler 83-5004] Build failed
makefile:45: recipe for target 'cleanxfOpenCV.elf' failed
make: *** [cleanxfOpenCV.elf] Error 1
在apt install gawk后, 报错:
Generating data motion network
INFO: [DMAnalysis 83-4494] Analyzing hardware accelerators...
ERROR: [DMAnalysis 83-4432] An unsupported inferred interface type (ap_memory) was detected
for the port p_src_data_V_q0 (name maybe encoded) of accelerator dilation_accel. Near /home/jumper/FPGA_projects/sdsoc2018.2/cleanxfOpenCV/src/xf_dilation_accel.cpp:33
[SUGGESTION]: Please check the argument declaration. For array, we recommend linearized array type
or pointer type enhanced with pragmas as needed. Please refer to documentation on Pragma SDS data.
Data motion generation exited with return code 1
- errors detected
sds++ log file saved as /home/jumper/FPGA_projects/sdsoc2018.2/cleanxfOpenCV/Release/_sds/reports/sds.log
ERROR: [SdsCompiler 83-5004] Build failed
makefile:45: recipe for target 'cleanxfOpenCV.elf' failed
make: *** [cleanxfOpenCV.elf] Error 1
19:53:46 Build Finished (took 38s.15ms)
貌似找到了解决办法:
ap_memory ports are not supported in SDSoC. SDSoC supports: ap_none/ovld/BRAM/FIFO/AXIS/M_AXI
You might have to use a zero_copy pragma to get an M_AXI interface for your port.
发现Sdx真是事儿多!!!
上面的报错是因为函数dilation_accel中的参数有Sdsoc不支持的ap_memory类型。解决办法:
#pragma SDS data access_pattern("_src.data":SEQUENTIAL, "_dst.data":SEQUENTIAL)
#pragma SDS data copy("_src.data"[0:"_src.size"], "_dst.data"[0:"_dst.size"])
#pragma SDS data mem_attribute("_src.data":NON_CACHEABLE|PHYSICAL_CONTIGUOUS)
#pragma SDS data mem_attribute("_dst.data":NON_CACHEABLE|PHYSICAL_CONTIGUOUS)
void dilation_accel(xf::Mat<TYPE, HEIGHT, WIDTH, NPC1> &_src,xf::Mat<TYPE, HEIGHT, WIDTH, NPC1> &_dst);
不再报那个错,报错是:
Preliminary link application ELF
/opt/Xilinx/Vivado/2018.2/lnx64/tools/opencv/opencv_gcc/libopencv_imgproc.so: file not recognized: 不可识别的文件格式
collect2: error: ld returned 1 exit status
这个错是因为库的版本问题比如有32位和64位冲突的问题,我用的是:/opt/Xilinx/SDx/2018.2/lnx64/tools/opencv这个路径下的库,然后我把这个路径从settings中去掉,报错换成:
Preliminary link application ELF
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: 找不到 -lopencv_imgproc
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: 找不到 -lopencv_highgui
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: 找不到 -lopencv_core
collect2: error: ld returned 1 exit status
看这个错误信息,居然用的是aarch32也就是32位编译器去链接我的64位库?所以才报错说冲突了。我疑惑的是为什么不用/opt/Xilinx/SDK/2018.2/gnu/aarch64/lin/aarch64-linux/aarch64-linux-gnu/bin...为什么不用64位的,这个是在哪里指定的?!可能是compiler 和linker那里指定的?!我终于知道了是板子决定的:因为zcu102的arm处理器是Cortex-A53,64位架构,而ZedBoard的arm处理器是Cortex-A9,32位架构!这在project.sdx中的System configuration中就可以看到,当我选择zcu102时出现的就是:/opt/Xilinx/SDK/2018.2/gnu/aarch64/lin/aarch64-linux/bin/..但是依旧会报找不到libjpeg?!明明我将libjpeg路径加入了settings啊?!
我发现SDK下面有一个ThirdParty文件夹下面有32位的opencv库,于是我将32位的include和lib都加进来替换原来的后,报错是:
Preliminary link application ELF
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libgtk-3.so.0, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libgdk-3.so.0, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libcairo.so.2, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libgdk_pixbuf-2.0.so.0, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libgobject-2.0.so.0, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libglib-2.0.so.0, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libjpeg.so.62, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_imgcodecs.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libwebp.so.6, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_imgcodecs.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libpng16.so.16, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_imgcodecs.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ld: warning: libtiff.so.5, needed by /opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_imgcodecs.so, not found (try using -rpath or -rpath-link)
/opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_imgcodecs.so:对‘png_set_filter@PNG16_0’未定义的引用
/opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_imgcodecs.so:对‘png_get_IHDR@PNG16_0’未定义的引用
/opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_imgcodecs.so:对‘png_create_read_struct@PNG16_0’未定义的引用
/opt/Xilinx/SDK/2018.2/data/embeddedsw/ThirdParty/opencv/aarch32/lib/libopencv_highgui.so:对‘g_time_val_add’未定义的引用
缺少libgtk、libcairo、libjpeg等库,然后我看了我电脑里有这些库,但都是64位的!!!其实我是不是不该修改库或者增加32位的库,而应该将编译器改成64位的?!这样改动最少。
我下载安装32 位libjpeg试试:
apt-get install libjpeg62:i386 对应路径是/usr/lib/i386-linux-gnu/libjpeg.so.62 我特意看了一下,确实是在这个路径中,然后将这个路径加到settings中。然而编译时还是报错说找不到jpeg的库?!