![0dba3919b37bbf0103b7be3924cad43a.png](https://i-blog.csdnimg.cn/blog_migrate/a109cfd50fd51cb53196906e50ca87a1.jpeg)
本文整理自高亚军老师的Vivado HLS视频教程
1. HLS新的数据类型
C/C++数据类型:
![2ba595c9cda413c7b80c98bc2c0c78ff.png](https://i-blog.csdnimg.cn/blog_migrate/445eba943df67ee6e6bc22a47e98edd7.jpeg)
其中HLS中不支持char16_t和char32_t两种数据类型。在C/C++中,所有的数据位宽都是基于8-bit,即位宽都是8-bit的倍数,当在逻辑中使用时,会明显造成资源的浪费,因此HLS中引入了Arbitrary Precision Data Type。
HLS中的Arbitraty Precision Data Types:
![2e2f691abab33e75744756797ac010e3.png](https://i-blog.csdnimg.cn/blog_migrate/efac65d39900219d3315349faf3fb6d3.jpeg)
其中W表示数据长度;I表示整数长度;Q表示量化方式;默认的为AP_TRN_ZERO,即Truncation to zero方式;O表示溢出模式,默认为AP_WPAP即Wrap Around方式。
![85a34e322e59ab8379332df1451bc815.png](https://i-blog.csdnimg.cn/blog_migrate/91d9ee3fa1ce98ee8e28a2323a7542e9.jpeg)
eg1.截位方式的影响
ap_fixed<3,2> var1 = 1.25;
ap_fixed<3,2,AP_RDN> var2 = 1.25;
1.25的二进制表示为:0 1.0 1,按第一种方式默认的TRN模式,则会将后面的1直接砍掉,剩下0 1.0,得到实际的结果是1.0;第二种方式的RDN是4舍5入的方式,后面的1进位到前一位,得0 1.1,实际结果为1.5。
eg2.溢出方式的影响
ap_fixed<4,4> var3 = 19;
ap_fixed<4,4,AP_RND,AP_SAT> var4 = 19;
19的二进制表示为0 1 0 0 1 1,第一种方式截取低4位,得到0011,对应10进制3;第二种方式中,由于19大于4 bits无符号数能表示的最大范围,因此按最大值取,得15。
可以使用sizeof()函数来查看数据所占用的空间大小。
ap_int<1> a; // a占用1个Byte
ap_int<8> b; // b也占用1个Byte
在VS中也可以使用HLS的任意数据类型,只需将VS工程的库路径设置为HLS的路径即可。当头文件中包含<hls_math.h>时,VS编译会报错,hsl_math.h里面包含的几个其他的头文件中的错误,这是将hls_math.h改为cmath,再综合就没有错误了。
![4b3d0cc701e1dac688ffc7a70780ba28.png](https://i-blog.csdnimg.cn/blog_migrate/ebd25aac3bda9ed6976384b6a66a9b22.jpeg)
2. 变量初始化
变量可以使用copy initialization方式或者direct initialization()方式。
![02fccc0ebced0b8f6d47a27e7dbd3504.png](https://i-blog.csdnimg.cn/blog_migrate/18fa99413a5c4a649f32d4e9797acf4f.jpeg)
需要注意的是:
1.在定义单精度浮点数据类型时,需要有后缀f:
float var = 5.0(f)
2.当常数参与到具体的运算中,要明确告知其数据类型:
a = a + ap_fixed<6,4>(0.25);
3.HLS中不支持的C/C++的代码方式:动态分配、涉及OS的和递归操作。
3. 数据类型的转换
有隐式转换和显式转换两种。
隐式转换:有promotion(扩展)和conversion(截取),其中promotion时会自动扩符号位,当conversion时会截取低位。
显式转换:采用()或者调用函数的方式。
ap_uint<3> i3 = 4;
ap_uint<4> i4 = 10;
ap_ufixed<6,4> i5 = i4/i3; // 结果 2
ap_ufixed<6,4> i6 = (ap_fixed<6,4>)i4/i3; // 结果 2.5
ap_ufixed<6,4> i7 = ap_fixed<6,4>(i4)/i3; // 结果 2.5
可以用tpyeid()来获取数据的类型,需要typeinfo头文件。
4. 复合数据类型
复合数据类型包括struct和enum类型。
在HLS中对struct类型有Byte Pad的选项,可选field level和struct level类型,其中field level类型表示每个变量都要扩展为8-bit整数倍的位宽;struct level类型表示每个变量的实际位宽保留,但整体封装后要扩展为8-bit整数倍位宽。
对于enum类型,当在top level时,会当做一个具体的数据来应用。
5. 复数的应用
在使用复数时,应包含有头文件<complex>,并且使用std来定义一个复数,复数的乘法可以采用常规的分别计算实部和虚部的方式,如下图所示。
![18cedee2e57256c948cd1190984c6140.png](https://i-blog.csdnimg.cn/blog_migrate/f3fe580522595efc518c59e78c4e6588.jpeg)
![1b1ff95aa981894f02d8d8d1c4f3f8fb.png](https://i-blog.csdnimg.cn/blog_migrate/ad3ff05ba7bed916eb48417783f0c32d.jpeg)
采用这种乘法方式进行了4次乘法和2次加法,也可以对该结构进行变换,如下图所示。用下面的这种方式,需要3次乘法和5次加法。
![a15f6b5e02709f7255a2abae67091b19.png](https://i-blog.csdnimg.cn/blog_migrate/c870996df7d2ec803f6f0d32914fa4f1.jpeg)
微信公众号:Quant_Times