精华内容
下载资源
问答
  • hls 教程zynq 7000 fpga教程,超过200页的hls教程(含例程),手把手教会你hlshls 教程zynq 7000 fpga教程,超过200页的hls教程(含例程),手把手教会你hls
  • Vivado HLSzynq TRD)源码分析

    千次阅读 2015-10-22 22:44:49
    这里不同于xapp1167,直接调用hls::cv的库函数,sobel边缘提取算法是重新实现的,更方便了解hls的算法实现的特点。 void image_filter(AXI_STREAM& video_in, AXI_STREAM& video_out, int rows, int cols,...

    概述

    源码是官方的2014.4 TRD工程里的,整个工程是基于zc702板子的,但手里只有块小zybo >_< 里面的硬件设计很有参考价值,最近想用FPGA加速surf算法,先在这分析下TRD工程里sobel edge detection的例程。

    wiki

    Top Function

    这里不同于xapp1167,直接调用hls::cv的库函数,sobel边缘提取算法是重新实现的,更方便了解hls的算法实现的特点。

    void image_filter(AXI_STREAM& video_in, AXI_STREAM& video_out, int rows, int cols,
                      int C_XR0C0, int C_XR0C1, int C_XR0C2, int C_XR1C0, int C_XR1C1, int C_XR1C2, int C_XR2C0, int C_XR2C1, int C_XR2C2,
                      int C_YR0C0, int C_YR0C1, int C_YR0C2, int C_YR1C0, int C_YR1C1, int C_YR1C2, int C_YR2C0, int C_YR2C1, int C_YR2C2,
                      int c_high_thresh, int c_low_thresh, int c_invert)
    {
        //Create AXI streaming interfaces for the core
        //这里定义axi-stream接口用于stream图像数据
    #pragma HLS INTERFACE axis port=video_in bundle=INPUT_STREAM
    #pragma HLS INTERFACE axis port=video_out bundle=OUTPUT_STREAM
    
    
    //设置rows、cols 为axilite总线上的寄存器,用于改变处理图像的大小(图像的最大尺寸为1920*1080)
    #pragma HLS INTERFACE s_axilite port=rows bundle=CONTROL_BUS offset=0x14
    #pragma HLS INTERFACE s_axilite port=cols bundle=CONTROL_BUS offset=0x1C
    #pragma HLS INTERFACE s_axilite port=return bundle=CONTROL_BUS
    
    //#pragma HLS INTERFACE ap_stable port=rows
    //#pragma HLS INTERFACE ap_stable port=cols
    
    //设置sobel算子x、y方向的滤波模板 方便PS端改变模板(比如可以改成Prewitt算子)
    #pragma HLS INTERFACE s_axilite port= C_XR0C0 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_XR0C1 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_XR0C2 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_XR1C0 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_XR1C1 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_XR1C2 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_XR2C0 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_XR2C1 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_XR2C2 bundle=CONTROL_BUS
    
    #pragma HLS INTERFACE s_axilite port= C_YR0C0 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_YR0C1 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_YR0C2 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_YR1C0 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_YR1C1 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_YR1C2 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_YR2C0 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_YR2C1 bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= C_YR2C2 bundle=CONTROL_BUS
    //x、y阈值
    #pragma HLS INTERFACE s_axilite port= c_high_thresh bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= c_low_thresh bundle=CONTROL_BUS
    #pragma HLS INTERFACE s_axilite port= c_invert bundle=CONTROL_BUS
    
        YUV_IMAGE img_0(rows, cols);
        YUV_IMAGE img_1(rows, cols);
    #pragma HLS dataflow
    //将axi-stream 转换为 hls::mat (hls::mat是数据流的形式)
        hls::AXIvideo2Mat(video_in, img_0);
    //sobel edge detection implement
        sobel_filter_core(img_0, img_1, rows, cols,
                          C_XR0C0, C_XR0C1, C_XR0C2, C_XR1C0, C_XR1C1, C_XR1C2, C_XR2C0, C_XR2C1, C_XR2C2,
                          C_YR0C0, C_YR0C1, C_YR0C2, C_YR1C0, C_YR1C1, C_YR1C2, C_YR2C0, C_YR2C1, C_YR2C2,
                          c_high_thresh, c_low_thresh, c_invert);
    //hls::mat 转换为axi-stream输出
        hls::Mat2AXIvideo(img_1, video_out);
    }
    

    top function 是一个标准的hls 图像处理结构,具体内容请参看xapp1167文档

    sobel_filter_core

    void sobel_filter_core(YUV_IMAGE& src, YUV_IMAGE& dst, int rows, int cols,
                           int C_XR0C0, int C_XR0C1, int C_XR0C2, int C_XR1C0, int C_XR1C1, int C_XR1C2, int C_XR2C0, int C_XR2C1, int C_XR2C2,
                           int C_YR0C0, int C_YR0C1, int C_YR0C2, int C_YR1C0, int C_YR1C1, int C_YR1C2, int C_YR2C0, int C_YR2C1, int C_YR2C2,
                           int c_high_thresh, int c_low_thresh, int c_invert)
    {
    
    
      Y_BUFFER buff_A;
      Y_WINDOW buff_C;
    //Y_BUFFER Y_WINDOW 定义如下
    //typedef hls::Window<3, 3, unsigned char>              Y_WINDOW;
    //typedef hls::LineBuffer<3, MAX_WIDTH, unsigned char>  Y_BUFFER;
    //hls特有的memory结构 具体特征说明见下方
    
      for(int row = 0; row < rows+1; row++){
        for(int col = 0; col < cols+1; col++){
    #pragma HLS loop_flatten off
    // loop_flatten 选项说明
    //Allows nested loops to be collapsed into a single loop with improved latency.
    //
    #pragma HLS dependence variable=&buff_A false
    // dependence 选项说明
    //Used to provide additional information that can overcome loop-carry dependencies and allow loops to be pipelined (or pipelined with lower intervals).
    #pragma HLS PIPELINE II = 1
    // PIPELINE 选项说明 
    //Reduces the initiation interval by allowing the concurrent execution of operations within a loop or function.
    //流水的迭代次数为1
    
          // Temp values are used to reduce the number of memory reads
          unsigned char temp;
          YUV_PIXEL tempx;
    
          //Line Buffer fill
          if(col < cols){
              buff_A.shift_down(col);
              //行存shift
              temp = buff_A.getval(0,col);
              //这里的行存里的row = 0 和row = 1 的值是相同的
          }
    
          //There is an offset to accomodate the active pixel region
          //There are only MAX_WIDTH and MAX_HEIGHT valid pixels in the image
          if(col < cols && row < rows){
              YUV_PIXEL new_pix;
              src >> new_pix;
              tempx = new_pix;
              buff_A.insert_bottom(tempx.val[0],col);
              //插入新值
          }
    
          //Shift the processing window to make room for the new column
          buff_C.shift_right();
          //窗右移空出一列
    
          //The Sobel processing window only needs to store luminance values
          //rgb2y function computes the luminance from the color pixel
          if(col < cols){
          //将数据从行存里复制到窗中,
          //对于这里为什么将之前的 temp = buff_A.getval(0,col)
          //而不是直接复制行存中row=1的数据,就如同对行存中row=2的数据的操作
          //eg:  buff_C.insert(buff_A.getval(2,col),2,0);
          //     buff_C.insert(buff_A.getval(1,col),1,0);
          //     buff_C.insert(tempx.val[0],0,0);
          //有疑问,猜想可能是Synthesis的时候并行化有影响
              buff_C.insert(buff_A.getval(2,col),2,0);
              buff_C.insert(temp,1,0);
              buff_C.insert(tempx.val[0],0,0);
          }
          YUV_PIXEL edge;
          //如下是基本的sobel算法的流程了 注意图像边缘的位置排除
          //The sobel operator only works on the inner part of the image
          //This design assumes there are no edges on the boundary of the image
          if( row <= 1 || col <= 1 || row > (rows-1) || col > (cols-1)){
              edge.val[0] = 0;
              edge.val[1] = 128;
          } else {
              //Sobel operation on the inner portion of the image
              edge = sobel_operator(&buff_C,
                                    C_XR0C0, C_XR0C1, C_XR0C2, C_XR1C0, C_XR1C1, C_XR1C2, C_XR2C0, C_XR2C1, C_XR2C2,
                                    C_YR0C0, C_YR0C1, C_YR0C2, C_YR1C0, C_YR1C1, C_YR1C2, C_YR2C0, C_YR2C1, C_XR2C2,
                                    c_high_thresh, c_low_thresh, c_invert);
          }
    
          //The output image is offset from the input to account for the line buffer
          if(row > 0 && col > 0) {
              dst << edge;
          }
        }
      }
    }
    

    参照ug902文档

    hls::LineBuffer

    The main features of the LineBuffer class are:
    • Support for all data types through parameterization
    • User-defined number of rows and columns
    • Automatic banking of rows into separate memory banks for increased memory
    bandwidth
    • Provides all the methods for using and debugging line buffers in an algorithmic design

    hls::Window

    • Support for all data types through parametrization
    • User-defined number of rows and columns
    • Automatic partitioning into individual registers for maximum bandwidth
    • Provides all the methods to use and debug memory windows in the context of an
    algorithm

    由于采用的是stearm流的形式处理图像数据,所以并不能访问图像上任意一点的值,为了方便滤波模板的操作提供了这两种数据结构,这里的sobel算子要求有一个3*3大小的窗与模板相乘,要产生这样的窗则需要一个三行数据的行存,两层的row、col循环中每次都把行存中col列的数据shift_down操作然后将新得到的数据插入到底部,注意这里和ug902的文档有出入,查看源码,发现ug902的文档上是错的 源码中定义的 top和bottom方向如下

    /* Member functions of LineBuffer class */
    
    /*     +---+---+-... ...-+---+---+
     * R-1 |   |   |         |   |   |
     *     +---+---+-... ...-+---+---+  
     * R-2 |   |   |         |   |   |
     *     +---+---+-... ...-+---+---+
     *       ...     ... ...   ...
     *     +---+---+-... ...-+---+---+
     *   1 |   |   |         |   |   |
     *     +---+---+-... ...-+---+---+  
     *   0 |   |   |         |   |   |
     *     +---+---+-... ...-+---+---+
     *       0   1   ... ...  C-2 C-1   (origin is at bottom-left point)
     */

    可能是官方的文档(v2014.1)没有更新

    sobel_operator

    x、y方向模板与窗相乘 没啥可说的了

    YUV_PIXEL sobel_operator(Y_WINDOW *window,
                       int XR0C0, int XR0C1, int XR0C2, int XR1C0, int XR1C1, int XR1C2, int XR2C0, int XR2C1, int XR2C2,
                       int YR0C0, int YR0C1, int YR0C2, int YR1C0, int YR1C1, int YR1C2, int YR2C0, int YR2C1, int YR2C2,
                       int high_thesh, int low_thresh, int invert)
    {
      short x_weight = 0;
      short y_weight = 0;
    
      short edge_weight;
      unsigned char edge_val;
      YUV_PIXEL pixel;
    
      char i;
      char j;
    
    
      const char x_op[3][3] = {{XR0C0,XR0C1,XR0C2},
                               {XR1C0,XR1C1,XR1C2},
                               {XR2C0,XR2C1,XR2C2}};
    
      const char y_op[3][3] = {{YR0C0,YR0C1,YR0C2},
                               {YR1C0,YR1C1,YR1C2},
                               {YR2C0,YR2C1,YR2C2}};
    
    
      //Compute approximation of the gradients in the X-Y direction
      for(i=0; i < 3; i++){
        for(j = 0; j < 3; j++){
    
          // X direction gradient
          x_weight = x_weight + (window->getval(i,j) * x_op[i][j]);
    
          // Y direction gradient
          y_weight = y_weight + (window->getval(i,j) * y_op[i][j]);
        }
      }
    
      edge_weight = ABS(x_weight) + ABS(y_weight);
    
      if (edge_weight < 255)
        edge_val = (255-(unsigned char)(edge_weight));
      else
        edge_val = 0;
    
      //Edge thresholding
      if(edge_val > high_thesh)
        edge_val = 255;
      else if(edge_val < low_thresh)
        edge_val = 0;
    
      // Invert
      if (invert == 1)
        edge_val = 255 - edge_val;
    
      pixel.val[0] = edge_val;
      pixel.val[1] = 128;
    
      return pixel;
    }
    展开全文
  • ZYNQ HLS 图像算法

    2018-09-12 11:20:29
    这是基于ZYNQ HLS图像处理算法的资料 详细的中文介绍 可以参考一下
  • zynq hls定点数计算

    2021-01-06 11:34:13
    本节介绍如何使用HLS进行定点运算以及如何与zynq cpu交互。 HLS中,有头文件ap_fixed.h,极大的方便了我们使用定点数,具体情况略。 HLS代码示例 #include #include typedef ap_fixed data_t; data_t fixed_test...
  • Zynq开发之HLS

    2018-04-16 13:21:00
    Zynq开发之HLS 由FPGA菜鸟于 星期三, 06/28/2017 - 11:53 发表 HLS简介 HLS(High Level Synthesis)即高层次综合,不同于以往的FPGA逻辑开发,是用HDL编写的,开发周期长、难度大。而HLS可以使用C...
    Zynq开发之HLS

    HLS简介

    HLS(High Level Synthesis)即高层次综合,不同于以往的FPGA逻辑开发,是用HDL编写的,开发周期长、难度大。而HLS可以使用C,C++,SystemC以及OPenCL等编写,通过高层次综合,可以把软件代码转化为硬件描述语言,可以大大加快开发速度,使软件工程师也可以编写硬件语言。

    HLS OpenCV简介

    OpenCV是开源的图像处理和计算机视觉库,它支持多种操作系统、包含多种计算机语言的接口。HLS opencv是HLS里带有的可综合成HDL的OpenCV库函数,换句话说,由于HDL和C++的特性(例如动态内存分配不可以综合成HDL)并不是所有的OpenCV库函数都可以综合成HDL,当然目前Xilinx提供了较多的HLS OpenCV库函数,可以满足一定的需求,相信以后会越来越多的。

    HLS加速模型

    HLS加速模型

     

    HLS OpenCV和OpenCV有着相似的书写风格

    OpenCV library : cvScale(src, dst, scale, shift);
    HLS video library : hls::Scale<…>(src, dst, scale, shift);

    HLS加速模型



     

    加速的opencv应用


     

    开发注意


     

    实例
    #ifndef _IMAGE_CORE_H_
    #define _IMAGE_CORE_H_

    #include"hls_video.h" //这里调用可以综合的视频库

    // maximum image size
    #define MAX_WIDTH 1920
    #define MAX_HEIGHT 1080
    // I/O Image Settings
    #define INPUT_IMAGE "test_1080p.jpg"
    #define OUTPUT_IMAGE "result_1080p.jpg"
    #define OUTPUT_IMAGE_GOLDEN "result_1080p_golden.jpg"

    // typedef video library core structures
    typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_IN;
    typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_OUT;
    typedef hls::Mat<max_height, max_width,="" hls_8uc3=""> RGB_IMAGE;

    // top level function for HW synthesis
    void image_core(AXI_STREAM_IN& src_axi, AXI_STREAM_OUT& dst_axi, int rows, int cols);

    #endif

    #include "image_core.h"

    void image_core(AXI_STREAM_IN& input, AXI_STREAM_OUT& output, int rows, int cols) {
    #pragma HLS RESOURCE variable=input core=AXI4Stream metadata="-bus_bundle INPUT_STREAM"
    #pragma HLS RESOURCE variable=output core=AXI4Stream metadata="-bus_bundle OUTPUT_STREAM"
    #pragma HLS INTERFACE ap_none port=cols
    #pragma HLS INTERFACE ap_none port=rows
    //AP_CONTROL_BUS_AXI(CONTROL_BUS);
    //set_directive_interface -mode ap_ctrl_none hls_sobel
    #pragma HLS interface ap_ctrl_none port=return
    RGB_IMAGE img_0(rows, cols);
    RGB_IMAGE img_1(rows, cols);
    #pragma HLS DATAFLOW // must use data flow to stream the data
    hls::AXIvideo2Mat(input, img_0); //read video stream by frames
    hls::Sobel<1,0,3>(img_0, img_1);//use Hls Sobel
    hls::Mat2AXIvideo(img_1, output); //write the frames to video stream
    }

    将“input”指定为以 “ S INPUT_STREAM” 命名的AXI4 Stream
    #pragma HLS RESOURCE variable=input core=AXIS metadata="-bus_bundle INPUT_STREAM"
    将控制接口分配到AXI4 Lite接口
    #pragma HLS RESOURCE variable=return core=AXI_SLAVE metadata="-bus_bundle CONTROL_BUS"
    指定“rows”可通过AXI4-Lite接口进行访问
    #pragma HLS RESOURCE variable=rows core=AXI_SLAVE metadata="-bus_bundle CONTROL_BUS"
    声明在函数执行过程中 “rows”不会改变
    #pragma HLS INTERFACE ap_stable port=rows
    启用数据流优化
    #pragma HLS dataflow

    C综合
    点击Solution -> Run C Synthesis -> Active Solution
    运行test.cpp C仿真测试
    #include "image_core.h"
    #include "opencv/cv.h"
    #include "opencv/cxcore.h"
    #include "opencv/highgui.h"
    #include "hls_opencv.h"

    int main (int argc, char** argv) {
    IplImage* src = cvLoadImage(INPUT_IMAGE);
    IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
    AXI_STREAM_IN src_axi;
    AXI_STREAM_OUT dst_axi;
    IplImage2AXIvideo(src, src_axi); //将图像转为视频流结构
    image_core(src_axi, dst_axi, src->height, src->width);
    AXIvideo2IplImage(dst_axi, dst);
    cvSaveImage(OUTPUT_IMAGE, dst);
    cvReleaseImage(&src);
    cvReleaseImage(&dst);
    }

    点击Project -> Run C simulation,弹出的对话框点确定即可。


     

    文章来源:skyplain1984的博客

    转载:http://xilinx.eetrend.com/blog/11593

    转载于:https://www.cnblogs.com/chengqi521/p/8855412.html

    展开全文
  • 基于ZYNQHLS 图像算法设计, 是购买的ZYNQ开发板里的图像算法设计文档, 供大家学习fpga开发图像算法方法
  • 基于ZYNQHLS 图像算法设计基础
  • OPENCV是开源计算机视觉库,支持C/C++、PYTHON等多种语言,OPENCV的设计可以直接运行在ZYNQ的PS上,但是用ARM处理高清视频处理的时候,可能就会处理不过来,于是会使用HLS OPENCV进行硬件加速,本文主要是针对HLS的...

    ZYNQ开发之HLS图像处理入门

    HLS(High Level Synthesis)即高层次综合,和以前Verilog及VHDL不一样,通过它可以用C/C++、SystemC及OPENCL编写FPGA程序,实现相应功能,大大加快开发的速度,使软件工程师可以参与到项目中,使硬件工程师可以增加工作效率

    OPENCV是开源计算机视觉库,支持C/C++、PYTHON等多种语言,OPENCV的设计可以直接运行在ZYNQ的PS上,但是用ARM处理高清视频处理的时候,可能就会处理不过来。于是HLS OPENCV就这样出现了(硬件加速),HLS Opencv是HLS自带的、可综合成HDL的OpenCV库函数(因为并不是所有的OpenCV库函数都可以综合成HDL),HLS OPENCV具体的函数操作方法,将写在理论系列(一) HLS OPENCV函数,本文主要是针对HLS的入门操作

    一、运行环境

    这个HLS的版本很重要!!!
    之前尝试用HLS普通的仿真没问题,但是对图像进行C仿真(调用HLS带的函数),仿真编译的时间就很长,而且结果报错:

    cc1plus.exe:-1: error: out of memory allocating ……

    解决方法:不要使用2017.1和2017.2的HLS,降到2016.4,或者升级到2017.3(本文2017.3)

    二、搭建HLS工程

    • 1.新建工程,根据向导设置相关参数
      新建工程的最后一步,新建了一个solution1,时钟周期就默认10ns,然后选择芯片型号,完成工程的创建

    • 2.新建文件
      新建三个文件test.cpp(测试文件)、image_core.cpp(算法核心)以及image_core.h,文件内容

    test.cpp:

    #include "image_core.h"
    #include "opencv/cv.h"
    #include "opencv/cxcore.h"
    #include "opencv/highgui.h"
    #include "hls_opencv.h"
    #define INPUT_IMAGE "test.jpg"
    
    int main (int argc, char** argv) {
        IplImage* src = cvLoadImage(INPUT_IMAGE,0);//读图片灰度
        IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
        AXI_STREAM_IN  src_axi;
        AXI_STREAM_OUT dst_axi;
        IplImage2AXIvideo(src, src_axi); //将图像转为数据流
        image_core(src_axi, dst_axi, src->height, src->width);//输入数据流,进行处理,输出数据流
        AXIvideo2IplImage(dst_axi, dst); //将输出流转回图片
        cvShowImage("src",src);
        cvShowImage("dst",dst);
        cvWaitKey(0);
        cvReleaseImage(&src);
        cvReleaseImage(&dst);
        return 0;
    }

    image_core.cpp:

    #include "image_core.h"
    
    void image_core(AXI_STREAM_IN& input, AXI_STREAM_OUT& output, int rows, int cols){
        #pragma HLS RESOURCE variable=input core=AXI4Stream metadata="-bus_bundle INPUT_STREAM"
        #pragma HLS RESOURCE variable=output core=AXI4Stream metadata="-bus_bundle OUTPUT_STREAM"
        #pragma HLS INTERFACE ap_none port=cols
        #pragma HLS INTERFACE ap_none port=rows
        #pragma HLS interface ap_ctrl_none port=return
    
        RGB_IMAGE img_0(rows, cols);
        RGB_IMAGE img_1(rows, cols);
        #pragma HLS DATAFLOW              // must use data flow to stream the data
        hls::AXIvideo2Mat(input, img_0);  //读输入到img_0
        hls::Sobel<1,0,3>(img_0, img_1);  //Sobel算子,边缘提取
        hls::Mat2AXIvideo(img_1, output); //img_1写到输出
    }

    image_core.h:

    #ifndef _IMAGE_CORE_H_
    #define _IMAGE_CORE_H_
    
    #include"hls_video.h" //调用可以综合的视频库
    
    //图像最大尺寸
    #define MAX_WIDTH 800
    #define MAX_HEIGHT 600
    
    //定义图像处理核,要用到的结构体
    typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_IN;
    typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_OUT;
    typedef hls::Mat<MAX_HEIGHT, MAX_WIDTH, HLS_8UC3> RGB_IMAGE;
    
    //硬件综合的顶层
    void image_core(AXI_STREAM_IN& src_axi, AXI_STREAM_OUT& dst_axi, int rows, int cols);
    
    #endif
    • 3.添加文件到相应位置
      将上述三个文件放在工程目录下,然后如图添加:
      这里写图片描述
      h文件,不需要添加,放在工程目录下即可

    • 4.运行仿真
      点击Run C Simulation按钮,然后直接点确定
      这里写图片描述
      按空格键,关闭图片

    • 5.生成IP核
      点击Run C Synthesis,综合完毕后,然后点击Export RTL
      这里写图片描述
      生成完毕后,即可通过VIVADO调用HLS的IP核(image_core)

    展开全文
  • 计算机视觉技术几年来已发展成为学术界一个相当成熟的科研领域,目前许多视觉算法来自于数十年的科研成果。不过,我们最近发现计算机视觉技术正快速渗透到我们生活的方方面面。现在我们拥有能自动驾驶的汽车、能根据...
  • 《领航者ZYNQHLS开发指南V1.1.pdf》正点原子ZYNQHLS开发资料,非常好的ZYNQ资料,希望对你的工作学习有所帮助。
  • zynq开发之HLS

    千次阅读 2016-12-17 14:31:00
    HLS简介 HLS(High Level Synthesis)即高层次综合,不同于以往的FPGA逻辑开发,是用HDL编写的,开发周期长、难度大。而HLS可以使用C,C++,SystemC以及OPenCL等编写,通过高层次综合,可以把软件代码转化为硬件描述...

    HLS简介

    HLS(High Level Synthesis)即高层次综合,不同于以往的FPGA逻辑开发,是用HDL编写的,开发周期长、难度大。而HLS可以使用C,C++,SystemC以及OPenCL等编写,通过高层次综合,可以把软件代码转化为硬件描述语言,可以大大加快开发速度,使软件工程师也可以编写硬件语言。

    HLS OpenCV简介

    OpenCV是开源的图像处理和计算机视觉库,它支持多种操作系统、包含多种计算机语言的接口。HLS Opencv是HLS里带有的可综合成HDL的OpenCV库函数,换句话说,由于HDL和C++的特性(例如动态内存分配不可以综合成HDL)并不是所有的OpenCV库函数都可以综合成HDL,当然目前Xilinx提供了较多的HLS OpenCV库函数,可以满足一定的需求,相信以后会越来越多的。

    HLS加速模型

    HLS OpenCV和OpenCV有着相似的书写风格

    OpenCV library : cvScale(src, dst, scale, shift); 

    HLS video library : hls::Scale<…>(src, dst, scale, shift); 





    加速的opencv应用



    开发注意




    实例

    #ifndef _IMAGE_CORE_H_
    #define _IMAGE_CORE_H_
    
    #include"hls_video.h" //这里调用可以综合的视频库
    
    // maximum image size
    #define MAX_WIDTH 1920
    #define MAX_HEIGHT 1080
    // I/O Image Settings
    #define INPUT_IMAGE "test_1080p.jpg"
    #define OUTPUT_IMAGE "result_1080p.jpg"
    #define OUTPUT_IMAGE_GOLDEN "result_1080p_golden.jpg"
    
    // typedef video library core structures
    typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_IN;
    typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_OUT;
    typedef hls::Mat<MAX_HEIGHT, MAX_WIDTH, HLS_8UC3> RGB_IMAGE;
    
    // top level function for HW synthesis
    void image_core(AXI_STREAM_IN& src_axi, AXI_STREAM_OUT& dst_axi, int rows, int cols);
    
    #endif

    #include "image_core.h"
    
    void image_core(AXI_STREAM_IN& input, AXI_STREAM_OUT& output, int rows, int cols) {
    	#pragma HLS RESOURCE variable=input core=AXI4Stream metadata="-bus_bundle INPUT_STREAM"
    	#pragma HLS RESOURCE variable=output core=AXI4Stream metadata="-bus_bundle OUTPUT_STREAM"
    	#pragma HLS INTERFACE ap_none port=cols
    	#pragma HLS INTERFACE ap_none port=rows
    	//AP_CONTROL_BUS_AXI(CONTROL_BUS);
    	//set_directive_interface -mode ap_ctrl_none hls_sobel
    	#pragma HLS interface ap_ctrl_none port=return
    	RGB_IMAGE img_0(rows, cols);
    	RGB_IMAGE img_1(rows, cols);
    	#pragma HLS DATAFLOW // must use data flow to stream the data
    	hls::AXIvideo2Mat(input, img_0); //read video stream by frames
    	hls::Sobel<1,0,3>(img_0, img_1);//use Hls Sobel
    	hls::Mat2AXIvideo(img_1, output); //write the frames to video stream
    }

    将“input”指定为以 “ S INPUT_STREAM” 命名的AXI4 Stream
    #pragma HLS RESOURCE variable=input core=AXIS metadata="-bus_bundle INPUT_STREAM"
    将控制接口分配到AXI4 Lite接口
    #pragma HLS RESOURCE variable=return core=AXI_SLAVE metadata="-bus_bundle CONTROL_BUS"
    指定“rows”可通过AXI4-Lite接口进行访问
    #pragma HLS RESOURCE variable=rows core=AXI_SLAVE metadata="-bus_bundle CONTROL_BUS"
    声明在函数执行过程中 “rows”不会改变
    #pragma HLS INTERFACE ap_stable port=rows
    启用数据流优化
    #pragma HLS dataflow


    C综合

    点击Solution -> Run C Synthesis -> Active Solution

    运行test.cpp C仿真测试

    #include "image_core.h"
    #include "opencv/cv.h"
    #include "opencv/cxcore.h"
    #include "opencv/highgui.h"
    #include "hls_opencv.h"
    
    int main (int argc, char** argv) {
        IplImage* src = cvLoadImage(INPUT_IMAGE);
        IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
        AXI_STREAM_IN src_axi;
        AXI_STREAM_OUT dst_axi;
        IplImage2AXIvideo(src, src_axi); //将图像转为视频流结构
        image_core(src_axi, dst_axi, src->height, src->width);
        AXIvideo2IplImage(dst_axi, dst);
        cvSaveImage(OUTPUT_IMAGE, dst);
        cvReleaseImage(&src);
        cvReleaseImage(&dst);
    }
    

    点击Project -> Run C simulation,弹出的对话框点确定即可。 



    展开全文
  • ZYNQ 是来自 Xilinx 公司ZYNQ-7000 所有可编程片上系统的开发板,具有开发片上系统能力。 在 ZYNQ上,ARM Cortex-A9 是一个应用级的处理器,能运行完整的像 Linux 这样的操作系统,而可编程逻辑是基于 Xilinx 7 ...
  • ALINX_ZYNQ开发平台HLS教程V1.03
  • ZYNQ HLS工具系列(一)中,体会到了HLS的强大,本篇将持续积累对HLS的学习,加固HLS的基础 一、HLS工作过程 如图,HLS的C到硬件,有几个重要步骤: 调度: 用来确定操作发生于哪几个时钟周期(以及是否...
  • ZYNQ-vivado HLS工具

    千次阅读 2018-01-31 14:11:26
    设计简单算法体验Vivado HLS的使用 前言  本文主要讲解了使用Vivado HLS设计简单C语言的二选一选择器算法的硬件HLS开发的全流程,包括工程创建-算法验证和仿真-算法综合-RTL仿真-IP封装等步骤。 参考网站:  ...
  • 内部教程-基于ZYNQHLS 图像算法设计基础milian教程
  • zynq linux调用HLS IP核

    2020-11-28 13:41:44
    1.HLS IP开发 这里仅作示例,写了一个最简单的HLS IP核,通过AXI Lite总线和ARM相连,代码编写如下: void adder(int a, int b, int& c) { #pragma HLS INTERFACE s_axilite port=a #pragma HLS INTERFACE s_...
  • zynq系列的fpga开发板,HLS使用教程。内容详细,指导全面,小白也可使用入门。亲测好用。内容详细,指导全面,小白也可使用入门。亲测好用。
  • 使用自己用hls生成的ip 在上一步中我们生成了自己用hls编写的ip 接下来将记录如何使用自己的ip 首先打开vivado 创建一个工程,这里不赘述了,教程很多 然后一次点击下图的按钮 导入刚刚的ip,注意下hls的目录 然后就...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 215
精华内容 86
关键字:

hlszynq