Vitis HLS 学习笔记--优化指令-BIND_OP_STORAGE

目录

1. BIND_OP_STORAGE 概述

1.1 BIND_OP

1.2 BIND_STORAGE

2. 语法解析

2.1 BIND_OP

2.2 BIND_OP 用法示例

2.3 BIND_STORAGE

2.4 BIND_STORAGE 示例

3. 实例演示

4. 总结


1. BIND_OP_STORAGE 概述

BIND_OP_STORAGE 其实是两个优化指令的合称:BIND_OP 和 BIND_STORAGE。

1.1 BIND_OP

Vitis HLS 使用特定 impl 来实现代码中的运算。BIND_OP 编译指示用于指定针对每个特定变量,都应将一项运算(mul、add、div)映射到特定器件资源,以便在 RTL 内实现 (impl)。如果不指定 BIND_OP 编译指示,Vitis HLS 会自动判定用于运算的资源。

1.2 BIND_STORAGE

BIND_STORAGE 编译指示用于将代码中的变量(阵列或函数实参)分配给 RTL 中的特定存储器类型 (type)。如果不指定此编译指示,那么 Vitis HLS 工具会判定要分配的存储器类型。HLS 工具在硬件中使用指定的实现 (impl) 来实现该存储器。

2. 语法解析

2.1 BIND_OP

#pragma HLS bind_op variable=<variable> op=<type> impl=<value> latency=<int>
  • variable=<variable>:用于定义要将 BIND_OP 编译指示分配到的变量
  • op=<type>:用于定义要绑定到特定实现资源的运算。受支持的函数运算包括:mul、add 和 sub 受支持的浮点运算包括:fadd、fsub、fdiv、fexp、flog、fmul、frsqrt、frecip、fsqrt、dadd、dsub、ddiv、dexp、dlog、dmul、drsqrt、drecip、dsqrt、hadd、hsub、hdiv、hmul 和 hsqrt。
  • impl=<value>:定义用于指定运算的实现。受支持的函数运算实现包括 fabric 和 dsp。受支持的浮点运算实现包括:fabric、meddsp、fulldsp、maxdsp 和 primitivedsp。
  • latency=<int>:定义运算的实现的默认时延。有效的时延值因指定的 op 和 impl 而异。默认值为 -1,即交由 Vitis HLS 选择时延。

支持的整数运算操作:

OP

Impl

Min Latency

Max Latency

add

fabric

0

4

add

dsp

0

4

mul

fabric

0

4

mul

dsp

0

4

sub

fabric

0

4

sub

dsp

0

0

 支持的浮点数运算操作:

操作

实现

Min Latency

Max Latency

fadd

fabric

0

13

fadd

fulldsp

0

12

fadd

primitivedsp

0

3

fexp

meddsp

0

21

fmul

maxdsp

0

7

快速记忆方法:

受支持的函数运算包括:
mul、add 、 sub受支持的浮点运算包括:
fadd fsub fdiv fexp flog fmul frsqrt frecip fsqrt
dadd dsub ddiv dexp dlog dmul drsqrt drecip dsqrt
hadd hsub hdiv           hmul               hsqrt

Impl解释:

  • fabric: 使用 FPGA 的逻辑单元和 RAM 块来实现算法。
  • dsp: 使用 FPGA DSP 功能来实现算法,例如 FFTFIRDDS 等。
  • meddsp: 使用 FPGA DSP 功能和一些逻辑单元来实现算法,适合中等复杂度的算法。
  • maxdsp: 使用 FPGA DSP 功能和更多的逻辑单元来实现算法,适合高复杂度的算法。
  • fulldsp: 使用 FPGA 的所有可用资源来实现算法,包括 DSPRAM 和逻辑单元。

2.2 BIND_OP 用法示例

double mult (double a, double b) {double c, d;
#pragma HLS BIND_OP variable=c op=dmul impl=fabric  latency=2
#pragma HLS BIND_OP variable=d op=dmul impl=fulldsp latency=10c = a * b;d = a * c;return d;
}

解释: 

  • 指定变量 的双精度浮点运算,实现方式fabric,延时为2
  • 指定变量 的双精度浮点运算,实现方式为fulldsp,延时为10

Vitis HLS 编译器得到的结果如下:

从命名可以看出:

  • dmul: 双精度乘法器。
  • 64ns: 输入数据的位宽是 64 位,ns的含义不明
  • 64: 输出数据的位宽是 64 位,3和5的含义不明。
  • max_dsp: 实现方法是使用最大数量的 DSP 功能。
  • U2: 模块的实例名字。

注意:

  • 编译器对待手动指定latency,会优先满足时钟频率上的要求,然后尽量靠近用户指定的latency
  • 如上述案例,虽然指定了latency=2,但是编译器需要latency等于3才能满足时钟频率要求。
  • 给定更多latency,系统能运行在更高的时钟频率上。

