0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HLS for循环优化

jf_78858299 来源:傅里叶的猫 作者:张大侠 2023-05-05 15:48 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

FOR循环优化

基本概念

从下面的例子中来解释for循环中的基本概念:

图 4.1 for循环基本概念

由于N等于3,因此每次循环可以分成4个步骤来完成:

c0:读取数据b和c;

c1:获取数据xin 0处地址;

c2:读取对应地址上的数据;

c3:计算yo[0]的值。

后面的计算都是三个时钟周期计算出一个值,因此对一次循环来说,Loop Iteration Latency为3,Loop Iteration Interval也是3,Loop Latency是9,再加上前面读b和c的值的一个周期,整个函数的Latency是10,函数间的Initial Interval是11.

Pipeline

对for循环常用的优化是pipeline,pipeline的原理如下图4.2所示。

图 4.2 pipeline优化原理

在优化结束后,Loop Iteration Latency为3,Loop Iteration Interval变成1,Loop Latency为5.

如果对函数做pipeline,那么会自动把函数下面的for循环都做unrolling处理;如果对外层的for循环做pipeline,那么会自动对内层的for循环做unrolling处理。

Unrolling

默认情况下for循环是折叠的,就是电路被时分复用。当展开后,资源增加。如下图所示将for循环展开成3倍的情况,资源也扩大了3倍。

图 4.3 展开成3倍

也可以部分展开,循环次数为6,但展开成3倍,程序如下所示:

展开后,程序被分成3部分,资源也复制了3份。

图 4.4 Unroll的设置

Merge

当几个for循环执行的内容很相似时,如下面的程序所示:

两个for循环分别对两个数据做加法和减法,在HLS综合后,会先进行第一个for循环的计算,完成后再进行第二个for循环的计算。这样综合出的Latency为18,Interval为19。

图 4.5 综合后延迟

在HLS中提供了Merge的选项,合并的是for所作用的region,合并后综合后的延迟如下图4.6所示。

图 4.6 Merge后的延迟

上面的例子中两个循环的边界相同,如果两个循环的边界不同,则以最大的作为合并后的边界;如果一个边界是变量,另一个是常量,则不能合并;如果两个循环边界都是变量,依然不能合并。

还可以将for循环封装成一个函数,并在上一层中例化两次,并对函数采用Allocation来使函数并行执行,在allocation中有limit选项,可以指定实例化的次数,该数据与程序中实际的数值应该是一样的。

数据流

在下面的例子中,Task B依赖于Task A,Task C依赖于Task B,如图4.7所示。

而且可以分析出,该结构不适合之前所讲的pipeline和merge方式进行处理,在可以使用dataflow的方式。

从图中可以看出,在使用DataFlow后,Loop B无需等待A执行完成后才开始执行,而且各个Loop之间也村在间隔。且延迟和资源都明显减少。

DataFlow使用的限制:

1.一个输出在多个Loop模块中使用

2.被Bypass的模块

3.带反馈的模块

4.带条件的模块

5.可变循环边界的模块

6.多个退出条件的模块

下面分别对上面的限制条件进行说明。

1.din在Loop1中输出的temp1同时赋给Loop2和Loop3使用,这时是不能使用dataflow的,如图4.10所示。

通过对代码进行适当的修改,将其结构进行变形,增加一个Loop_copy模块,将其输出一个送个Loop2,另一个输出送给Loop3,但其实这两个输出的结果是相同的。就可以使用DataFlow来完成该函数。

且使用了DateFlow后,工程所占用的资源和延迟都相应减少。

  1. 被Bypass的模块

如下图4.12所示的例子中,temp1在Loop2中使用,但temp2没有经过Loop2,直接在Loop3中使用,这种情况下也是不能使用DataFlow的。

同样的,可以对代码进行优化以达到可以使用DataFlow的目的,如下图4.13所示。在Loop2中,增加一个输出端口,使其输出给Loop3,这样就可以使用DataFlow了。

