HLS系列 – High Level Synthesis(HLS) 从一个最简单的fir滤波器开始2

FPGA/ASIC技术

194人已加入

描述

在这个系列的上一篇文章“HighLevel Synthesis(HLS) 从一个最简单的fir滤波器开始1”中,我们从一个最简单的FIR滤波器,介绍了HLS是如何把C映射成RTL代码的一些基本细节:
1、c函数的参数,会映射成RTL代码的输入或者输出;
2、HLS会自动在RTL代码接口上加入clk和rst信号;除此之外,还可以选择性加入其它一些系统控制信号;
3、c函数里面的变量,一般会映射成寄存器;数组可能会映射成RAM
4、c里面的加减乘运算,也会映射成RTL里面的加减乘运算;一般乘法运算用FPGA里的DSP Block来实现
5、c里面的循环,if else等控制,也会映射成RTL里面的状态机或者if else控制逻辑。

在这一章里,我们尝试去修改下代码结构,或者加入一些约束,在c函数基本功能不变或者微小变化的情况下,去控制HLS生成不一样的RTL代码逻辑电路结构。

让我们先从如何控制变量的精度(硬件电路里面,具体为表示信号所需要用的位宽)开始。

我们知道rtl和c最大的区别之一,是c里面只能选择8bit(char),16bit(short),32bit(int,float),和64bit(long,double)四种表示变量所占bit位宽的定义,而在rtl里面,我们可以灵活的选择任意位宽来表示一个变量。在FPGA里面,不合适的位宽表示,通常意味着资源的浪费,尤其是对于一些重要的资源如DSP Block,Block RAM等。

在上一篇例子中,我们定义的fir滤波器,其变量都是采用的32bit整形,其一个乘法器要占用掉4个DSP Block。为了更直观,我把上一篇的.c,.h,和综合结果贴在下面:

FIR

上述代码在HLS中不加任何约束,其综合结果资源消耗如下:

FIR

上述这段代码,一共消耗掉了8个DSP48E。之所以会这样,
上述代码综合后,在RTL里面一共生成了2个乘法运算;
每个32bit的乘法运算,在FPGA里面要消耗4个DSP Block;

上述的DSP48E消耗数量,很可能不是一个较优的结果。假设我们的变量和系数,都只有18bit位宽,用int型32bit表示显然是太浪费了。那么我们如何修改代码,去控制HLS综合出我们想要的结果呢?其实很容易做到,在HLS里面,对标准C做了扩展,我们可以用任意精度的bit位宽(其实限制在1-1024之间)来定义我们的变量。

对于整形变量,HLS里面提供了扩展整形定义intN(1≤N≤1024)来进行修饰,只需要在头文件里面包含ap_cint.h即可。具体做法如下,只需要把头文件改成如下即可:

我把修改头文件后的综合结果也附在了一起。我们可以看到, 在c的头文件里面修改类型精度定义后,最终的综合结果里面,其DSP48E仅消耗2个,这同样是2个因素作用的结果:

上述代码综合后,在RTL里面仍然生成了2个乘法运算,这一点没有改变;

但是一个18bitx18bit的乘法器,在FPGA里面只消耗1个DSP48E;(其实一个DSP48E支持25x18的乘法运算,读者可以自己实验把coef_t的定义改成int25,综合后的DSP48E个数不会改变,仍然是2个)

这个结果比之前有很大的改善,但是它仍然还存在瑕疵,不是最优的结果。

比如说,现在仍然要消耗2个DSP48E去实现2个乘法运算。其实按照常理来讲,如果是以串行方式实现的上述fir滤波器,那么理论上只需要1个DSP48E实现1个乘法运算就足够了。也就是说,上述c代码中的2处乘法运算,其实可以合并成一路乘法运算。

但HLS综合过程并没有这么做(或者说没有分析出来这2个乘法运算其实是可以合并公用一个乘法单元的),为什么HLS没有识别出来呢,我们怎么控制才能达到想要的结果呢?留待下章分解!

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 相关推荐
  • FIR

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分