一个HLS Stream应用案例

2019-10-30 21:53:11 浏览数 (2)

思考空间

对于如图11所示的顶层函数,HLS会将其接口综合成何种形式?

图11 形参为stream的顶层函数图11 形参为stream的顶层函数

对于顶层函数,如果形参类型为hls::stream,HLS会将其综合为ap_fifo类型的接口。

这里,我们看一个HLS Stream应用案例。顶层函数top由两个底层函数read_data和handle_data构成,其中read_data主要功能是从输入stream上获取特定数据;handle_data的主要功能则是对获取的数据进行处理。这里主要是为了说明stream的使用方法,所以,请大家把关注点放在stream的定义、函数之间的参数传递以及相应的directive的设置等。实际上,read_data和handle_data是可以合并的。

图1 头文件图1 头文件
图2 read_data源代码图2 read_data源代码
图3 handle_data源代码图3 handle_data源代码
图4 top源代码图4 top源代码

从图2和图3的代码中可以看到,从流中读取数据可以用>>或read(),向流中写入数据可以用 << 或write()。同时,在使用 << 或 >> 时,并不需要添加#include <iostream>。

首先,执行C功能仿真,仿真结束时会出现如图5所示的warning。

图5 C Simulation时出现的warning图5 C Simulation时出现的warning

第二步,不设置任何directive,直接执行C综合,此时会显示如下错误信息。该信息表明,在非dataflow区域使用默认的FIFO规模(这个FIFO是因为stream而生成的,默认深度为1),会导致Deadlock。根据提示我们修改这个FIFO的深度。之后,重新执行C综合和C/RTL Cosimulation,均可通过。

图6 修改FIFO深度图6 修改FIFO深度

第三步,进一步优化,可以看到这两个底层函数是可以应用dataflow以降低latency。具体设置如图7所示。执行C综合,综合结束时会显示如图8所示信息。[HLS214-111]显示静态变量和非静态Stream不能在同一个DATAFLOW区域中使用,故需要对top.cpp第4行进行修改,只需添加static关键字,如图9所示。再次综合,该warning即被消除。

图7 设置DATAFLOW图7 设置DATAFLOW
图8 C综合后显示的warning图8 C综合后显示的warning
图9 添加static关键字图9 添加static关键字

如果只设置DATAFLOW,而不设置FIFO深度,C综合是可以通过的,但执行C/RTL Cosimulation时,会显示如图10所示错误信息。可以判断与FIFO的读写相关。这通常是因为出现了FIFO写满或者FIFO读空,从而造成DEADLOCK。从这个角度而言,先设置一个solution,不用进行任何directive的设置,执行C综合,尽可能地修复所有的warning。这个阶段给出的warning及修复建议更具体、更具有针对性。

图10 C/RTLCosimulation错误信息图10 C/RTLCosimulation错误信息

第四步,进一步优化,由于数组key深度只有8,可以完全打散,用register代替,具体设置如图11所示。

图11 Array partition图11 Array partition

至此,我们创建了3个Solution:

Solution 1: 设置FIFO深度

Solution 2: 设置FIFO深度 设置DATAFLOW

Solution 3: 设置FIFO深度 设置DATAFLOW ARRAY PARTITION

3个Solution综合后的性能对比如图12所示。

图12 性能对比图12 性能对比

从这个案例我们可以得出如下结论:

-流用于内部函数间的参数传递时,会被综合为深度为1的FIFO

-当流数据被综合为FIFO时,由于默认深度为1,可能会在C/RTLCosimulation时出现DEADLOCK

-先创建一个没有任何directive的Solution执行C综合,尽可能地解决此时出现的warning或者错误,这也是UFDM所倡导的设计思想。

思考空间

如果要修改hls_stream对应的FIFO的深度,该采用哪个directive?

0 人点赞