HLS图像处理系列——在ZEDBoard搭建DDR图像处理通路

ZYNQ芯片内包含一个丰富特性的基于双核ARM Cortex-A9的处理子系统(Processing System,PS)和Xilinx 28nm可编程逻辑(Programmable Logic,PL)。PS除了核心外还包括片上存储器、外部存储器接口以及大量外设连接接口。

利用ARM,我们可以做嵌入式操作系统相关的任务,如图形界面、用户输入、网络、DDR3控制等,由于ARM本身具有丰富的外设接口,而且支持多级流水线,处理这些事务游刃有余,但对于计算量较大的应用却捉襟见肘,因为ARM本身还是典型的串行处理器,不适合做大数据、实时性较高的处理任务。FPGA恰好弥补了这一点,利用可编程逻辑可以实现并行处理,只要逻辑资源够用,我们可以采用以空间换时间的策略,使多个计算单元同时进行,可大大缩短处理时间。

用ZYNQ进行图像处理具有架构上的优势,因此对于用ZYNQ做视频相关的开发人员,一套ZYNQ上的图像通路是必须的。本博文介绍的是一种摄像头+HLS图像处理+DDR存储+VGA显示的图像通路。该通路是本人和另外一位同事合作实现,本人负责摄像头的FPGA驱动、HLS图像处理IP的实现以及系统的后期优化。由于涉及公司项目,因此不能提供工程文件,只提供框架和思路。

系统框架如下:


重点模块介绍:

Camera:采用ov7725摄像头,帧率60fps,分辨率640*480。关于摄像头时序的详解,请参考本人博文《教程——在ZEDBoard实现图像通路(Block Ram版本)》

封装后的摄像头IP如下图:


VDMA:在本设计中,VDMA的地位和通常设计中的DMA相似。但是,和DMA不同的是,VDMA专门为视频流数据提供的高度存储访问模块。其通过AXI-Stream协议接收视频数据,而控制信号(比如帧缓冲的大小,DMA功能的开启和关闭,以及一些其他的设置)则通过AXI-Lite从其他接口访问。


VDMA拥有两条DMA通路,S2MM通路将输入的AXI4-Stream数据流映射到指定的帧缓冲,而MM2S则相反,将帧缓冲输出为AXI4-Stream类型的数据流。

VDMA的配置界面如图:


其中可以看到一些对于数据帧的配置信息,以及FrameBuffers数量的设置。FrameBuffers数量至少为3个,因为如果少于3个,那么会出现写入DDR与读取DDR的冲突,导致图像出现断层现象。在本设计中,FrameBuffers设置为3个。

Video In to AXI4-Stream 与 AXI4-Stream to Video Out:由于摄像头传入的信号使用的协议并非AXI4-Stream,而VDMA却需要接收AXI4-Stream类型的数据,所以需要有专门的IP核来进行两者之间的转换。

这两个IP核是:

Video In to AXI4-Stream,该IP将视频数据转化为AXI4-Stream类型。本工程中,视频数据来自于camera模块,只需要camera提供四路信号:行同步、场同步、24bit的像素、数据有效信号。

AXI4-Stream to Video Out,该IP将AXI4-Stream类型数据转化为视频数据。视频数据即为VGA信号,包含行同步、场同步、数据有效信号以及像素。该模块有一个timing的输入,在本系统中,来自于video timing control IP。video timing control模块给AXI4-Stream to Video Out IP提供一个640*480p的VGA时序信号。

下图为Video In to AXI4-Stream IP与AXI4-Stream to Video Out IP:



这两个IP核在本设计中处于桥梁地位,用于连接外部IO和VDMA。在这两个模块内部的视频数据都是AXI4-Stream类型,省去了地址,因此速度更快、更容易处理。一般而言,HLS硬件图像处理模块都会放在这两个IP核之间。