在DataFlow的循环之间的存储模块,对于scalar、pointer和reference或者函数的返回值,HLS会综合为FIFO;对于数组,结果可能是乒乓RAM或者FIFO:如果HLS可以判断数据是流模式,就会综合为FIFO,且深度为1,若不能判断,就会综合为乒乓RAM。我们也可以指定为FIFO或者乒乓RAM,但在指定为FIFO时,如果指定的深度不合适,综合时就会出现错误。

嵌套for循环

三种嵌套循环:

对于Perfect Loop,对外边的Loop做流水比对内循环做流水更加节省时间。

对于Imperfect Loop,我们总希望可以转换为Perfect Loop或者Semi-Perfect Loop。如下的Imperfect Loop,如果对内层Product做流水,综合结果如右侧的图所示。

如果对第二层即col的Loop做流水,则会提示信息,col下的循环会被展开。

从图中的warning可以看出,a被综合为一个双端口的RAM,但第14行和第20行对a的操作有一个重叠的区域,意味着吞吐率受限。

如果对最外部的循环做流水,会把下面所有的循环都展开,延迟会减少,但资源会增加。

如果对整个函数做流水,那么函数下面的所有循环都会展开,能获得最好的Latency,但资源也是最多的。

我们可以对代码就行优化,具体代码具体优化。

Rewind

我们在使用了pipeline后,循环之间仍然会有间隔,但使用rewind功能,可以消除该间隔,如下图所示。

图 4.16 rewind功能

但当函数中有多个循环时,rewind不能使用。

自动添加流水

在config_compile中,可以设置自动添加流水操作,如果循环次数小于我们设定的pipeline loops时,HLS就会自动为for循环添加流水。

在使用config_compile后,如果不想对某些for循环做流水,就可以在pipeline下面的选项中选中disable Loop pipeline。

变量边界的解决方法

当循环边界为变量时,通常可以采用下面的方式进行处理。

  1. 使用tripcount directive;
  2. 对于边界变量的定义使用ap_int;
  3. 在C代码中使用assert宏。

Tripcount directive不会对综合有任何的影响,它只会对报告的显示有影响。

使用ap_int和assert方法后,综合后的资源会有明显的减少。采用assert的方式的资源和延迟是最少的。