2.3 BIND_STORAGE

#pragma HLS bind_storage variable=<variable> type=<type> [ impl=<value> latency=<int> ]
  • variable=<variable>:定义要将 BIND_STORAGE 编译指示分配到的变量。
  • type=<type>:定义要绑定到指定变量的存储器的类型。受支持的类型包括:fifo、ram_1p、ram_1wnr、ram_2p、ram_s2p、ram_t2p、rom_1p、rom_2p、rom_np。
  • impl=<value>:定义指定存储器类型的实现。受支持的实现包括:bram、bram_ecc、lutram、uram、uram_ecc、srl、memory 和 auto,如下所述。
  • latency=<int>:定义用于绑定类型的默认时延。如下表所示,有效的时延值因指定的 type 和 impl 而异。默认值为 -1,即交由 Vitis HLS 选择时延。

存储类型:

类型

描述

FIFO

FIFOVitis HLS 可判定如何在 RTL 中将其实现,除非指定 -impl 选项。

RAM_1WNR

1 个写入端口和 N 个读取端口的 RAM,内部使用 N bank

RAM_2P

双端口 RAM,允许在某一端口上执行操作,并在另一个端口上执行读写操作。

RAM_S2P

双端口 RAM,允许在某一端口上执行操作,并在另一个端口上执行操作。

RAM_T2P

真正的双端口 RAM,支持在 2 个端口上执行读写操作。

ROM_1P

单端口 ROMVitis HLS 可判定如何在 RTL 中将其实现,除非指定 -impl 选项。

ROM_2P

双端口 ROM

ROM_NP

多端口 ROM

实现类型:

名称

描述

MEMORY

通用存储器,允许 Vivado 工具选择实现。

URAM

UltraRAM 资源

URAM_ECC

ECC UltraRAM

SRL

移位寄存器逻辑资源,Shift Register Look-up Table(移位寄存器查找表)

LUTRAM

分布式 RAM 资源

BRAM

RAM 资源

BRAM_ECC

ECC 的块 RAM

AUTO

Vitis HLS 会自动判定变量的实现。

受支持的存储器类型、实现和时延组合:

操作

实现

Min Latency

Max Latency

FIFO

BRAM

0

0

FIFO

LUTRAM

0

0

FIFO

MEMORY

0

0

FIFO

SRL

0

0

FIFO

URAM

0

0

RAM_1P

AUTO

1

3

RAM_1P

BRAM

1

3

RAM_1P

LUTRAM

1

3

RAM_1P

URAM

1

3

RAM_1WNR

AUTO

1

3

RAM_1WNR

BRAM

1

3

RAM_1WNR

LUTRAM

1

3

RAM_1WNR

URAM

1

3

RAM_2P

AUTO

1

3

RAM_2P

BRAM

1

3

RAM_2P

LUTRAM

1

3

RAM_2P

URAM

1

3

操作

实现

Min Latency

Max Latency

RAM_S2P

BRAM

1

3

RAM_S2P

BRAM_ECC

1

3

RAM_S2P

LUTRAM

1

3

RAM_S2P

URAM

1

3

RAM_S2P

URAM_ECC

1

3

RAM_T2P

BRAM

1

3

RAM_T2P

URAM

1

3

ROM_1P

AUTO

1

3

ROM_1P

BRAM

1

3

ROM_1P

LUTRAM

1

3

ROM_2P

AUTO

1

3

ROM_2P

BRAM

1

3

ROM_2P

LUTRAM

1

3

ROM_NP

BRAM

1

3

ROM_NP

LUTRAM

1

3

2.4 BIND_STORAGE 示例

#pragma HLS bind_storage variable=coeffs type=RAM_1P impl=bram

解释:

指令告诉HLS工具将 coeffs 数组绑定到一个单端口RAM上,并且使用块RAM作为其实现方式。

3. 实例演示

