这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » 在Vivado Hls中,数据类型的转化分析

共1条 1/1 1 跳转至

在Vivado Hls中,数据类型的转化分析

菜鸟
2017-06-28 16:14:25     打赏
如何对任意精度类型的变量初始化

对于ap_int类型

在C/C++里,是通过变量类型+变量名+数值,来对一个变量初始化,同样,对于任意精度的数据类型,我们也可以采用这种方式来进行变量初始化。在Vivado Hls里是支持copy initialization(Y)和direct initialization(Y)这两种方式来进行初始化,但不支持uniform initialization,同时,对于任意精度的数据类型,还可以采用基数符号+数值+基数,例如: 
int data_i = 5; 
ap_int<8> a_8bit_data_c = 18; 
ap_int<8> a_8bit_data_d (18); 
ap_int<8> a_8bit_data_r2("0b010010",2); 
ap_int<8> a_8bit_data_r8("0o22",8); 
ap_int<8> a_8bit_data_r10("18",10); 
ap_int<8> a_8bit_data_r16("0x12",16); 

注意:上面的基数符号是可以去掉的,在初始化的时候,尽可能每一行只初始化一个变量,避免在一行初始化多个变量
对于ap_fixed类型

前面我们提到ap_fixed< W,I,Q,O>,这里W代表整个数据的字长,I代表整数部分的字长,那么小数部分被的字长就是W-I,Q表示量化模式(针对低位部分),O表示溢出模式,针对高位部分,例如:

ap_fixed<3,2> data1 = 1.25; 
ap_fixed<3,2,AP_RND> data1 = 1.25 
此时的结果分别为1(等价于01.0)和1.5(等价于01.1)

ap_fixed<4,4> data3 = 20 
ap_fixed<3,2,AP_RND,AP_SAT> data1 = 20 
此时的结果分别为4(等价于0100)和7(等价于0111)

对于浮点类型

对于单精度类型浮点需要有后缀f,对于双精度则可以省略,例如: 
double data1(2.0) 
flout data2(2.0f) 
Vivado Hls对这些数据类型都是支持的,并且还提供一个数学库hls_math.h,它对C语言(math.h)和C++(cmath.h)都是支持的,这种支持包括单精度,双精度浮点的一些函数,还包括对数据类型本身的支持。

数据类型的转换

隐式数据类型转换

隐式数据类型转换包括Numeric promotion 和 Numeric conversion。 
Numeric promotion是一种安全模式,它把数据类型从小类型向大类型的数据转换,对于有符号数据类型,就是进行数据位的扩展,对于无符号数据类型来说,就是进行高位0扩展,例如: 
ap_uint<8> data; 
ap_int<4> x1 = -4; 
ap_uint<4> x2 = 4; 
data1 = x1; 
data2 = x2; 
这里得到的data1为252(0b11111100),由于x1为有符号,所以进行符号位的扩展,而data2为4(0b00000100),由于x2为无符号,所以进行高位0的扩展。

Numeric conversion是把大类型向小类型的数据转换,这种转换可能导致数据的损失或者结果的错误,例如: 
ap_int<2> data; 
ap_int<4> x3 = -3; 
ap_uint<4> x4= 3; 
data3 = x3; 
data4 = x4; 
这里得到的data3为-1(0b11),data4为-1(0b11),这是由于data为有符号数据类型,导致结果错误。 
ap_fixed<4,2> data5 = 1.25; 
ap_fixed<3,2,AP_RND> data6 = data5 
这里得到的data6为1.5(0b01.1),导致数据精度的损失。

显式数据类型的转换

显式数据类型的转换有两种方式,一种是通过“( )”操作,另一种是在C++中通过类似调用函数的方式进行转换,例如: 
`ap_uint<3> i1 = 2; 
ap_uint<4> i2= 7; 
ap_ufixed<6,4> i3 = i2 / i1; 
cout << “The result of i3 :\t” << i3 <<’\n’;

ap_ufixed<6,4> i4 =(ap_ufixed<6,4>) i2 / i1; 
cout << “The result of i4 :\t” << i4 <<’\n’;

ap_ufixed<6,4> i5 = ap_ufixed<6,4> (i2 )/ i1; 
cout << “The result of i5 :\t” << i5 <<’\n’;` 
这里得到的i3为3,而i4和i5为3.5,3.5才是我们要的结果,因此对于显式数据类型的转换,可以(括号数据类型类型)+变量名 和 数据类型+(变量名)来完成转换。

注意:在Vivado Hls 中常用的二进制运算有+,-,*,/ , %这五种。两个数相加,为防止溢出,位宽会增加一位。两个数相乘,最终位宽为两个数位宽之和。我们的原则是,大数据不溢出(否则导致结果错误),小数据不损失(否则导致精度损失)。当我们想要获取变量的数据类型,我们可以使用typeid(变量名),相应的我们需要声明typeinfo.h这个头文件。

总结

本文介绍了数据类型的转化,在Vivado Hls中,我们要根据算法的类型来确定合理的位宽,这对运算的结果至关重要,此外,我们在完成数据转换时,可以采用显式数据转换的两种方式。


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]