参考博客:
https://blog.csdn.net/weixin_36520607/article/details/53152718
https://blog.csdn.net/zhangningning1996/article/details/107383183
https://blog.csdn.net/christne1225i/article/details/53353801
资源浪费
设计硬件时,往往是要求更精确的位宽。例如,一个filter的输入是12位和一个累加器的结果只需要一个最大范围为27位。然而对于硬件设计来说,使用标准的C数据类型会造成硬件成本的浪费。这就会造成我们要使用更多的LUT和寄存器,延迟甚至可能超过时钟周期和需要更多的周期来计算结果。这往往不是我们需要的结果。因此下面我将介绍如何利用Vivado HLS处理许多位准确或任意精度数据类型,以及允许使用任何(任意)宽度的模型变量。
例如,采用C语言去描述一个18*18 bits的乘法器,那么就需要将输入数据都声明为32 bits(int),结果声明为64 bits(long long),这将会在FPGA中消耗4个DSP48E1(DSP48E1乘法器是25x18 Multiplier),显然这是很浪费资源的。
Vivado HLS ap_fixed数据类型
任意精度定点数定点数
C++ Arbitrary Precision Fixed Point Types的缩写就是ap_fixed。编译这个类型,要加上**#include <ap_fixed.h>**头文件
定义如下
ap_[u]fixed<int W,
int I,
ap_q_mode Q,
ap_o_mode O,
ap_sat_bits N>;
W:宽度,数据占用的位宽,
I:整数部分的位数,那么(W-I)就是小数部分fraction占用的宽度了
Q:量化模式
AP_RNDAP_RND——指示该值应舍入到最接近ap_ [u]定点类型的可表示值;
AP_RND_ZERO ——向零取整;
AP_RND_MIN_INF——向负无穷取整;
AP_RND_INF ——向正无穷取整。
O:溢出模式
Saturation AP_SAT ——取到剩余位数能表示的最大的值
p_ufixed<4, 4, AP_RND, AP_SAT> UAPFixed4 = 19.0; // Yields: 15.0 4位无符号最大能取到15
ap_fixed<4, 4, AP_RND, AP_SAT> UAPFixed4 = 19.0; // Yields: 7.0 4位有符号数最大能取到7
ap_ufixed<4, 4, AP_RND, AP_SAT> UAPFixed4 = -19.0; // Yields: 0.0 4位无符号最大能取到0
ap_fixed<4, 4, AP_RND, AP_SAT> UAPFixed4 = -19.0; // Yields: -8.0 4位有符号极限能取到-8
AP_SAT_ZERO
ap_ufixed<4, 4, AP_RND, AP_SAT_ZERO> UAPFixed4 = 19.0; // Yields: 0.0
ap_fixed<4, 4, AP_RND, AP_SAT_ZERO> UAPFixed4 = 19.0; // Yields: 0.0
ap_ufixed<4, 4, AP_RND, AP_SAT_ZERO> UAPFixed4 = -19.0; // Yields: 0.0
ap_fixed<4, 4, AP_RND, AP_SAT_ZERO> UAPFixed4 = -19.0; // Yields: 0.0
AP_WRAP
ap_ufixed<4, 4, AP_RND, AP_WRAP> UAPFixed4 = 19.0; // Yields: 3.0 10011取低4位就是3
ap_fixed<4, 4, AP_RND, AP_WRAP> UAPFixed4 = 31.0; // Yields: -1.0
ap_ufixed<4, 4, AP_RND, AP_WRAP> UAPFixed4 = -19.0; // Yields: 13.0
ap_fixed<4, 4, AP_RND, AP_WRAP> UAPFixed4 = -19.0; // Yields: -3.0