您的位置 首页 元件

Xilinx Vivado HLS中Floating-Point(浮点)规划介绍

Xilinx Vivado HLS中Floating-Point(浮点)设计介绍-尽管通常Fixed-Point(定点)比Floating-Point(浮点)算法的FPGA实现要更快,且面积更高效,但往往有时也需要Floating-Point来实现。这是因为Fixed-Point有限的数据动态范围,需要深入的分析来决定整个设计中间数据位宽变化的pattern,为了达到优化的QoR,并且要引入很多不同类型的Fixed-Point中间变量。而Floating-Point具有更大的数据动态范围,从而在很多算法中只需要一种数据类型的优势。Xilinx Vivado HLS工具支持C/C++ IEEE-54标准单精度及双精度浮点数据类型,可以比较容易,快速地将C/C++ Floating-Point算法转成RTL代码。

编码风格与技巧

虽然一般Fixed-Point(定点)比FloaTIng-Point(浮点)算法的FPGA完结要更快,且面积更高效,但往往有时也需求FloaTIng-Point来完结。这是由于Fixed-Point有限的数据动态规模,需求深化的剖析来决议整个规划中心数据位宽改变的pattern,为了到达优化的QoR,而且要引进许多不同类型的Fixed-Point中心变量。而FloaTIng-Point具有更大的数据动态规模,从而在许多算法中只需求一种数据类型的优势。

Xilinx Vivado HLS东西支撑C/C++ IEEE-54规范单精度及双精度浮点数据类型,能够比较简略,快速地将C/C++ FloaTIng-Point算法转成RTL代码。与此一起,为了到达用户希望的FPGA资源与功能, 当运用Vivado HLS directives时需求留意C/C++编码风格与技巧相结合。

编码风格

1.1 单双精度浮点数学函数

#include

float example(float var)

{

return log(var); // 双精度自然对数

}

在C规划中, 这个比如, Vviado HLS 生成的RTL完结将输入转化成双精度浮点,并根据双精度浮点核算自然对数,然后将双精度浮点输出转化成单精度浮点。

#include

float example(float var)

{

return logf(var); // 单精度自然对数

}

在C规划中, logf才是单精度自然对数, 这个比如 Vviado HLS 生成的RTL完结将根据单精度浮点核算自然对数, 而且没有输入输出单双精度的互转。

1.2 浮点运算优化

咱们先来看一个比如,三个从代数上看起来差不多的写法,但其在Vivado HLS中归纳出来的是三个彻底不一样的成果。

void example(float *m0, float *m1, float *m2, float var)

{

*m0 = 0.2 * var; // 双精度浮点乘法,单双精度类型转化

*m1 = 0.2f * var; // 单精度浮点乘法

*m2 = var / 20.0f; // 单精度浮点除法

}

Vivado HLS将日m0, m1, m2归纳成不同的RTL完结。

由于0.2是一个不能准确表征的双精度数字, 所以m0运算会被Vivado HLS归纳成一个双精度浮点乘法, 而且将var 转化成双精度, 然后将双精度乘法输出m0转化成单精度。

特别留意,假如希望Vivado HLS归纳出单精度常熟,需求在常数后边加f, 如0.2f。这样m1归纳成一个单精度乘法的输出。同理,m2将被Vivado HLS归纳成单精度除法的输出。

咱们来看别的一个比如。

void example(float *m0, float *m1, float var)

{

*m0 = 0.2f * 5.0f * var; // *m0 = var;常数乘法被优化掉

*m1 = 0.2f * var * 5.0f; // 两个双精度浮点乘法

}

再来看另一个比如。

void example(float *m0, float *m1, float var)

{

*m0 = 0.5 * var; //

*m1 = var/2; //

}

m0运算会被Vivado HLS归纳成一个双精度浮点乘法, 而且将var 转化成双精度, 然后将双精度乘法输出m0转化成单精度。

m1运算会被Vivado HLS归纳成简略的右移运算。所以假如用户希望完结对var除以2, 就写成m1这种表达式,而不是m0的表达式。

并行度与资源复用

由于浮点运算比较整型,定点运算耗用更可观的资源。Vivado HLS会尽量用更有用的资源来完结浮点运算,当数据的相关性及束缚答应的情况下,在Vivado HLS中,会尽量复用一些浮点运算单元。为了阐明这个,咱们看一个简略的四个浮点加法比如, Vivado HLS复用一个浮点加法器来串行完结四个浮点加法。

void example(float *r, float a, float b,

float c, float d)

{

*r = a + b + c + d;

}

有时规划需求更高的throughput及更低的latency。这时就需求进步规划的并行度。以下面比如来阐明,在Vivado HLS就需求对for循环loop加pipeline与unroll 的directives。一起需求经过设置a,b,r0 为FIFO, 并对其重排以进步I/O带宽两倍。这样Vivado HLS就会归纳出两个浮点加法来并行完结,这是由于每个加法器核算是彻底独立的。

void example(float r0[32], float a[32], float b[32])

{

#pragma HLS interface ap_fifo port=a,b,r0

#pragma HLS array_reshape cyclic factor=2 variable=a,b,r0

for (int i = 0; i 《 32; i++)

{

#pragma HLS pipeline

#pragma HLS unroll factor=2

r0[i] = a[i] + b[i];

}

}

但是,假如更多杂乱的运算,或许会导致不独立的浮点运算,在这种情况下,Vivado HLS不能重新排列这些运算的次序,这样会导致更低的,不是所希望的复用。 下面举例来阐明怎么进步带有反应浮点运算的功能。

这个比如的累加会导致recurrence,而且一般浮点加法的latency大于一个时钟周期,加的pipeline directive并不能到达一个时钟周期完结一次累加的throughput。

float example(float x[32])

{

#pragma HLS interface ap_fifo port=x

float acc = 0;

for (int i = 0; i 《 32; i++)

{

#pragma HLS pipeline

acc += x[i];

}

return acc;

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/yuanjian/340216.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部