FPGA/ASIC技术
在上一章“High LevelSynthesis(HLS) 从一个最简单的fir滤波器开始2”中,我们通过修改c的头文件里面的类型精度定义,把DSP48E的消耗数量从8个压缩到了2个:
但这个结果仍然不是最优的结果。理论上如果采用串行的结构,乘加运算可以复用,虽然latency会变长,但是一个fir滤波器最少只需要1个乘法器即可实现。但是我们之前的c代码,HLS确采用的2个乘法运算单元,这是为什么呢?
我们还是先看下原先的代码结构,简单起见,只放相关的片段:
我们可以看到,在上述c代码中,我们写了2处乘法运算,在默认的优化等级,且不加任何约束的情况下,HLS是直接一一对应翻译的过程,把这2处乘法运算直接映射成了RTL代码中的2个乘法单元。
其实稍微深入分析一下既可发现,c代码中的2处乘法运算,不会同时执行!①处的乘法运算,只有在i==0时才会执行;②处的乘法运算,只有在i≠0的时候才会执行。这两处乘法运算从逻辑上永远不会冲突(同时执行),也就意味着在理论上它们可以合并成一个乘法运算!
从上面的分析,我们可能会认为HLS工具是很“笨”的,为什么上述很简单是可以合并的乘法运算,它却没有办法分析出来呢。其实这是误解,HLS虽然是直接的翻译过程,但很多情况它是可以智能识别代码中某些可以合并的逻辑,并自动合并的。我们只需要设置一下HLS综合时的优化等级即可,就跟我们在c编译的时候设置优化等级一样。如何做呢?
1、在GUI界面下,邮件点击solution
2、选择solution settings…
3、在弹出的界面里面选择Add…
4、在弹出的界面里,选择config_bind(合并的意思),设置effortlevel为high,填写min_opp为mul(乘法的意思)
全部设置完成后,我们重新跑一遍HLS综合流程,既可以发现,综合后的资源消耗里面,DSP48E的个数变成了1个:
除了上面的,修改HLS综合工具设置的办法(把cofig_bind合并属性的effortlevel调高)之外,还有一个办法,可以达到上述一样的目的。这种办法就是:修改c代码,在c源代码里面只显性的出现一处*乘法运算
对于此fir滤波器的例子,我们可以把代码修改如下。功能没有任何改变,只是改变了c的写法,在代码中仅显式的出现了一处乘法运算。从综合结果里面可以看到,仅使用了一个DSP48E。
这两种方法,我本身更倾向于第2种,即重构c代码的结构,来引导HLS综合出想要的结果。这样的方式适应性更好,可以让我们对c到rtl的映射过程,有更深入和精确的把握!
全部0条评论
快来发表一下你的评论吧 !