HLS通过ALLOCATION减少资源-Xilinx-AMD社区-FPGA CPLD-ChipDebug

HLS通过ALLOCATION减少资源

Vitis HLS会自动探测算法中的并行性,尽可能将函数或逻辑并行执行以降低整体的Latency。例如,我们以如下函数为例。待综合的顶层函数loop_sequential包括两个for循环,这两个for循环彼此独立,不存在数据依赖关系(所谓数据依赖是指前者的运算结果给后者使用,换言之,前者写数,后者读数)。因此,Vitis HLS会将这两个for循环并行执行。这可在Schedule Viewer视图中确认。Vivado HLS在默认情况下则是将这两个for循环顺序执行,这是和Vitis HLS的差异。
图片[1]-HLS通过ALLOCATION减少资源-Xilinx-AMD社区-FPGA CPLD-ChipDebug
图片[2]-HLS通过ALLOCATION减少资源-Xilinx-AMD社区-FPGA CPLD-ChipDebug
另一方面,从并行性的角度而言,如果这两个for循环的循环边界相同即tripcount一致,那么可以将这两个for循环合并。这种合并可以通过两种方法实现,一种是在待代码层面合并,这需要我们在代码开发初期有意识地将相关语句放在一个for循环里。另一种是通过pragma LOOP_MERGE将两个for循环合并。但LOOP_MERGE的前提是两个for循环边界一致。对于上述案例,两个for循环的循环边界分别为xlimitylimit,是不同的,故无法用LOOP_MERGE合并。
这里,这两个for循环并行执行意味着需要消耗两个累加器,这其实就是通过增加资源提升速度。那么反过来我们也可以通过降低资源来降低并行度。这正体现了FPGA设计中面积与速度互换的原则。那么具体如何操作呢?
首先,我们对上述代码稍加改造,如下图所示。将for循环封装为一个函数sub_func,这样顶层函数就由两个子函数构成。同样,在默认情况下,Vitis HLS会将这两个函数并行执行。
图片[3]-HLS通过ALLOCATION减少资源-Xilinx-AMD社区-FPGA CPLD-ChipDebug

接下来,我们在loop_functions里使用ALLOCATION,其作用对象为子函数sub_func,如下图所示。ALLOCATION之后紧跟function,表明将其施加于某个函数上,instances的值为函数名称,limit的值(这里为1)表明该函数对应的RTL模块只会被实例化一份。

图片[4]-HLS通过ALLOCATION减少资源-Xilinx-AMD社区-FPGA CPLD-ChipDebug
由于该模块只被实例化一份,那么两次累加操作就需要分时复用这个累加器,从而实现了资源共享,但也降低了性能,这可从Schedule Viewer视图中验证。
图片[5]-HLS通过ALLOCATION减少资源-Xilinx-AMD社区-FPGA CPLD-ChipDebug
实际工程中,我们发现有时ALLOCATION并未生效,一方面要检查是否对相应函数关闭了INLINE,另一方面要检查是否对相应函数使用了PIPELINEHLS在执行C综合时,其中一个关键的步骤是ScheduleSchedule的优先级高于ALLOCATION。工具会优先考虑所有函数的执行顺序,再决定是否可以ALLOCATION
此外,ALLOCATION还可以指定某类资源的用量,如下图所示。通过指定操作,可以限定LUTDSP等的用量。
图片[6]-HLS通过ALLOCATION减少资源-Xilinx-AMD社区-FPGA CPLD-ChipDebug
 
 

请登录后发表评论

    没有回复内容