Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算

一. 如何处理任意精度的数据类型

Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算

  • C语言支持的数据类型有字符型、整型(有符号和无符号)、浮点型、boolean类型等的,需要注意的是char 16_t和char 30_t这两个数据类型在Vivado HLS中是不支持的;
  • Vivado HLS继承了传统的C/C++包含的数据类型,包括char、short、int、float和double,又由于这些数据类型都是以8为边界的(8、16、32、64),有时候对于某些操作来说不够高效(比如进行18位的两个数的加法,需要定义两个32位的数),因此引入任意精度的数据类型来提高硬件效率;
  • 定义任意精度数据类型时最好将它声明在头文件里,方便debug;
  • 使用sizeof打印我们定义数据实际占用的内存空间;

二. 数据类型的初始化

1. 变量定义和初始化

Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算
关于拷贝初始化和直接初始化的区别:https://blog.csdn.net/linda_ds/article/details/82807006#commentBox
需要注意的是copy initialization不允许隐式转换,必须直接由初始化器(先类型转换等)产生T类型。在初始化尽可能的每行只初始化一个变量。

Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算ap_[u]fixed<W,I,Q,O>中的W是指总共的位数;I是正数部分的位数,W-I就是小数部分的位数;Q是量化模式,针对低位部分;O是溢出模式,针对高位部分。
Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算定义单精度浮点类型的时要有后缀f。

2. 隐式数据类型转换

Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算
隐式的数据类型转换包括Numeric promotion和Numeric conversion两种,promotion其实是一种安全的方式,把小类型的向大类型的数据转化(对于有符号数就是符号位的扩展,对于无符号数就是扩展0);conversion是将大类型向小类型转换,这种转换可能会导致数据的损失甚至结果的错误。

3. 显式数据类型转换

Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算
显式数据类型转换包括()和C++中采用的类似于调用函数的转换两种方式,我们的原则就是大数据不溢出,小数据不损失。

4. 获取变量数据类型

Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算
利用头文件# include中的 typeid函数来获取;

三. 复合数据类型在HLS中的应用

C++常用的两种符合数据类型:结构体和枚举类型

1. 结构体

Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算

  • scalar members被映射成scalar端口,默认情况下数组被映射成memory端口;
  • 建议将结构体预先在头文件中声明;
  • 对于结构体中的这些元素HLS提供了相应的优化方式——data packing,优化方式有两种,一种是field_level,结构体中每个元素都以8为边界;一种是struct_level,先保留每个元素的位宽,之后再将其扩展到以8为边界;

两种Data Pack Mode的不同
Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算

2. 枚举类型

Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算
struct 和 enum这两种类型都可以在顶层作为接口出现,如果结构体出现在顶层函数中会被data pack directive封装,枚举类型出现在顶层函数中作为接口,它实质上是正数,Vivado HLS会自动推断数据位宽。

四. Vivado HLS中的C++基本运算

进行基本运算时要特别注意数据位宽的处理,总体原则就是大数不溢出,小数不损失。
Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算
Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算Vivado HLS(High-level Synthesis)笔记二:数据类型及其初始化、复合数据类型、HLS中的C++基本运算

  • 算术运算符
  • 自增、自减运算符
  • 条件和关系运算符
  • 逻辑运算和位运算