Vitis HLS 学习笔记--函数例化(Function Instantiation)

目录

1. 简介

2. 功能分析

3. 示例分析

3.1 不使用 FUNCTION_INSTANTIATE

3.2 使用 FUNCTION_INSTANTIATE

4. 总结


1. 简介

函数例化(Function Instantiation)是 Vitis HLS 中的一个高级优化技术。它允许开发者在保持函数层次结构的同时,对函数的特定实例进行局部优化。如果函数的某些输入参数在调用时是已知的常量,那么可以利用这些信息来简化函数的控制逻辑,从而可能改善延迟和吞吐量。

2. 功能分析

在 Vitis HLS 中的函数,在没有特别指定编译指示的情况下,HLS 工具会遵循以下原则进行处理:

  • 函数保留为独立层级块:每个函数在生成的RTL(寄存器传输级)代码中都会作为一个独立的模块存在。这有助于保持设计的模块化,使得每个函数都可以独立地被验证和复用。
  • 函数分解(或内联)到更高层次的函数中:如果HLS工具决定将一个函数内联到另一个函数中,那么在RTL代码中,原本独立的函数将不再作为单独的模块存在。相反,它的逻辑会被合并到调用它的函数中。这通常是为了优化性能,减少函数调用的开销。
  • 所有实例使用单一RTL实现:如果一个函数被多次调用,每个调用实例在默认情况下都会共享相同的RTL代码块。这有助于减少生成的硬件资源的数量,因为不需要为每个函数调用创建单独的硬件实现。

Function Instantiation 语法:

#pragma HLS FUNCTION_INSTANTIATE variable=<variable>

其中,variable=<variable>:这是必需的实参,用于定义要用作为常量的函数实参。

FUNCTION_INSTANTIATE 编译指示用于为函数的每个实例创建唯一的 RTL 实现,允许根据函数调用对每个实例进行局部最优化。鉴于调用函数时部分函数输入可能是常量,此编译指示可藉此简化周围控制结构,并生成进一步优化的、更小的函数块。

3. 示例分析

3.1 不使用 FUNCTION_INSTANTIATE

char foo(char inval, char incr) {
#pragma HLS INLINE OFF
//#pragma HLS FUNCTION_INSTANTIATE variable = incr
    return inval + incr;
}

void top(char inval1, char inval2, char inval3, char* outval1, char* outval2,
         char* outval3) {
    *outval1 = foo(inval1, 0);
    *outval2 = foo(inval2, 1);
    *outval3 = foo(inval3, 100);
}

经过综合,得到如下文件结构:

可以发现,代码会为 top 中的函数的全部 3 个实例生成函数 foo 的单一 RTL 实现。函数 foo 的每个实例都是以相同方式实现的。这对于函数复用并无影响,并且可以减少函数的每次实例调用所需的面积,但是函数内部的控制逻辑必须更复杂,以便应对每次调用 foo 时产生的变化。

如下代码可以看到每次函数调用的情况:

...