HLS图像处理模块:本设计中,构建了一个简单的Sobel图像处理模块,由HLS工具生成打包成IP。关于HLS工具不多介绍,可以参考本人博客《HLS图像处理系列——前言》来初步了解HLS。HLS生成的IP输入输出视频流都符合AXI4-Stream协议。

然后,附上vivado的工程截图:


在SDK工程,主要是进行HLS IP的初始化与VDMA的初始化。只有初始化之后,整个图像通路才能正确运行。HLS初始化源码短短几行,但也是折磨了我好久,因为需要关闭中断,好长时间内都没有发现这个问题。初始化重点源码如下:

/************config hls ip********/
void ConfigureHlsIP(XImgprocess_top *ImgProcess)
{
	ImgProcess->Control_bus_BaseAddress = XPAR_IMGPROCESS_TOP_0_S_AXI_CONTROL_BUS_BASEADDR;
	ImgProcess->IsReady = XIL_COMPONENT_IS_READY;

	XImgprocess_top_EnableAutoRestart(ImgProcess);
	XImgprocess_top_SetRows(ImgProcess, 480);
	XImgprocess_top_SetCols(ImgProcess,640);

	XImgprocess_top_InterruptDisable(ImgProcess, 0xFFFFFFFF);
	XImgprocess_top_InterruptGlobalDisable(ImgProcess);
	XImgprocess_top_Start(ImgProcess);
}

int main()
{
    init_platform();
	usleep(100000);
    print("Hello World\n\r");
    ConfigureHlsIP(&ImgProcess);
	// MM2S
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x00, 0x008B);		// enable run, circular_park, GenlockEn, GenlockSrc
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C, 0x01000000);	// Start address of the 1st frame(3 frames in all)
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x60, 0x02000000);	// Start address of the 2nd frame(3 frames in all)
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x64, 0x03000000);	// Start address of the 3rd frame(3 frames in all)
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x58, 0x0780);		// Stride number
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x54, 0x0780);		// number of bytes per line(640 x 3)
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x50, 0x01E0);		// number of lines per frame(480)

	//S2MM
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x108B);		// enable run, circular_park
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, 0x01000000);	// Start address of the 1st frame(3 frames in all)
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xB0, 0x02000000);	// Start address of the 2nd frame(3 frames in all)
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xB4, 0x03000000);	// Start address of the 3rd frame(3 frames in all)
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, 0x0780);		// Stride number
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 0x0780);		// number of bytes per line(640 x 3)
	Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 0x01E0);		// number of lines per frame(480)

    return 0;
}


  • 13
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
Vivado HLS 是 Xilinx 公司推出的一款高级综合工具,可以将 C/C++ 等高级语言代码转换为硬件描述语言 VHDL/Verilog,从而实现硬件加速。在图像处理领域,使用 Vivado HLS 可以将图像处理算法实现为硬件电路,提高算法运行速度和功耗效率。 以下是 Vivado HLS图像处理中的基本应用: 1. 图像滤波:图像滤波是图像处理中的基本操作,可以去除噪声、增强图像细节等。常用的滤波算法有均值滤波、中值滤波、高斯滤波等。使用 Vivado HLS 可以将这些算法实现为硬件电路,加速图像滤波操作。 2. 图像变换:图像变换是将图像从一个空间域转换到另一个空间域的操作,如傅里叶变换、小波变换等。这些变换算法需要大量的计算,使用 Vivado HLS 可以将其实现为硬件电路,提高计算速度。 3. 图像分割:图像分割是将图像分成多个区域的操作,常用的算法有阈值分割、边缘检测等。使用 Vivado HLS 可以将这些算法实现为硬件电路,提高图像分割速度。 4. 特征提取:图像特征提取是从图像中提取出特定的特征,如角点、边缘等。常用的特征提取算法有Harris角点检测、SIFT算法等。使用 Vivado HLS 可以将这些算法实现为硬件电路,提高特征提取速度。 总之,Vivado HLS图像处理领域中有着广泛的应用,可以加速图像处理算法的运行,提高系统性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值