#define BUFFER_SIZE 1024
#define DATA_SIZE 4096// TRIPCOUNT identifier
const unsigned int c_len = DATA_SIZE / BUFFER_SIZE;
const unsigned int c_size = BUFFER_SIZE;extern "C" {
void vadd(const unsigned int* in1, // Read-Only Vector 1const unsigned int* in2, // Read-Only Vector 2unsigned int* out_r,     // Output Resultint size                 // Size in integer) {unsigned int v1_buffer[BUFFER_SIZE];   // Local memory to store vector1unsigned int v2_buffer[BUFFER_SIZE];   // Local memory to store vector2unsigned int vout_buffer[BUFFER_SIZE]; // Local Memory to store result// Using the BIND_OP pragma the user can specify the operator, implementation
// and latency
#pragma HLS BIND_OP variable = v1_buffer op = mul impl = DSP latency = 2
#pragma HLS BIND_OP variable = v2_buffer op = mul impl = DSP latency = 2
#pragma HLS BIND_OP variable = vout_buffer op = add impl = DSP
// Using the BIND STORAGE the used can choose the type, resource and latency
#pragma HLS BIND_STORAGE variable = v1_buffer type = RAM_1P impl = BRAM latency = 2
#pragma HLS BIND_STORAGE variable = v2_buffer type = RAM_1P impl = LUTRAM latency = 2
#pragma HLS BIND_STORAGE variable = vout_buffer type = RAM_1P impl = URAM// Per iteration of this loop perform BUFFER_SIZE vector additionfor (int i = 0; i < size; i += BUFFER_SIZE) {
#pragma HLS LOOP_TRIPCOUNT min = c_len max = c_lenint chunk_size = BUFFER_SIZE;// boundary checksif ((i + BUFFER_SIZE) > size) chunk_size = size - i;// Auto-pipeline is going to apply pipeline to these loopsread1:for (int j = 0; j < chunk_size; j++) {
#pragma HLS LOOP_TRIPCOUNT min = c_size max = c_sizev1_buffer[j] = in1[i + j] * in1[i + j];}read2:for (int j = 0; j < chunk_size; j++) {
#pragma HLS LOOP_TRIPCOUNT min = c_size max = c_sizev2_buffer[j] = in2[i + j] * in2[i + j];}vadd:for (int j = 0; j < chunk_size; j++) {
// As the outer loop is not a perfect loop
#pragma HLS loop_flatten off
#pragma HLS LOOP_TRIPCOUNT min = c_size max = c_size// perform vector additionvout_buffer[j] = v1_buffer[j] + v2_buffer[j];}// burst write the resultwrite:for (int j = 0; j < chunk_size; j++) {
#pragma HLS LOOP_TRIPCOUNT min = c_size max = c_sizeout_r[i + j] = vout_buffer[j];}}
}
}

其中关键的优化指令如下:

// Using the BIND_OP pragma the user can specify the operator, implementation and latency
#pragma HLS BIND_OP variable = v1_buffer    op = mul impl = DSP latency = 2
#pragma HLS BIND_OP variable = v2_buffer    op = mul impl = DSP latency = 2
#pragma HLS BIND_OP variable = vout_buffer op = add impl = DSP


// Using the BIND STORAGE the used can choose the type, resource and latency
#pragma HLS BIND_STORAGE variable = v1_buffer    type = RAM_1P impl = BRAM     latency = 2
#pragma HLS BIND_STORAGE variable = v2_buffer    type = RAM_1P impl = LUTRAM latency = 2
#pragma HLS BIND_STORAGE variable = vout_buffer type = RAM_1P impl = URAM

运行 Vitis HLS 编译器,我们得到如下结果:

================================================================
== Pragma Report
================================================================
* Valid Pragma Syntax
+----------------+----------------------------------------------------------------+-------------------------+
| Type           | Options                                                        | Location                |
+----------------+----------------------------------------------------------------+-------------------------+
| bind_op        | variable = v1_buffer     op = mul    impl = DSP    latency = 2 | src/vadd.cpp:20 in vadd |
| bind_op        | variable = v2_buffer     op = mul    impl = DSP    latency = 2 | src/vadd.cpp:21 in vadd |
| bind_op        | variable = vout_buffer   op = add    impl = DSP                | src/vadd.cpp:22 in vadd |
| bind_storage   | variable = v1_buffer   type = RAM_1P impl = BRAM   latency = 2 | src/vadd.cpp:24 in vadd |
| bind_storage   | variable = v2_buffer   type = RAM_1P impl = LUTRAM latency = 2 | src/vadd.cpp:25 in vadd |
| bind_storage   | variable = vout_buffer type = RAM_1P impl = URAM               | src/vadd.cpp:26 in vadd |
+----------------+----------------------------------------------------------------+-------------------------+

请注意区分,一个变量可以同时使用这两种绑定,例如 v1_buffer 既被指定了op,又被指定了storage,op 绑定和 storage 绑定关注不同的方面。op 绑定关心的是如何执行计算,而storage 绑定关心的是如何存储数据。

4. 总结

这些指令指导了高级综合(HLS)工具在优化指定数组的存储和操作实现时的行为。它们有助于在 FPGA 设计中实现更好的性能和资源利用率。存储类型的选择(BRAM、LUTRAM 或 URAM)以及专用 DSP 资源的使用会影响设计的整体效率。指定的延迟控制了这些操作的时序特性。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux磁盘及读写数据原理/Raid技术/硬软raid及企业案例/磁盘分区环境搭建/格式化磁盘系列-12213字

