位置: 首页 > 资讯 > > 正文

使用VVAS调用硬件加速器

2023-06-20 12:19:21 来源:面包芯语

作者:Shaoyi Chen,来源:AMD Xilinx开发者社区

本篇博客介绍VVAS框架所支持调用的H/W(HLS)内核。H/W内核指的是使用HLS工具生成的在FPGA部分执行的硬件功能模块。


(相关资料图)

#include "xf_pp_pipeline_config.h"void pp_pipeline_accel(ap_uint* img_inp_y,  // Y Input image pointer ap_uint* img_inp_uv, // UV Input image pointer                         ap_uint* img_out, // output image pointer                         float params[2 * XF_CHANNELS(IN_TYPE, NPC)],                         int in_img_width,                         int in_img_height,                         int in_img_linestride,                         int out_img_width,      // Final Output image width                         int out_img_height,     // Final Output image height                         int out_img_linestride) { // Final Output image line stride#pragma HLS INTERFACE m_axi     port=img_inp_y  offset=slave bundle=gmem1#pragma HLS INTERFACE m_axi     port=img_inp_uv  offset=slave bundle=gmem2#pragma HLS INTERFACE m_axi     port=img_out  offset=slave bundle=gmem3#pragma HLS INTERFACE m_axi     port=params  offset=slave bundle=gmem4#pragma HLS INTERFACE s_axilite port=in_img_width     #pragma HLS INTERFACE s_axilite port=in_img_height     #pragma HLS INTERFACE s_axilite port=in_img_linestride     #pragma HLS INTERFACE s_axilite port=out_img_width     #pragma HLS INTERFACE s_axilite port=out_img_height     #pragma HLS INTERFACE s_axilite port=out_img_linestride     #pragma HLS INTERFACE s_axilite port=return......    xf::cv::resize(rgb_mat, resize_out_mat);    xf::cv::preProcess(resize_out_mat, out_mat, params);......}

xf_pp_pipeline_accel.cpp作为硬件的一部分,需要将它和platform结合在一起。v++将HLS kernel打包为xo文件用于后续的硬件集成。

kv260_ispMipiRx_vcu_DP是smartcam应用使用的platform,xf_pp_pipeline.cpp打包成xo对象后,通过v++链接为完整的硬件工程并生成xclbin文件。完整的硬件框图如下图所示,红框部分为对应的HLS kernel。

xlnx_kernel_init()函数读取json文件中的mean_r、mean_g、mean_b、scale_r、scale_g、scale_b。

int32_t xlnx_kernel_init(IVASKernel *handle){......kernel_priv->mean_r = json_number_value(val);kernel_priv->mean_g = json_number_value(val);kernel_priv->mean_b = json_number_value(val);kernel_priv->scale_r = json_number_value(val);kernel_priv->scale_g = json_number_value(val);kernel_priv->scale_b = json_number_value(val);......}

xlnx_kernel_start()函数为HLS kernel配置参数。

int32_t xlnx_kernel_start(IVASKernel *handle, int start, IVASFrame *input[MAX_NUM_OBJECT], IVASFrame *output[MAX_NUM_OBJECT]){......    ivas_register_write(handle, &(input[0]->props.width), sizeof(uint32_t), 0x40);   /* In width */    ivas_register_write(handle, &(input[0]->props.height), sizeof(uint32_t), 0x48);  /* In height */    ivas_register_write(handle, &(input[0]->props.stride), sizeof(uint32_t), 0x50);  /* In stride */    ivas_register_write(handle, &(output[0]->props.width), sizeof(uint32_t), 0x58);  /* Out width */    ivas_register_write(handle, &(output[0]->props.height), sizeof(uint32_t), 0x60); /* Out height */    ivas_register_write(handle, &(output[0]->props.width), sizeof(uint32_t), 0x68); /* Out stride */    ivas_register_write(handle, &(input[0]->paddr[0]), sizeof(uint64_t), 0x10);      /* Y Input */    ivas_register_write(handle, &(input[0]->paddr[1]), sizeof(uint64_t), 0x1C);      /* UV Input */    ivas_register_write(handle, &(output[0]->paddr[0]), sizeof(uint64_t), 0x28);      /* Output */    ivas_register_write(handle, &(kernel_priv->params->paddr[0]), sizeof(uint64_t), 0x34);     /* Params */    ivas_register_write(handle, &start, sizeof(uint32_t), 0x0);                      /* start */......}

xlnx_kernel_deinit()函数用来释放不需要的句柄。

uint32_t xlnx_kernel_deinit(IVASKernel *handle){    ResizeKernelPriv *kernel_priv;    kernel_priv = (ResizeKernelPriv *)handle->kernel_priv;    ivas_free_buffer (handle, kernel_priv->params);    free(kernel_priv);    return 0;}

xlnx_kernel_done()函数进行超时检测。

int32_t xlnx_kernel_done(IVASKernel *handle){    uint32_t val = 0, count = 0;    do {        ivas_register_read(handle, &val, sizeof(uint32_t), 0x0); /* start */        count++;        if (count > 1000000) {            printf("ERROR: kernel done wait TIME OUT !!\\n");            return 0;        }    } while (!(0x4 & val));    return 1;}

通过这四个函数就完成了VVAS自定义插件的设计。在smartcam应用运行时,通过命令行gst-launch-1.0 -v filesrc XXXXXX ! queue ! vvas_xmultisrc kconfig="/opt/xilinx/kv260-smartcam/share/vvas/facedetect/preprocess.json" ! XXXXXX完成插件的调用。

其中preprocess.json的内容为:

{  "xclbin-location":"/lib/firmware/xilinx/kv260-smartcam/kv260-smartcam.xclbin",  "vvas-library-repo": "/opt/xilinx/kv260-smartcam/lib",  "element-mode": "transform",  "kernels": [    {      "kernel-name": "pp_pipeline_accel:{pp_pipeline_accel_1}",      "library-name": "libvvas_xpp.so",      "config": {        "debug_level" : 1,        "mean_r": 123,        "mean_g": 117,        "mean_b": 104,        "scale_r": 1,        "scale_g": 1,        "scale_b": 1      }    }  ]}

本文简要介绍了VVAS调用HLS生成的硬件加速器的主要流程,更多的细节可以参考VVAS手册。

参考链接:https://github.com/Xilinx/kria-vitis-platformshttps://github.com/Xilinx/kria-vitis-platforms/blob/xlnx_rel_v2022.1/kv2...https://xilinx.github.io/Vitis_Libraries/vision/2022.1/overview.htmlhttps://xilinx.github.io/VVAS/main/build/html/docs/release_notes.html

标签: