本文转载自:FPGA打工人微信公众号
注:本文由作者授权转发,如需转载请联系作者本人
数据类型及精度
传统的C语言数据类型 以8为边界,即数据宽度为8的整数倍,比如32bit,64bit等,相比之下RTL数据的位宽即比较灵活,可以自定义,所以HLS引入了任意精度,采用任意精度的最大好处就是可以根据需求自定义位宽,进而降低对资源的消耗。
[u]是区分有符号数还是无符号数,
#include
#ifdef _NO_SYNTH_
typedef int data_t ;
#else
typedef ap_int<18> data_t ;
#endif
定点数据类型
定点化数据在FPGA算法实现中不说常用吧,应该是逃不过的一道坎。
ap_[u]fixed
详细说说参数Q和参数O:
上面也说过,参数Q默认情况是AP_TRN_ZERO,当设置为AP_RND后,采用的是四舍五入(四舍五入具体实现方法就是被保留的最后一位的下一位是1时,则在最后一位加1,否则直接移除)。
ap_fixed<3,2,AP_RND> data = 1.25;
3代表data的数据长度,2代表整个整数部分的数据长度,AP_RND表示Q参数为四舍五入,最后得到的结果为1.5:
当O设置为AP_SAT时,截取后的数据为其能表示的最大值。
ap_fixed<4,4,AP_RND,AP_SAT> data = 19;
4代表data的数据长度,第二个4代表整个整数部分的数据长度。AP_SAT表示截取后的数据为其能表示的最大值,因为第一位为符号位,所以最大值只能为7。
结构体
HLS也是支持结构体的,可能要注意的是,当结构体为函数的参数时,结构体中的标量数据会映射为scalar端口,数组则映射为memory端口。比如:
typedef struct {
data_t data_test ;
mem_t mem_test[5] ;
} test_str;
test_str StrPort(test_str data_in)
{
test_str data_out ;
int i ;
data_out.data_test = data_in.data_test + 20 ;
for (i=0;i<5;i++)
{
data_out.mem_test[i] = data_in.mem_test[i] - 20 ;
}
return data_out ;
}
枚举类型
枚举是用关键字enum来定义。
typedef enum
{
M_INLE,
M_TEST1,
M_TEST2,
M_END
}mode_t;
在上面的变量mode_t中占2bit,HLS会自动推断并分配给合适的位宽。若枚举出现在函数的参数中,则会作为一个整数来实现port。