高薪思维&#xff1a; 怎么才能一直去坚持下去&#xff1f; 1.做这件事情的好处&#xff0c;对自己一直去放大。 2.不做的坏处&#xff0c;并放大 3.学习痛苦&#xff1f;还是去上班&#xff08;餐饮、外卖痛苦&#xff1f;&#xff09; 用比学习更痛苦的事情&#xff0c;去对抗…

西瓜书学习——第一、二章笔记

文章目录 什么是机器学习?假设空间和版本空间基本术语机器学习任务分类 归纳偏好数据决定模型的上限&#xff0c;而算法则是让模型无限逼近上限评估方法留出法交叉验证法自助法调参与最终模型验证集和测试集的区别 性能度量均方误差错误率与精度查准率、查全率与F1ROC与AUC代价…

Python 实现 Mock 数据功能(模拟真实对象的行为)

当你需要在 Python 中测试某些代码时&#xff0c;有时你希望模拟&#xff08;或者说替换&#xff09;某些部分&#xff0c;以便更好地控制测试环境。这就是 Mock 功能的用武之地。Mock 对象可以模拟真实对象的行为&#xff0c;使你能够在测试中对其进行配置&#xff0c;以便更容…

函数模版实例化

目录 一、前言 二、 什么是C模板 &#x1f4a6;泛型编程的思想 &#x1f4a6;C模板的分类 三、函数模板 &#x1f4a6;函数模板概念 &#x1f4a6;函数模板格式 &#x1f4a6;函数模板的原理 &#x1f4a6;函数模板的实例化 &#x1f34e;隐式实例化 &#x1f349;显式实例化 …

揭秘链动3+1商业模式:打造未来商业新风潮

大家好&#xff0c;我是微三云周丽&#xff0c;今天给大家分析当下市场比较火爆的商业模式&#xff01; 小编今天跟大伙们分享什么是链动31模式&#xff1f; 在当今商业世界中&#xff0c;随着科技的飞速发展和消费者需求的不断升级&#xff0c;新的商业模式不断涌现。其中&a…

如何搭建一个vue2组件库(king-ui-pro)

文章引用图片无法查看&#xff0c;直接查看原文 感兴趣的可以关注或订阅下这个系列&#xff0c;后续会陆续将相关的组件与公共方法进行分享 目前已经完成了的组件有 多行省略pro版&#xff0c;不是简单的多行省略效果 公共方法&#xff1a; 1、图片预览&#xff0c;知乎的图…

leetcode(hot100)——贪心算法

55. 跳跃游戏 本题不用纠结于可以跳几步&#xff0c;可以聚焦于覆盖范围&#xff0c;即 当前位置当前跳数 能够覆盖的范围&#xff0c;若这个范围足以到达最后一个位置&#xff0c;则返回true&#xff1b;若for循环结束&#xff0c;则还没返回true&#xff0c;则返回false。 下…

苹果手机远程打卡教程

关于苹果手机远程打卡教程之——有电脑零成本版 &#x1f4ce;个人主页&#xff1a;我的主页 &#x1f4ce;小白一枚&#xff0c;欢迎指教&#x1f44f; 嗨嗨嗨&#xff0c;今天来出一期iPhone实现远程打卡的教程&#xff0c;让我们可以随时随地的打卡wherever&#xff5e; 准…

A4云打印仅需5分/页?云打印多少钱?云打印怎么收费?

随着互联网技术的发展&#xff0c;越来越多的同学在打印资料的时候都开始转向线上&#xff0c;转向云打印服务了。云打印服务不仅可以给我们节省很多时间&#xff0c;价格方面较打印店也更有优势。那么云打印多少钱&#xff1f;云打印怎么收费&#xff1f;今天小易就带大家来了…

了解IPS和IDS:这5个差异将改变你的安全观念!

IPS 代表 入侵防御系统&#xff08;Intrusion Prevention System&#xff09;&#xff0c;它是 IDS 的进一步发展&#xff0c;不仅具备检测攻击的能力&#xff0c;还能在检测到攻击后主动采取措施阻止攻击。IPS 通常部署在防火墙和网络设备之间&#xff0c;能够深度感知并检测流…

《自动机理论、语言和计算导论》阅读笔记:p225-p260

《自动机理论、语言和计算导论》学习第 9 天&#xff0c;p225-p260总结&#xff0c;总计 26 页。 一、技术总结 1.pushdown automation(PDA&#xff0c;下推自动机) 2.DPDA Deterministic PDA(确定性下推自动机)。 二、英语总结 1.instantaneous (1)instant: adj. happi…

基于python实现web漏洞挖掘技术的研究(django)

基于python实现web漏洞挖掘技术的研究(django) 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;网络爬虫&#xff0c;SQL注入&#xff0c;XSS漏洞工具&#xff1a;pycharm、Navicat、Maven 系统的实现与漏洞挖掘 系统的首页面 此次的系统首页面是登录的页…