一、HLS简单介绍

vivado HLS是xilinx推行的高级综合工具,可以使用C/C++以及system C来实现xilinx的可编程器件的编程,不用手写verilog语言,官方提供了两个重要的HLS开发文档:ug871-vivado-high-level-synthesis-tutorial.pdf和ug902-vivado-high-level-synthesis.pdf,详细讲解了HLS工程的建立,编写testbench,和怎么优化。简单总结:在vivado HLS软件右侧中有个Directive栏(如果没有可以在功能栏中的window将其显示出来),里边列出了所有的变量、函数、循环结构,右键点击就可以对其进行配置;简单讲解一下如何进行配置,对于循环结构体,一般选择unroll(展开循环),可以自己设定展开的因子factor;对于函数,为了提高程序的并行处理能力,可以右键选择PIPELINE;对于数组,可以设置为ARRAY_PARTITION,数组维数根据需求设置。每一个优化的方案都可以保存在一个solution中,可以创建多个solution。

二、OpenCV和HLS视频库介绍

vivado HLS中包含了大量的视频库函数,方便进行视频处理。HLS中的视频库函数代替了处理算法的openCV功能函数,而OpenCv函数用来访问输入输出图像。HLS视频库中许多视频的概念和OpenCV非常的相似,很多图像处理函数和OpenCV库函数一致。比如,OpenCV中用于代表图片很重要的一个类便是cv::Mat,cv::Mat对象定义如下:
cv::Mat image(1080,1920,CV_8UC3)该行的代码声明了一个1080*1920的像素,每一个像素由3个8位无符号数表示的变量image,对应HLS视频库模板类hls::Mat<>声明如下:

hls::Mat<2047,2047,HLS_8UC3> image(1080,1920)

这两行代码的参数形式,图像尺寸最大值、语法规则不同,生成的对象是类似的。如果图片规定的最大尺寸和图像的实际尺寸相同的花也可以用下面的代码来代替:

hls::Mat<1080,1920,HLDD_8UC3> image();

这位博主关于HLS的解释更为详细,推荐阅读【传送门】

三、AXI4流和视频接口

vivado HLS包含两个可综合的视频接口转化函数

视频库还提供了其他不可综合的视频接口函数,这些函数用于基于OpenCV测试平台与综合后的函数结合。VivadoHLS 视频处理函数库使用 hls::Mat<>数据类型,这种类型用于模型化视频像素流处理,实质等同于
hls::steam<>流的类型,而不是 OpenCV 中在外部 memory 中存储的 matrix 矩阵类型。因此,在用 Vivado HLS 实现
OpenCV 的设计中,需要将输入和输出 HLS 可综合的视频设计接口,修改为 Video stream 接口,也就是采用 HLS 提
供的 video 接口可综合函数,实现 AXI4 video stream 到 VivadoHLS 中 hls::Mat<>类型的转换。

四、代码优化

class ap_fixed:publicc ap_fixed_base<_AP_W,_AP_I,ture,_AP_Q,_AP_0,_AP_N>

这个函数怎么使用呢?它的定义可以这么理解:ap_fixed<M,N>,第一个M代表数据总位宽,N代表数据部分的位宽,那么小数部分的位宽为:M-N;
代码:

typedef int led_t;
typedef int cnt32_t;

可以优化为:

typedef ap_fixed<4,4> led_t;
typedef ap_fixed<32,32> cnt32_t;

这样就实现了端口数据位宽的约束。
另外还需要在directive目录下对端口进行优化。比如某一个接口src_axi(举例子),所以directive选择INTERFACE,Destination选择source file,那么这两个有什么区别呢?source file 就是针对所有的solution采用同一个优化手段,而Directive File是对当前的solution有效,mode(optional)选择ap_ovld,即输出使能。

