本篇博客介绍vvas框架所支持调用的h/w(hls)内核。h/w内核指的是使用hls工具生成的在fpga部分执行的硬件功能模块。
hls kernel创建
我们以smartcam的预处理作为例子,相关的代码可以在参考链接中找到。xf_pp_pipeline的作用是将输入图像的格式从nv12转换为bgr,再进行减均值和归一化操作。xf_pp_pipeline的实现基于hls vision library。vitis视觉库是为在vitis开发环境中工作而设计的,它为在fpga设备上加速的计算机视觉功能提供了一个软件接口。vitis视觉库的功能大多与opencv的功能相似。更多的详细说明可以在参考链接中找到。
#include xf_pp_pipeline_config.hvoid 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。
kernel调用
使用vvas框架为xf_pp_pipeline.cpp编写自定义驱动是要实现四个函数,分别是xlnx_kernel_start、xlnx_kernel_done、xlnx_kernel_init、xlnx_kernel_deinit。
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手册。
气伺服焊钳的补偿值运用过程
如何对汽车电路基础元件进行检测
Traxon推出String (串灯) 和Dot XL (圆
你不知道的Wayland:XWindow的前生今世
ADI运算放大器ADA4177:性能最稳定,能满足系统设计人员的要求
VVAS调用HLS生成的硬件加速器的主要流程
调心滚子轴承内圈的压装方法 三类轴承的拆卸步骤
艾拉物联在展会中展示出一站式开发者平台和全屋智能两大业务线
全方位解读标签印刷发展大趋势
在阿里做自然语言理解工程师是一种什么样的体验
恩智浦S32K3系列汽车通用MCU帮助车厂实现软件的有效性检测
LED照明产品质量与价格分辨
AP2953在上网本中的应用
基于TCP/IP网络的机房监控系统方案
黄仁勋访问中国台湾 巩固人工智能处理器市场领导地位
盛美上海预计2023年营收增幅27%-48%,2024年全年营收有望达到50亿
川土微电子CA-IS398X数字输入接收器的应用案例
中科院:太赫兹技术及应用的发展已进入关键时期
3D打印机打印精度和打印速度,如何兼顾?
飞腾官方京东自营旗舰店正式上线试运营