HLS实践 - 04 - 任意精度

简介: HLS实践 - 04 - 任意精度

概述


C/C++ 提供的数据类型固定为 8 位(8的整数倍):

  • char(8 位)
  • short(16 位)
  • int(32 位)
  • long long(64 位)
  • float(32 位)
  • double(64 位)
  • 精确宽度整数类型,例如 int16_t(16 位)和 int32_t(32 位)

创建硬件时,通常需要更准确的位宽。位宽设置不恰当可能会造成丢失数据或者浪费资源, Vivado 高级综合 (HLS) 提供多种位精确或任意精度数据类型,允许您使用任何(任意)宽度对变量进行建模。

在本次设计中,使用标准 C 类型综合设计。然后在该项目的基础上进行使用任意精度类型进行优化对比。

使用标准C数据类型


添加文件进行设计,该工程文件根据之前的工程进行修改,在source中添加adders.cpp和adders.h,因为任意精度里的定点数表示只在C++中可以使用所以在这里定义为cpp文件。

此时使用的是标准C的数据类型

adders.cpp

#include "adders.h"
double adders(double in1, double in2, double in3) {
#pragma HLS INTERFACE ap_ctrl_none port=return
// Prevent IO protocols on all input ports
#pragma HLS INTERFACE ap_none port=in3
#pragma HLS INTERFACE ap_none port=in2
#pragma HLS INTERFACE ap_none port=in1
  double sum;
  sum = in1 + in2 * in3;
  return sum;
}

adders.h

#include "adders.h"
double adders(double in1, double in2, double in3) {
#pragma HLS INTERFACE ap_ctrl_none port=return
// Prevent IO protocols on all input ports
#pragma HLS INTERFACE ap_none port=in3
#pragma HLS INTERFACE ap_none port=in2
#pragma HLS INTERFACE ap_none port=in1
  double sum;
  sum = in1 + in2 * in3;
  return sum;
}

test bench里添加下面文件内容:

#include <stdio.h>
#include "adders.h"
int main()
{
  double inA, inB, inC;
  double sum;
  // For adders
  double refOut[2] = {6.66058944, 12.91818944};
  int i;
  inA = 0;
  inB = 2.1288;
  inC = 3.1288;
  // Call the adder for 2 transactions
  for (i=0; i<2; i++)
  {
    sum = adders(inA, inB, inC);
    fprintf(stdout, "    %lf+%lf*%lf=%lf \n", inA, inB, inC, sum);
    fprintf(stdout, "ref:%lf+%lf*%lf=%lf \n", inA, inB, inC, refOut[i]);
    inB=inB+1;
    inC=inC+1;
  }
  return 0;
}

完成添加后进行C综合并进行C仿真。此时的延迟和资源使用情况如下:

image.png

此时使用了14个DSP48资源。此时的仿真结果为:

image.png

保证了小数点后6位的精度。

使用任意精度类型


因为任意精度里的定点数表示只在C++中可以使用所以在这里定义为cpp文件。

修改source中的参数的数据类型。

adders.cpp

#include "adders.h"
doubl1 adders(doubl in1, doubl in2, doubl in3) {
#pragma HLS INTERFACE ap_ctrl_none port=return
// Prevent IO protocols on all input ports
#pragma HLS INTERFACE ap_none port=in3
#pragma HLS INTERFACE ap_none port=in2
#pragma HLS INTERFACE ap_none port=in1
  double sum;
  sum = in1 + in2 * in3;
  return sum;
}

adders.h

#ifndef ADDERS_H_
#define ADDERS_H_
#include "ap_fixed.h"
typedef ap_fixed<24,8> doubl;
typedef ap_fixed<26,8> doubl1;
doubl1 adders(doubl in1, doubl in2, doubl in3);
#endif

完成添加后进行C综合并进行C仿真。此时的延迟和资源使用情况如下:

image.png

仿真结果,此时的仿真结果为:

image.png

此时的数据类型保证了小数点后5位的数据正确性,并且节约了12个DSP48资源。

目录
相关文章
|
18天前
|
编解码 人工智能 开发者
长短大小样样精通!原始分辨率、超长视频输入:更灵活的全开源多模态架构Oryx
【10月更文挑战第23天】Oryx 是一种新型多模态架构,能够灵活处理各种分辨率的图像和视频数据。其核心创新在于能够对图像和视频进行任意分辨率编码,并通过动态压缩器模块提高处理效率。Oryx 在处理长视觉上下文(如视频)时表现出色,同时在图像、视频和3D多模态理解方面也展现了强大能力。该模型的开源性质为多模态研究社区提供了宝贵资源,但同时也面临一些挑战,如选择合适的分辨率和压缩率以及计算资源的需求。
27 3
|
3月前
深入解析802.11g标准及其频率范围
【8月更文挑战第24天】
88 0
|
5月前
|
Java Linux
ffmpeg音频格式转换、合成、速率调整
ffmpeg音频格式转换、合成、速率调整
113 2
|
6月前
|
编解码 算法 异构计算
m基于CCSDS标准的LDPC编码器的FPGA实现,包含testbench,码长1024,码率0.5
在Vivado 2019.2中进行的LDPC码仿真展示了算法的良好效果。LDPC码是一种1962年由Gallager提出的稀疏校验矩阵线性分组码,利用Tanner图表示编码解码结构。CCSDS标准定义的LDPC(1024,512)码具有准循环结构,适用于空间通信,其编码通过填充信息比特和校验节点的线性组合实现。Verilog代码示例展示了TEST_encoder_top模块,用于控制LDPC编码过程,包括时钟、复位信号处理和中间数据读取。
82 1
|
人工智能
支持跨语言、人声狗吠互换,仅利用最近邻的简单语音转换模型有多神奇
支持跨语言、人声狗吠互换,仅利用最近邻的简单语音转换模型有多神奇
164 0
|
C语言 C++ 异构计算
HLS开发学习-04- 数据类型的处理--任意精度数据类型
HLS开发学习-04- 数据类型的处理--任意精度数据类型
185 0
HLS开发学习-04- 数据类型的处理--任意精度数据类型
|
异构计算
HLS开发学习-13- 数组优化
HLS开发学习-13- 数组优化
491 0
HLS开发学习-13- 数组优化
|
BI 索引
HLS开发学习-06- 数据类型的处理-- HLS 中的复合数据类型
HLS开发学习-06- 数据类型的处理-- HLS 中的复合数据类型
206 0
HLS开发学习-06- 数据类型的处理-- HLS 中的复合数据类型
【Cubase】Cubase 量化设置 ( 量化预置 | 长度量化 | 快捷键设置 | 量化开头 | 量化 MIDI 事件结尾 | 量化 MIDI 事件长度 )(一)
【Cubase】Cubase 量化设置 ( 量化预置 | 长度量化 | 快捷键设置 | 量化开头 | 量化 MIDI 事件结尾 | 量化 MIDI 事件长度 )(一)
578 0
【Cubase】Cubase 量化设置 ( 量化预置 | 长度量化 | 快捷键设置 | 量化开头 | 量化 MIDI 事件结尾 | 量化 MIDI 事件长度 )(一)