说明一下有两个类似的接口,他们的区别(ap_ovld和ap_vld):ap_ovld这种接口和ap_vld基本是一样的,没啥区别,只是将输入的信号设为ap_ovld后,是没有效果的,只针对输出有效。但ap_vld对输入和输出都是有效的。详细接口的介绍可以看这个博主的文章【传送门】
将重点部分搬过来,方便理解,不过建议还是去阅读原文,原文讲得比较细,我这里只是提炼重点而已:

  1. ap_none:仅仅有数据,没有数据有效信号的这种接口,就是ap_none,这种ap_none在一个地方有用到,就是组合逻辑的实现时
    

  2.   ap_vld:产生一个数据有效的标志。因为,在第一点中提到的,在数据传输中,如果只单独有数据信号,在传输中无法判断哪些信号是有效的,必须要一个数据有效信号,而ap_vld接口就产生了这种数据的有效信号。再举个输入的例子,如果把输入接口in设成ap_vld,那么当数据输入时,也会有一个数据的有效信号输入,如果模块需要检测到4个数据输入后,再进行工作,就会不断等待4个vld的标志。如果在输出模块与输入模块之间,都使用ap_vld接口,可以实现点对点的通信,也即相连基本没有阻碍。但也会存在一个问题,就是后面一个模块是否可以接收数据,前一个模块是不知道的,如果一直发出去,后一个模块无法接收,那还是会出错。需要一个ready反馈信号,变成了
  3.   ap_hs:handshake,即握手信号,后续用的非常多的一个接口类型。握手是为了解决模块间是否能通信而诞生的
    

  1.       ap_ack:这种接口相当于ap_hs的特例,即原来的vld信号给去除掉了。数据传输时只有data和ack两根线,当后一级模块需要接收X个数据时,就会发出X个脉冲的ack信号,而前一级模块收到ack为1的情况,就会把数据传输给后一级模块。这种接口适合于前一级模块的数据都是有效的情况。这种接口其实不是很保险,因为前一级模块的数据很难做到都有效,或者说很难ack一为高,数据就准备好。
    
  2. ap_fifo:和ap_hs非常的像,会形成一个fifo的通路,ap_hs中的vld和ready相当于ap_fifo中的wr_en和full(read和empty)。
    

  1. ap_ovld:这种接口和ap_vld基本是一样的,没啥区别,只是将输入的信号设为ap_ovld后,是没有效果的,只针对输出有效。但ap_vld对输入和输出都是有效的。
    

  1. ap_stable:这个接口和ap_none很像,用于表示某个接口的信号在一次工作期间都是稳定的,用在配置寄存器中非常多,比如fir模块中的length就可以做成ap_stable的形式,每次工作期间都是个常数,但这次工作和下次工作期间可能会发生变化。再举个例子:卷积运算时需要KX和KY来配置kernel的大小,33或55,先配置好,单次运算的过程中,并不会发生改变。
    
  2. c ap_memory:数组就是这种,假设数据来源于存储器的接口。

  3. ap_bus:这种接口是Xilinx自己定义的一个接口,基本上用不着。通常都是用ap_hs来代替其。

这些是自学过程中总结的一些重点,好记忆不如烂笔头,虽然看的时候已经大致了解,但是过后肯定会遗忘,所以用博客的形式记录,方便日后回顾。

五、代码优化指令补充

1、情况一:



指令#pragma HLS UNROLL是优化语句,它的作用:
是针对与for循环的,将256个数展开并行计算。对于没有加UNROLL语句时,for循环中的乘法tmp=w[i][j]*I[j]是串行进行的,需要256个周期才能完成遍历计算,因为当前只用了一个乘法器来完成计算,当加入了unroll语句,将256个数展开来,一个周期就可以完成256个数据计算,但此时需要256个乘法器,从而实现了并行计算。

上面的指令是对for循环进行展开优化,其实这样子还不能完全的优化,因为参与运算的数据W和I是存储在ram中,而ram一个周期只能读取一个数,如果是双端口的ram可以一个周期读取2个数,所以为了匹配上unroll优化语句一个周期计算完,那么读取的熟读也要跟上,不然优化结果不是很明显,所以需要用指令展开存储器。首先介绍一下array_partiton指令:中文的意思就是队列的划分,将数据划分到不同的ram里面去

2、情况二:采用pipleine优化指令来展开for,即流水线的方式


II=1是按照最优的标准来优化,如果不行系统会自动往上加。

3、情况三:array_reshape指令来优化代码

这个指令可以节省ram的使用,用一个block ram存储数据,里面的数据可以同时取出分给不同的模块进行运算。举个例子,从block ram中取出32bit的数据,然后计算模块再从32bit的总线上读取数据,其中高16bit给a模块,低16bit数据给b模块进行处理,这样既可以提高并行度,又可以节约block ram的使用。这就是array_reshape指令的用法

1).按照complete完全展开

这样做的缺点就是系统将总线的位宽设置得很大,大的程度主要看存储数据得大小,这将会导致查找表资源用掉很多。当存储得数据位宽不是很大的时候可以全部展开。

2)、cyclic方式展开数据

其中参数factor的含义是将数据分为几个块。

cyclic方法分组的解释,假设原来的数据再block ram的存储方式是这样


按照cyclic方式成两块(factor=2)

3)、如果按照block方式来分块,那么得到的数据排列如下图:

4、函数接口的约束

1)对函数整体进行约束

mode的选择

  • 1.ap_ctrl_none:没有什么协议,单纯做信号线
  • 2.s_axilite:使用axilite协议来控制IP的启动、检查IP是否在工作、中断等功能
depth参数可以不填
latency参数可以不填
bundle是总线的名称,这个可以命名方便区分

2)对函数数据接口进行约束

  • 1.m_axi:相当于将IP看做主机,从机就是从ps端的ddr
  • 2.offset:一般设置为slave
  • 3.bundle:命名,用于区分

最后的约束指令

HLS代码机构上的优化

原来代码:

for(){for(){for(){}a=1+2;}b1=3+1;b2=3+2;
}

