Program Listing for File xf_infra.hpp
↰ Return to documentation for file (/tmp/ws/src/vitis_common/include/common/xf_infra.hpp
)
/*
* Copyright 2019 Xilinx, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _XF_INFRA_H_
#define _XF_INFRA_H_
#ifndef __cplusplus
#error C++ is needed to use this file!
#endif
#include <stdio.h>
#include <assert.h>
#include "xf_types.hpp"
#include "hls_stream.h"
#include "ap_axi_sdata.h"
#include "xf_axi_io.hpp"
namespace xf {
namespace cv {
/* reading data from scalar and write into img*/
template <int SRC_T, int ROWS, int COLS, int NPC>
void write(xf::cv::Mat<SRC_T, ROWS, COLS, NPC>& img,
xf::cv::Scalar<XF_CHANNELS(SRC_T, NPC), XF_TNAME(SRC_T, NPC)> s,
int ind) {
// clang-format off
#pragma HLS inline
// clang-format on
img.write(ind, s.val[0]);
}
/* reading data from scalar and write into img*/
template <int SRC_T, int ROWS, int COLS, int NPC>
void fetchingmatdata(xf::cv::Mat<SRC_T, ROWS, COLS, NPC>& img,
xf::cv::Scalar<XF_CHANNELS(SRC_T, NPC), XF_TNAME(SRC_T, NPC)> s,
int val) {
// clang-format off
#pragma HLS inline
// clang-format on
write(img, s, val);
}
/* reading data from img and writing onto scalar variable*/
template <int SRC_T, int ROWS, int COLS, int NPC>
xf::cv::Scalar<XF_CHANNELS(SRC_T, NPC), XF_TNAME(SRC_T, NPC)> read(xf::cv::Mat<SRC_T, ROWS, COLS, NPC>& img,
int index) {
// clang-format off
#pragma HLS inline
// clang-format on
xf::cv::Scalar<XF_CHANNELS(SRC_T, NPC), XF_TNAME(SRC_T, NPC)> scl;
scl.val[0] = img.read(index);
return scl;
}
/* reading data from img and writing onto scalar variable*/
template <int SRC_T, int ROWS, int COLS, int NPC>
void fillingdata(xf::cv::Mat<SRC_T, ROWS, COLS, NPC>& img,
xf::cv::Scalar<XF_CHANNELS(SRC_T, NPC), XF_TNAME(SRC_T, NPC)>& s,
int index) {
// clang-format off
#pragma HLS inline
// clang-format on
s = read(img, index);
}
#define HLS_CN_MAX 512
#define HLS_CN_SHIFT 11
#define HLS_DEPTH_MAX (1 << HLS_CN_SHIFT)
#define HLS_MAT_CN_MASK ((HLS_CN_MAX - 1) << HLS_CN_SHIFT)
#define HLS_MAT_CN(flags) ((((flags)&HLS_MAT_CN_MASK) >> HLS_CN_SHIFT) + 1)
#define HLS_MAT_TYPE_MASK (HLS_DEPTH_MAX * HLS_CN_MAX - 1)
#define HLS_MAT_TYPE(flags) ((flags)&HLS_MAT_TYPE_MASK)
#define ERROR_IO_EOL_EARLY (1 << 0)
#define ERROR_IO_EOL_LATE (1 << 1)
#define ERROR_IO_SOF_EARLY (1 << 0)
#define ERROR_IO_SOF_LATE (1 << 1)
/*
Unpack a AXI video stream into a xf::cv::Mat<> object
*input: AXI_video_strm
*output: img
*/
template <int W, int TYPE, int ROWS, int COLS, int NPPC>
int AXIvideo2xfMat(hls::stream<ap_axiu<W, 1, 1, 1> >& AXI_video_strm, xf::cv::Mat<TYPE, ROWS, COLS, NPPC>& img) {
ap_axiu<W, 1, 1, 1> axi;
int res = 0;
const int m_pix_width = XF_PIXELWIDTH(TYPE, NPPC) * XF_NPIXPERCYCLE(NPPC);
int rows = img.rows;
int cols = img.cols >> XF_BITSHIFT(NPPC);
int idx = 0;
assert(img.rows <= ROWS);
assert(img.cols <= COLS);
bool start = false;
bool last = false;
loop_start_hunt:
while (!start) {
// clang-format off
#pragma HLS pipeline II=1
#pragma HLS loop_tripcount avg=1 max=1
// clang-format on
AXI_video_strm >> axi;
start = axi.user.to_bool();
}
loop_row_axi2mat:
for (int i = 0; i < rows; i++) {
last = false;
loop_col_zxi2mat:
for (int j = 0; j < cols; j++) {
// clang-format off
#pragma HLS loop_flatten off
#pragma HLS pipeline II=1
// clang-format on
if (start || last) {
start = false;
} else {
AXI_video_strm >> axi;
bool user = axi.user.to_int();
if (user) {
res |= ERROR_IO_SOF_EARLY;
}
}
if (last && (j != img.cols - 1)) { // checking end of each row
res |= ERROR_IO_EOL_EARLY;
}
last = axi.last.to_bool();
img.write(idx++, axi.data(m_pix_width - 1, 0));
}
loop_last_hunt:
while (!last) {
// clang-format off
#pragma HLS pipeline II=1
#pragma HLS loop_tripcount avg=1 max=1
// clang-format on
AXI_video_strm >> axi;
last = axi.last.to_bool();
res |= ERROR_IO_EOL_LATE;
}
}
return res;
}
// Pack the data of a xf::cv::Mat<> object into an AXI Video stream
/*
* input: img
* output: AXI_video_strm
*/
template <int W, int TYPE, int ROWS, int COLS, int NPPC>
int xfMat2AXIvideo(xf::cv::Mat<TYPE, ROWS, COLS, NPPC>& img, hls::stream<ap_axiu<W, 1, 1, 1> >& AXI_video_strm) {
ap_axiu<W, 1, 1, 1> axi;
int res = 0;
int rows = img.rows;
int cols = img.cols >> XF_BITSHIFT(NPPC);
int idx = 0;
assert(img.rows <= ROWS);
assert(img.cols <= COLS);
const int m_pix_width = XF_PIXELWIDTH(TYPE, NPPC) * XF_NPIXPERCYCLE(NPPC);
bool sof = true; // Indicates start of frame
loop_row_mat2axi:
for (int i = 0; i < rows; i++) {
loop_col_mat2axi:
for (int j = 0; j < cols; j++) {
// clang-format off
#pragma HLS loop_flatten off
#pragma HLS pipeline II = 1
// clang-format on
if (sof) {
axi.user = 1;
} else {
axi.user = 0;
}
if (j == cols - 1) {
axi.last = 1;
} else {
axi.last = 0;
}
axi.data = 0;
axi.data(m_pix_width - 1, 0) = img.read(idx++);
axi.keep = -1;
AXI_video_strm << axi;
sof = false;
}
}
return res;
}
} // namespace cv
} // namespace xf
#endif