Vivado HLS #pragma HLS STREAM

dataflow数据流

#pragma HLS dataflow //任务级流水化而不是顺序执行 默认用double-buffer来实现
一个比较经典的方式来展示templete参数,unroll、dataflow使用的例子,如下所示,它实现了N个testCore模块并行执行。

templete<int N>
void design(int value[N]){
    
    
#pragma HLS dataflow
    for(int i = 0; i < N; i++){
    
    
#pragma HLS unroll
        testCore(value[i]);
    }
}

STREAM

#pragma HLS stream variable=<variable> depth=<int> dim=<int>      //以高性能FIFO代替高资源占用的double-buffered RAM,必须有一个producer和一个consumer

depth=:只适用于数据流通道中的数组流。默认情况下,在RTL中实现的FIFO的深度与C代码中指定的数组大小相同。这个选项允许您修改FIFO的大小并指定不同的深度。
当数组在数据流区域中实现时,通常使用depth=选项来减小FIFO的大小。例如,在一个数据流区域中,当所有循环和函数都以II=1的速率处理数据时,就不需要一个大型FIFO,因为数据是在每个时钟周期中产生和消耗的。在这种情况下,可以使用depth=选项将FIFO大小减少到1,从而大大减少RTL设计的面积。
提示:config_dataflow -depth命令能够流化一个数据流区域中的所有数组。这里指定的depth=选项将覆盖指定变量的config_dataflow命令。

FIFO深度的含义[1]:
FIFO的宽度:也就是英文资料里常看到的THE WIDTH,它只的是FIFO一次读写操作的数据位,就像MCU有8位和16位,ARM 32位等等,FIFO的宽度在单片成品IC中是固定的,也有可选择的,如果用FPGA自己实现一个FIFO,其数据位,也就是宽度是可以自己定义的。
FIFO的深度:THE DEEPTH,它指的是FIFO可以存储多少个N位的数据(如果宽度为N)。如一个8位的FIFO,若深度为8,它可以存储8个8位的数据,深度为12 ,就可以存储12个8位的数据,FIFO的深度可大可小,个人认为FIFO深度的计算并无一个固定的公式。在FIFO实际工作中,其数据的满/空标志可以控制数据的继续写入或读出。在一个具体的应用中也不可能由一些参数算数精确的所需FIFO深度为多少,这在写速度大于读速度的理想状态下是可行的,但在实际中用到的FIFO深度往往要大于计算值。一般来说根据电路的具体情况,在兼顾系统性能和FIFO成本的情况下估算一个大概的宽度和深度就可以了。而对于写速度慢于读速度的应用,FIFO的深度要根据读出的数据结构和读出数据的由那些具体的要求来确定。

dim=:指定要流化的数组的维度。默认是维度1。指定为从0到N的整数,用于具有N维数的数组。
off:禁用流数据。只适用于数据流通道中的数组流
提示:config_dataflow -default_channel fifo命令全局暗示了对设计中所有数组上使用stream pragma。这里指定的off选项会覆盖指定变量的config_dataflow命令,并恢复使用基于RAM pingpong buffer通道的默认值。

HLS Stream应用案例

顶层函数top由两个底层函数read_data和handle_data构成,其中read_data主要功能是从输入stream上获取特定数据;handle_data的主要功能则是对获取的数据进行处理。这里主要是为了说明stream的使用方法.

#include <ap_int.h>
#include <hls_stream.h>
using namespace hls;
#define N 512
#define M 8
#define W 32
typedef ap_uint<W> data_t;
typedef stream<data_t> xstream;
void read_data(xstream &idx_in,xstream &idx_out, data_t key[M])
{
    
    
	data_t new_data;
	for (int i=0;i<M;i++)
	{
    
    
		idx_in>>key[i];
	}
	for(int i=0;i<N;i++)
	{
    
    
		idx_in>>new_data;
		idx_out<<new_data;
	}
}
void handle_data(xstream &idx_in,xstream &idx_out, data_t key[M])
{
    
    
	for(int i=0;i<N;i++)
	{
    
    
		data_t idx_in_data=idx_in.read();
		data_t result=idx_in_data*key[i%M];
		idx_out.write(result);
	}
}
void top(xstream &idx_in,xstream &idx_out)
{
    
    
//#pragma HLS dataflow
	//static xstream idx_fifo ("idx_fifo_stream");
	xstream idx_fifo ("idx_fifo_stream");
#pragma HLS STREAM variable=idx_fifo depth=512 dim=1
	data_t key[M];
//#pragma HLS ARRAY_PARTITION variable=key complete dim=1
	read_data( idx_in, idx_fifo,  key);
	handle_data( idx_fifo, idx_out,  key);

}
不设置任何directive,直接执行C综合,
不加:
```cpp
#pragma HLS STREAM variable=idx_fifo depth=512 dim=1

此时会显示如下错误信息。
在这里插入图片描述

该信息表明,在非dataflow区域使用默认的FIFO规模(这个FIFO是因为stream而生成的,默认深度为1),会导致Deadlock。根据提示我们修改这个FIFO的深度。之后,重新执行C综合和C/RTL Cosimulation,均可通过。

加上后能够正常综合

https://www.it610.com/article/1290917355366457344.htm
ref
https://blog.csdn.net/u010379248/article/details/102532100

猜你喜欢

转载自blog.csdn.net/qq_35608277/article/details/113064465
HLS
今日推荐