跟Xilinx SAE 学HLS系列视频讲座笔记(5)—— 数组优化

    科技2022-09-05  120

    目录

    第一讲 数组分割第二讲 数组映射与重组第三讲 其他优化方法

    本节主要介绍的是《跟Xilinx SAE 学HLS系列视频讲座》第20,21,22节。 跟Xilinx SAE 学HLS系列视频讲座笔记(1) 跟Xilinx SAE 学HLS系列视频讲座笔记(2)—— 编写高效的C Test Bench 跟Xilinx SAE 学HLS系列视频讲座笔记(3)—— 接口综合 跟Xilinx SAE 学HLS系列视频讲座笔记(4)—— For循环优化 跟Xilinx SAE 学HLS系列视频讲座笔记(5)—— 数组优化 跟Xilinx SAE 学HLS系列视频讲座笔记(6)—— 函数优化

    第一讲 数组分割

    对于数组可以resource directive来明确告知HLS当前数组采用什么样的Memory(RAM、FIFO等)来实现,如果没有使用resource,Vivado HLS会自行决定采用单端口还是双端口(取决于哪种更好); 数组最终会以Memory形式出现(RAM、ROM或者FIFO),如果是顶层函数中的形参就会以相应Memory的接口呈现,包括读写地址、使能以及数据;如果数组是在内部,就会综合成内部的block RAM、LUTRAM、registers,这取决于优化设置;

    Vivado HLS提供了三种对数组分割的方法——Block/Factor、Cyclic/Factor、Complete;我们以一维数组为例。

    通过对比,我们可知采用三种方法,它们的效果都增强了,其中Complete是完全并行的方式。

    当然,在Block/Factor这种方式下,并不是越多的Block结果就越好,这取决于真实的数据流的需求;下例是采用Block3和Block2的性能对比,我们观察到它们的延迟是相同的,资源方面也仅仅有一些不同,可以忽略不计。

    对于多维数组 总结

    Vivado HLS提供了三种对数组分割的方法——Block/Factor、Cyclic/Factor、Complete数组分割可以提高吞吐量

    第二讲 数组映射与重组

    1. MAPPING

    在C代码中如果有多个小数组,可以通过map将它们合并成一个大数组,而这个大数组会综合成block RAM或者UltraRAM,降低资源用量,Vivado HLS提供了横向和纵向两种方式做映射;

    Horizontal(水平方向)的映射 对于Horizontal(水平方向)的映射,它减少了相应的Memory的资源,但对数据吞吐率并没有改善,因为Memory个数减少了,意味着读出数据的端口的个数也少了。

    Vertical(纵向)的映射

    对于Vertical(纵向)的映射,是将相应位置对应的元素做位拼接,所以最终数组长度仍然是原来数组中较长的数组长度,但是宽度发生了变化;

    数组分割和映射(横向)结合

    可以将数组分割和映射(横向)结合,先通过PARTITION将数组分割成两个模块,再通过MAP将分割的部分合并,这样的好处在于减少资源的同时获得吞吐率的提升

    2. ARRAY RESHAPE ARRAY_RESHAPE是将纵向的ARRAY_MAP和ARRAY_PARTITION结合起来,从而降低了资源用量,提高了并行度,因为ARRAY_PARTITION有三种形式,所以ARRAY_RESHAPE也有3种形式,ARRAY_SHAPE是针对同一个数组的。 例子 ARRAY_MAP可以减少资源用量,但是不能提高数据吞吐率,ARRAY_RESHAPE一定程度上在资源和数据吞吐量之间取得了平衡;

    3. 总结

    第三讲 其他优化方法

    1. 定义一个ROM

    可以通过关键字const+initial value的方法定义一个ROM,优势在于简单,不足之处在于如果长度过长时很容易出错且不易于代码管理。可以通过头文件,将ROM定义在头文件中(比较靠谱); 如果系数值是通过数学公式计算的并且未更新,则Vivado HLS将推断出ROM

    2. 改变ROM输出latency

    默认情况下,ROM输出latency为2;增加ROM输出latency可以改善这条路径上的时序 3. Array Initialization HLS要将数组映射为Memory实现时,需要在前面加关键字static,这个static不仅保证了作为Memory实现,还保证了最终综合生成的RTL和C在行为上一致的(当数组有初始值时,无static时对Memory有相应操作时首先要初始化,需要一定时间),加了static后初始化的值已经被写进执行文件中。 4. 总结

    Processed: 0.013, SQL: 9