优化后的代码:但是有时候这样子作的效果不明显。

for(){for(){for(){if(条件1){a=1+2;}if(条件2){b1=3+1;b2=3+2;}}}
}
 --晓凡  2022年9月3日于南宁书

【二 HLS】HLS接口的简单介绍相关推荐

  1. 获取同花顺数据接口_简单介绍同花顺_数据获取方式(Excel VBA)

    简单介绍同花顺_数据获取方式(Excel VBA) 2018-09-12 简单介绍数据获取方式(Excel VBA) 数据是量化的根本和原材料,数据的准确性非常重要.获得数据的方式各种各样,最小的单位 ...

  2. 客快物流大数据项目(二十七):Cloudera Manager简单介绍

    目录 Cloudera Manager简单介绍 一.cloudera manager的概念 二.cloudera manager的功能 三.cloudera manager的架构 <

  3. FatFs 的用户层API接口应用简单介绍(基于STM32F1)

    ℹ️ 本篇文章没有说明实现方法,仅是简单介绍了 FatFs 的部分函数和结构体定义. FatFs API 应用程序接口 ▶️ 根据 FatFS 的教程手册来看,将程序接口分为了四个部分. 文件访问 目 ...

  4. wmaster0接口的简单介绍

    wmaster0是linux无线网络设备的主接口,根据官方说明,从linux2.6.32开始删除了这个接口,所以从linux2.6.32版本开始不会再看到这个接口,我们比较熟悉的是类似于waln0这种 ...

  5. R232接口的简单介绍

    这个接口又叫串口,主要用在工业控制.路由器调试.串口通信,还可以接MODEM,串口鼠标,不 过这两项现在不常见了,就不说了,主要说下前三项.        工业控制:工厂里的各种设备,像机电一体化等等 ...

  6. Kotlin入门笔记(二) Kotlin 函数的简单介绍

    前言:本教程最好在有JAVA的基础下进行学习 一.main函数的使用 (1) 学过java的小伙伴们应该知道,java的main方法是静态的,且写在class中.Kotlin就有所不同,一般的写法可以 ...

  7. STM32CubeMx + LWIP(实现UDP组播/MQTT/热插拔)系列 二 ----- CubeMx生成文件的简单介绍与热插拔

    CubeMx生成的文件主要是两个文件,lwipopts.h和ethnetif.c. lwipopts.h主要是对于lwip中一些宏的定义的选择.该文件include在lwip的opt.h文件前面.因此 ...

  8. 【抽象类与接口的简单介绍】

    ✨hello,愿意点进来的小伙伴们,你们好呐! ✨

  9. 微信公众平台接口简单介绍

    微信公众平台的管理地址是:https://mp.weixin.qq.com 注册完个人公众号以后,登录到微信公众平台的管理后台,需要用微信扫一下二维码才能登录进去哦... 这个后台提供了基本的对公众号 ...

最新文章

  1. SpringBoot使用AOP
  2. python 列表索引第一个字典_python开发(第三篇):python基本数据类型(列表,元组,字典)...
  3. java高效遍历匹配,使用cypher或遍历api仅匹配路径极端的单个节点
  4. js 获取 select的option的 id值
  5. 记录今天登录oracle时遇到的一个小问题--不能登录
  6. 上海最帅交警迷倒一片女白领成为城市风景
  7. socket 网络编程
  8. 数据库-windows上安装mysql
  9. 如何在uniapp中使用百度云实现OCR身份证识别功能
  10. 静态HTML+CSS 中国高等教育学生信息网(学信网)网站
  11. Installing Kubernetes Using ‘kubeadm’
  12. R语言将变量分组的三种方法(含cut函数介绍)
  13. 扫描枪识别条码为乱码
  14. F-PointNets
  15. vulnhub--Funbox: Scriptkiddie
  16. win10配置Java环境
  17. 鸟哥的Linux私房菜(基础篇)- 第二十一章、系统配置工具(网络与打印机)与硬件侦测
  18. 对链特异性建库的理解
  19. VVIC接口,item_get - 根据ID取商品详情
  20. 手把手教你批量剪辑视频

热门文章

  1. 小数点化分数的过程_怎么把小数化成分数
  2. 一个完整的Installshield安装程序实例
  3. 字节跳动 校招薪资曝光,老员工被倒挂疯了~
  4. 人均8万啊,腾讯豪掷21亿股票奖励员工,爱奇艺却大规模裁员,这就是差距吗?
  5. 人脸验证(图片/视频) tensorflow、pytorch框架、dlib库(face_recognition)和opencv库————附带详细步骤和代码,可实际运行
  6. 域名是干啥用的?企业自己都记不住的域名还能发挥作用吗?
  7. 【TV Picture Quality - 02】TV常见信号接口
  8. 企业——nginx的图片压缩、https模块、重写规则、盗链
  9. 电子设计硬件可靠性设计----总结2
  10. Apache Kafka 在 360 的深度实践