example_foo tmp_foo_fu_79(
    .ap_ready(tmp_foo_fu_79_ap_ready),
    .inval(inval1),
    .incr(6'd0),
    .ap_return(tmp_foo_fu_79_ap_return)
);

example_foo tmp_1_foo_fu_88(
    .ap_ready(tmp_1_foo_fu_88_ap_ready),
    .inval(inval2),
    .incr(6'd1),
    .ap_return(tmp_1_foo_fu_88_ap_return)
);

example_foo tmp_2_foo_fu_97(
    .ap_ready(tmp_2_foo_fu_97_ap_ready),
    .inval(inval3),
    .incr(6'd36),
    .ap_return(tmp_2_foo_fu_97_ap_return)
);

always @ (*) begin
    if ((ap_start == 1'b1)) begin
        outval1_ap_vld = 1'b1;
    end else begin
        outval1_ap_vld = 1'b0;
    end
end

always @ (*) begin
    if ((ap_start == 1'b1)) begin
        outval2_ap_vld = 1'b1;
    end else begin
        outval2_ap_vld = 1'b0;
    end
end

always @ (*) begin
    if ((ap_start == 1'b1)) begin
        outval3_ap_vld = 1'b1;
    end else begin
        outval3_ap_vld = 1'b0;
    end
end

assign ap_done = ap_start;

assign ap_idle = 1'b1;

assign ap_ready = ap_start;

assign outval1 = tmp_foo_fu_79_ap_return;

assign outval2 = tmp_1_foo_fu_88_ap_return;

assign outval3 = tmp_2_foo_fu_97_ap_return;

endmodule //example

3.2 使用 FUNCTION_INSTANTIATE

char foo(char inval, char incr) {
#pragma HLS INLINE OFF
#pragma HLS FUNCTION_INSTANTIATE variable = incr
    return inval + incr;
}

void top(char inval1, char inval2, char inval3, char* outval1, char* outval2,
         char* outval3) {
    *outval1 = foo(inval1, 0);
    *outval2 = foo(inval2, 1);
    *outval3 = foo(inval3, 100);
}

经过综合,得到如下文件结构:

可以发现,代码会为 top 中的函数的由 3 个独立的实例生成函数 foo 的 RTL 实现:example_foo_0.v、example_foo_1.v、example_foo_2.v。

在以上代码样本中:

#pragma HLS FUNCTION_INSTANTIATE variable = incr

FUNCTION_INSTANTIATE 编译指示会生成函数 foo 的 3 个不同实现,每个实现都会按incr 指定值进行最优化,从而减少面积并改善函数实现的性能。

提示:Vitis HLS 工具会将小函数自动分解(或内联)到更高层次的调用函数中。即使对于函数例化也同样如此。将 INLINE 编译指示与 OFF 选项搭配使用即可阻止此自动内联操作。

4. 总结

函数例化是Vitis HLS中的一种高级优化技术,它允许开发者在保持函数层次结构的同时,对特定函数实例进行局部优化。这种技术通过利用编译时已知的常量输入参数,简化函数的控制逻辑,从而可能改善延迟和吞吐量。默认情况下,函数在RTL中作为独立层级块保留,或者分解到更高层次的函数中,所有实例共享单一RTL实现。通过使用FUNCTION_INSTANTIATE编译指示,可以为每个函数调用创建唯一的RTL实现,允许针对每个实例进行局部最优化。这样,即使原始函数包含复杂的控制逻辑,每个实例化的函数也可以被优化以仅包含必要的逻辑,减少硬件资源消耗并提高性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/718741.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

wsl2平台鸿蒙全仓docker编译环境快速创建方法

文章目录 1 文章适用范围&#xff1a;2 WSL环境安装3 镜像迁移非C盘4 Docker环境准备4.1 docker用户组和用户创建4.2 Docker环境配置4.2.1 Ubuntu下安装docker工具4.2.2 鸿蒙Docker环境安装4.2.3 鸿蒙全仓代码拉取编译 5 参考文献6 FAQ6.1 缺头文件xcrusor/xcursor.h6.2 缺头文…

多叉树的DFS深度优先遍历,回溯法的基础算法之一

一、前言 多叉树一般用于解决回溯问题。 想必大家都学过二叉树&#xff0c;以及二叉树的深度优先遍历和广度优先遍历&#xff0c;我们思考&#xff1a;能不能将二叉树的DFS转化为多叉树的DFS&#xff1f; 二、多叉树的结构 多叉树的本质&#xff0c;就是一棵普通的树&#x…

六、Nginx-正向代理和反向代理

目录 一、正向代理 1、参数详解 2、常用变量详解 3、配置示例 二、反向代理 三、 Nginx的安全控制 1、如何使用SSL对流量进行加密 2、nginx添加SSL的支持 3、 Nginx的SSL相关指令 &#xff08;1&#xff09;ssl &#xff08;2&#xff09;ssl_certificate &#xff0…

Tuxera NTFS与Paragon NTFS:两款NTFS驱动软件的深度对比 tuxera和paragon NTFS哪个好

在Mac上使用NTFS格式的磁盘&#xff0c;通常需要借助第三方的驱动软件。其中&#xff0c;Tuxera NTFS和Paragon NTFS是两款备受欢迎的选择。虽然它们的基本功能相似&#xff0c;但在细节和使用体验上却有所不同。本文将带你深入了解这两款软件的差异&#xff0c;帮助你做出更明…

【python】OpenCV—Segmentation

文章目录 cv2.kmeans牛刀小试 cv2.kmeans cv2.kmeans 是 OpenCV 库中用于执行 K-Means 聚类算法的函数。以下是根据参考文章整理的 cv2.kmeans 函数的中文文档&#xff1a; 一、函数功能 cv2.kmeans 用于执行 K-Means 聚类算法&#xff0c;将一组数据点划分到 K 个簇中&…

响应式高端网站模板源码图库素材 资源下载平台源码

源码介绍 亲测可用&#xff0c;可用于做娱乐网资源网&#xff0c;功能非常的齐全无任何加密也无任何后门&#xff01;响应式高端网站模板源码图库素材 资源下载平台源码&#xff08;可运营&#xff09; 页面很美观&#xff0c;堪比大型网站的美工&#xff0c;而且页面做的也很…

Python将字符串用特定字符分割并前面加序号

Python将字符串用特定字符分割并前面加序号 Python将字符串用特定字符分割并前面加序号&#xff0c;今天项目中就遇到&#xff0c;看着不难&#xff0c;得花点时间搞出来急用啊&#xff0c;在网上找了一圈&#xff0c;没发现有完整流程的文章。所以就搞出来并写了这个文章。仅…

Mybatis 笔记 (一) V- 3.5.16

文章目录 Mybatis 笔记&#xff08;3.5.16&#xff09;1、基础数据2、基础依赖3、魔改点标记 A、试试SqlSessionFactoryB、建立连接的三种方式1、执行方法2、实现方式 C、“复杂”的 Configuration 模式实现1、直接构建Configuration2、补充environment 要素2.1、填充id2.2、填…

文生视频开源产品的一些调研(一)

笔者尝试AI视频生成的几个特点&#xff1a; 玄学prompt&#xff0c;每个视频的prompt可能也需要微调很多次&#xff0c;需要找到使用模型的最佳prompt词组合&#xff0c;不恰当的比喻&#xff0c;骑自行车&#xff0c;座位高度等都是人与车彼此熟悉玄学生成&#xff0c;因为需…

Java | Leetcode Java题解之第162题寻找峰值

题目&#xff1a; 题解&#xff1a; class Solution {public int findPeakElement(int[] nums) {int n nums.length;int left 0, right n - 1, ans -1;while (left < right) {int mid (left right) / 2;if (compare(nums, mid - 1, mid) < 0 && compare(n…

vue:对三种获取更新后的dom的方式进行分析

一、问题分析 由于vue的异步更新机制&#xff0c;我们在同步代码中是无法获取到更新后的dom的信息的 针对这个问题&#xff0c;我们有三种解决方案获取更新后的dom: 1.nextTick() 2.setTimeout() 3.在微任务中获取 因为更新是在同步任务结束后&#xff0c;执行微任务之前…

【网络安全】网络安全威胁及途径

1、网络安全威胁的种类及途径 &#xff08;1&#xff09;网络安全威胁的主要类型 网络安全面临的威胁和隐患种类繁多&#xff0c;主要包括人为因素、网络系统及数据资源和运行环境等影响。网络安全威胁主要表现为&#xff1a;黑客入侵、非授权访问、窃听、假冒合法用户、病毒…

C++日志库spdlog使用方法

对于线上服务&#xff0c;打日志至关重要&#xff0c;通过日志可以进行事件定位、debug&#xff0c;有时也会通过收集日志实现追溯、监控、特征采集等工作。 1. spdlog简介 spdlog github 一个开源的C日志库&#xff0c;快速便捷&#xff0c;使用了fmt作为格式化工具。 2. s…

02 - matlab m_map地学绘图工具基础函数 - m_proj

02 - matlab m_map地学绘图工具基础函数 - m_proj 0. 引言1. 查看所有投影方式3. 各投影方式绘图示例3.1 极射赤面投影法&#xff08;Stereographic &#xff09;3.2 Orthographic 正射投影示例3.3 Azimuthal Equal-area 方位等面积投影3.4 Azimuthal Equidistant 等距方位投影…

函数模板的注意事项

1.可以为类的成员函数创建模板&#xff0c;但不可以是虚函数和析构函数。 #include <iostream> using namespace std;class CGirl {public:template <typename T>CGirl(T a) {//构造函数中cout << "a" << a << endl;}template <ty…

Mysqld数据库管理

一.Mysqld数据库类型 常用的数据类型 int 整型 无符号[0-4294967296&#xff08;2的32次方&#xff09;-1]&#xff0c;有符号[-2147483648&#xff08;2的31次方&#xff09;-2147483647]float单精度浮点 4字节32位double双精度浮点 8字节64位char固定长度的字符类型…

如何利用TikTok矩阵源码实现自动定时发布和高效多账号管理

在如今社交媒体的盛行下&#xff0c;TikTok已成为全球范围内最受欢迎的短视频平台之一。对于那些希望提高效率的内容创作者而言&#xff0c;手动发布和管理多个TikTok账号可能会是一项繁琐且耗时的任务。幸运的是&#xff0c;通过利用TikTok矩阵源码&#xff0c;我们可以实现自…

【vue3|第9期】Vue3中watch监视的深度解读

日期&#xff1a;2024年6月10日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

element-plus的Tour 漫游式引导怎么去绑定Cascader 级联选择器

首先官方例子是用的button 官方.$el这个log出来是&#xff1a; 知道是以元素为准就拿对应的元素就行 级联选择器.$el是这样的&#xff1a; 你可以移入这个元素部分去看看是哪个要用的&#xff08;好像火狐直接放上去就可以看到元素表示&#xff0c;谷歌要双击或者右键选择去看…

英语恶补ing

ing的词组都有停下来做某事的感觉了。 second hand是形容词了。 wouldnt buy这里的would是情态动词&#xff0c;也是助动词 助动词不能单独使用&#xff0c;要搭配实义动词&#xff0c;这样才能构成谓语 情态动词&#xff08;modals&#xff09;在英语中有多种作用&#xff…