本例利用之前介绍的基础函数进行功能级实现。
void bayer_write_accel(hls::stream<T_AXIU(BAYER_BPP, BAYER_NPPC)>& src, T_UINT(BAYER_BPP, DDR_NPPC)* dst)
{
#pragma HLS INTERFACE axis register both port=src
#pragma HLS INTERFACE m_axi offset=direct port=dst depth=1940800
hls::stream<T_UINT(BAYER_BPP, BAYER_NPPC)> inter0("inter0");
hls::stream<T_UINT(BAYER_BPP, DDR_NPPC)> inter1("inter1");
#pragma HLS STREAM variable=inter0 depth=1024
#pragma HLS STREAM variable=inter1 depth=1024
#pragma HLS DATAFLOW
axis2stream<BAYER_BPP, BAYER_HEIGHT, BAYER_WIDTH, BAYER_NPPC>(src, inter0, BAYER_WIDTH, BAYER_HEIGHT);
stream_nppc_change<BAYER_BPP, BAYER_HEIGHT, BAYER_WIDTH, BAYER_NPPC, DDR_NPPC, MID_NPPC>(inter0, inter1, BAYER_WIDTH, BAYER_HEIGHT);
stream2axim<BAYER_BPP, BAYER_HEIGHT, BAYER_WIDTH, DDR_NPPC, DDR_BURST_WORD>(inter1, dst, BAYER_WIDTH, BAYER_HEIGHT);
}
输入源对象是一个AXIS的stream,输出目的对象是一个AXIMM。
首先,用axis2stream的具象函数,抽取出data,并对齐。
然后,用stream_nppc_chage的具象函数,调整位宽。
然后,用stream2axim的具象函数,将stream中的data,输出到给定的AXIMM的内存块中。
两个参数src和dst,被添加了interface约束。
其中,src被实现为axis,
dst则被实现为m_axi。
#pragma HLS INTERFACE axis register both port=src
#pragma HLS INTERFACE m_axi offset=direct port=dst depth=1940800
定义了两个局部对象,stream,
它们被添加了stream约束。HLS将它们理解为FIFO。
#pragma HLS STREAM variable=inter0 depth=1024
#pragma HLS STREAM variable=inter1 depth=1024
函数整体处理的调用过程,被添加了dataflow约束。
#pragma HLS DATAFLOW
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
然后,来看看如何对它进行CSIM。
#include "hls_opencv.h"
#include "hls_video.h"
#include "bayer_write_accl.h"
#include "bayer_write_tb.h"
using namespace cv;
需要使用到opencv库,所以包含如上的头文件,以及namespace。
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("usage: %s bayer.png\n", argv[0]);
return -1;
}
cv::Mat in_img;
in_img = cv::imread(argv[1], 0);
if (in_img.data == NULL)
{
fprintf(stderr,"Cannot open image at %s\n", argv[1]);
return 0;
}
int width = in_img.size().width;
int height = in_img.size().height;
if ((width != BAYER_WIDTH) || (height != BAYER_HEIGHT))
{
printf("image size is wrong, real:%dx%d, needed:%dx%d \n", width, height, BAYER_WIDTH, BAYER_HEIGHT);
return 0;
}
cv::Mat out_img;
out_img.create(height, width, CV_8U);
unsigned char index = 0;
hls::stream<T_AXIU(BAYER_BPP, BAYER_NPPC)> src;
T_UINT(BAYER_BPP, DDR_NPPC)* dst = (T_UINT(BAYER_BPP, DDR_NPPC)*)(out_img.data);
cvMat2axis<BAYER_BPP, BAYER_NPPC>(in_img, src);
bayer_write_accel(src, dst);
cv::imwrite("hls.bmp", out_img);
return 0;
}
主体框架何基本框架一样,
这里,使用了自定义的基础函数cvMat2axis。
将cvMat对象的数据抽取出来,并转换成axis数据流对象,向DUT传递。