inline是针对函数,flatten是针对嵌套的循环。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66828
  • HLS
    HLS
    +关注

    关注

    1

    文章

    133

    浏览量

    25591
  • for循环
    +关注

    关注

    0

    文章

    61

    浏览量

    2852
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何使用AMD Vitis HLS创建HLS IP

    本文逐步演示了如何使用 AMD Vitis HLS 来创建一个 HLS IP,通过 AXI4 接口从存储器读取数据、执行简单的数学运算,然后将数据写回存储器。接着会在 AMD Vivado Design Suite 设计中使用此 HLS
    的头像 发表于 06-13 09:50 1274次阅读
    如何使用AMD Vitis <b class='flag-5'>HLS</b>创建<b class='flag-5'>HLS</b> IP

    探索Vivado HLS设计流,Vivado HLS高层次综合设计

    作者:Mculover666 1.实验目的 通过例程探索Vivado HLS设计流 用图形用户界面和TCL脚本两种方式创建Vivado HLS项目 用各种HLS指令综合接口 优化Viv
    的头像 发表于 12-21 16:27 4316次阅读

    HLS优化设计中pipeline以及unroll指令:细粒度并行优化的完美循环

    HLS 优化设计的最关键指令有两个:一个是流水线 (pipeline) 指令,一个是数据流(dataflow) 指令。正确地使用好这两个指令能够增强算法地并行性,提升吞吐量,降低延迟但是需要遵循一定
    发表于 01-08 10:26 9887次阅读

    如何优化HLS仿真脚本运行时间

    需求:由于自己目前一个 HLS 仿真脚本需要运行 1个多小时,先打算通过打印时间戳的方式找出最耗时的部分,然后想办法优化
    的头像 发表于 02-23 09:29 1337次阅读

    AMD-Xilinx的Vitis-HLS编译指示小结

    。 含多个退出条件的循环 由于篇幅原因,这里就不细讲了,详情可以参考Vitis高层次综合用户指南 (UG1399) 阵列优化指令 pragma HLS array_partition
    发表于 12-31 21:20

    优化 FPGA HLS 设计

    优化 FPGA HLS 设计 用工具用 C 生成 RTL 的代码基本不可读。以下是如何在不更改任何 RTL 的情况下提高设计性能。 介绍 高级设计能够以简洁的方式捕获设计,从而
    发表于 08-16 19:56

    怎么利用Synphony HLS为ASIC和FPGA架构生成最优化RTL代码?

    相比,能够为通信和多媒体应用提供高达10倍速的更高的设计和验证能力。Synphony HLS为ASIC 和 FPGA的应用、架构和快速原型生成最优化的RTL。Synphony HLS解决方案架构图
    发表于 08-13 08:21

    Vivado HLS设计流的相关资料分享

    1.实验目的通过例程探索Vivado HLS设计流用图形用户界面和TCL脚本两种方式创建Vivado HLS项目用各种HLS指令综合接口优化Vivado
    发表于 11-11 07:09

    FPGA高层次综合HLS之Vitis HLS知识库简析

    1、HLS最全知识库介绍高层次综合(High-level Synthesis)简称HLS,指的是将高层次语言描述的逻辑结构,自动转换成低抽象级语言描述的电路模型的过程。对于AMD Xilinx而言
    发表于 09-07 15:21

    使用Vitis HLS创建属于自己的IP相关资料分享

    1、使用Vitis HLS创建属于自己的IP高层次综合(High-level Synthesis)简称HLS,指的是将高层次语言描述的逻辑结构,自动转换成低抽象级语言描述的电路模型的过程。对于AMD
    发表于 09-09 16:45

    HLS系列 – High Level Synthesis(HLS) 的一些基本概念1

    相信通过前面5篇fir滤波器的实现和优化过程,大家对HLS已经有了基本的认识。是时候提炼一些HLS的基本概念了。 HLS支持C,C++,和SystemC作为输入,输出为Verilog(
    发表于 02-08 05:23 1089次阅读
    <b class='flag-5'>HLS</b>系列 – High Level Synthesis(<b class='flag-5'>HLS</b>) 的一些基本概念1

    HLS:lab3 采用了优化设计解决方案

    本实验练习使用的设计是实验1并对它进行优化。 步骤1:创建新项目 1.打开Vivado HLS 命令提示符 a.在windows系统中,采用Start>All Programs>Xilinx
    发表于 02-09 05:07 1093次阅读
    <b class='flag-5'>HLS</b>:lab3 采用了<b class='flag-5'>优化</b>设计解决方案

    FPGA并行编程:基于HLS技术优化硬件设计

    作为集成电路设计领域现场可编程门阵列 (FPGA) 技术的创造者之一,赛灵思一直积极推广高层次综合 (HLS) 技术,通过这种能够解读所需行为的自动化设计流程打造出可实现此类行为的硬件。赛灵思刚刚推出了一本专著,清晰介绍了如何使用 HLS 技术来创建
    发表于 11-10 11:01 3159次阅读

    for 循环并行执行的可能性

    我们将继续介绍 Vivado HLS 所支持的 “for循环” 的优化方法。在默认情况下,Vivado HLS 并不会对顺序执行的 for 循环
    的头像 发表于 08-01 16:59 3227次阅读

    HLS优化设计的最关键指令

    Unroll 指令在 for 循环的代码区域进行优化,这个指令不包含流水线执行的概念,单纯地将循环体展开使用更多地硬件资源实现,保证并行循环体在调度地过程中是彼此独立的。
    的头像 发表于 01-14 09:41 3207次阅读