ZYNQ图像处理|静态图像通路|VDMA寄存器、DDR内存操作

作者:林菜鸟 ,来源:佛系入门ZYNQ图像处理

“写在前面”

最美的人间四月天,适合读书。

那么,《五月天》

适合唱歌?

适合烂笔头?!

好的记性,应该不如,听着美妙的Music,

然后佛系的总结与佛系的吹水。

接下来的咸鱼时间,不妨借助,

这些Topic进行分享:

Top1:

静态图像通路|VDMA寄存器、DDR内存操作

Top2:

静态图像通路|VDMA库函数、SD卡操作

Top3:

HLS如何复现、优化OpenCV图像处理

Top4:

AXI协议/VIVADO软硬件调试(ila逻辑仪)

Top5:

摄像头视频流的实时处理

……

本次Demo吹水Top1,大致内容如下:

“关于”Lena美女图像

本次Demo目的及实现功能

HDMI接口的佛系介绍

软核VDMA的佛系介绍

软核Video Timing Controller

软核AXI4-Stream to Video Out

软核Clocking Wizard

VIVADO搭建静态图像通路

XSDK编写Demo应用程序

Demo实验现象

“关于”Lena美女图像

在图像处理、计算机视觉领域,Lena数字图像被大多数的键盘侠广泛使用,Lena可以说是一张司空见惯的标准图。

国外某期刊的主编,曾经说明过以下原因:1.Lena图像混合了各种细节、纹理特征、平滑区域和阴影部分,能够很好的测试图像处理的各种算法;2.Lena是个迷人的美女,做图像处理的研究者或工程师,大部分都是男的,不奇怪他们被Lena美女所吸引。

可以想象,各位Coder每天的工作是多么的烦躁,能够顺便的看看Lena无疑是有效的放松。

或者说,996可以接受,但是,工作的心情一定要愉悦

更多的关于Lena图像背后的故事,或是完整版的Lena美女(国外某杂志的封面),各位老铁可以自行了解,相信大家会有别样的收获。

图像处理界的不完整版的Lena标准图如下:

本次Demo目的及实现功能

有一帧,分辨率是800*600大小的Lena静态图像,存储/缓冲在ARM的DDR内存上。

FPGA的VDMA需要访问这块内存,“搬运”ARM的Lena美女到FPGA,然后根据视频时序要求,送至FPGA的HDMI接口,完成图像信号的“差分转换”并显示出来。

HDMI接口的佛系介绍

支持视频、图像传输的接口协议,通常有HDMI、DVI和VGA,其中的高清晰度多媒体接口HDMI(High Definition Multimedia Interface)是现在比较流行的。

最新的HDMI已经支持4K的分辨率(比如,4k超高清的家庭电视)。不过,Coder或者FPGAer,平时最常用的,应该还是1920*1080、1280*1024,800*600等分辨率。

HDMI接口协议包括两个部分:编码端(板子)和解码端(电脑显示器),如下图所示,每个部分都有四个相互独立的通道(RGB三个数据通道和一个clock时钟通道),每个独立的通道,传输的都是TMDS差分信号。

由于HDMI传输的信号是数字化的(VGA是模拟信号),而且,HDMI接口通常是跟ZYNQ的FPGA相连的(高速),所以,在板子没有HDMI驱动芯片的情况下,可以在FPGA内部使用Verilog实现HDMI传输协议(VGA通常要使用外部的驱动芯片),或者调用第三方公司的软核IP,

比如Digilent公司的rgb2dvi,rgb2dvi直接封装好了HDMI接口协议,支持RGB888或者其他颜色空间的图像信号,到HDMI协议所要求的TMDS差分信号的转换,如下图所示:

软核VDMA的佛系介绍

XILINX公司的VDMA(Video DMA)是一个专门的在ZYNQ内部(FPGA、ARM之间)搬运视频、图像等“大数据”的软核IP,刚好封装了AXI的三种协议,VDMA框图如下:

从VDMA框图可以看出,其内部包括了控制寄存器、状态寄存器、数据搬运和行缓冲等模块,以及顶层的AXI4-Lite、AXI-Stream和AXI4等通信协议。

ARM可以通过顶层的AXI-Lite协议完成VDMA内部的控制寄存器、状态寄存器的配置和访问,通过配置寄存器可以指定,数据搬运模块具体如何工作,数据搬运的过程需要经过行缓冲模块进行缓存;

AXI-Stream流协议,完成VDMA与其他的外部IP(比如FPGA的摄像头、HLS IP等)的数据流通信,换言之,只有在FPGA这个PL端,才有“流”的说法;

AXI4协议负责VDMA读写DDR的操作(ARM),所以VDMA在FPGA和ARM之间搬运视频图像数据,实际上是AXI4这个子协议完成的,而AXI-Stream负责在PL端的VDMA与其他FPGA模块的数据流通信。

所以,也有前辈说过,ZYNQ视频图像处理系统,VDMA是必须的。

但菜鸟个人认为,如果不考虑数据通信的效率问题,这不是必须的,

因为可以在HLS IP添加一个M-AXIS(Master)接口,然后整个HLS IP直接的连到ZYNQ的HP口进行DDR的访问,只是自定义的HLS IP未必有VDMA高效(VDMA实际是二维的DMA)。

介绍完VDMA的框图,下面介绍VDMA内部的寄存器:

VDMA内部的偏移地址,映射列表如下图,分为MM2S读通道和S2MM写通道两组寄存器:

偏移地址00h、30h:MM2S、S2MM读写通道的控制寄存器(稍后详细介绍);

偏移地址04h、34h:MM2S、S2MM读写通道的状态寄存器,ARM应用程序通过访问这个寄存器,可以获取VDMA的工作状态,比如通道是否启动、通道是否响应每次传输的中断、帧延时和帧计数等中断;

偏移地址5Ch至98h、ACh至E8h:分别配置MM2S、S2MM读写通道的每一帧缓存的起始地址,需要根据VIVADO例化VDMA IP的时候,指定的缓存帧数进行软件上的配置(比如,VDMA常用的是1帧或3帧缓存);

偏移地址50h、A0h:分别配置MM2S、S2MM读写通道的垂直方向尺寸,即指定传输的图像实际高度(行数),这个寄存器一般在最后一步进行配置,以便启动整个通道的传输;

偏移地址54h、A4h:分别配置MM2S、S2MM读写通道的水平方向尺寸,但它不是指定传输的图像实际宽度(列数),它指定的是每一行需要传输多少个字节的数据,比如640*3,图像每行的宽度是640列,每个像素占用3个字节的内存;

偏移地址58h、A8h:分别配置MM2S、S2MM读写通道的跨度,即指定每两行的第一个像素之间在内存上间隔多少个数据。比如,当前分辨率下的图像,每一行实际有640*3个字节,待传输显示。但考虑程序的通用性,有可能使用宏定义指定了不同的显示分辨率下,都是1920*3固定大小的跨度;

下面“详细”介绍前面提到的控制寄存器(00h、30h):

考虑到MM2S、S2MM读写通道是独立的,互不影响,下面选择MM2S通道的控制寄存器进行介绍(S2MM通道是同样的道理):

如下图,是VDMA读通道的控制寄存器,该寄存器用于控制整个VDMA的运行方式,包括复位、时钟使能(锁相/动态锁相)、帧缓存的切换模式、VDMA的读/写通道的启动等等。

下面对低4位的作用进行介绍,低4位也是最常用的最重要的(其他比特位的作用,可以参阅pg020官方文档)。

低0位,控制VDMA读/写通道的运行和停止,其中,赋值1表示运行,赋值0表示停止;

低1位,控制帧缓存的切换模式,其中,赋值1表示循环的切换显示(比如内存上有3帧的缓存);赋值0表示,一直停留在XSDK的应用程序所指定的当前帧,进行“搬运”和HDMI显示;

低2位,控制读/写通道的复位,其中,赋值1表示高电平复位有效,所以在VDMA正常工作的情况下,低2位要赋值为低电平;

低3位,控制时钟使能是否有效,其中,赋值1表示使能/开启当前模式的时钟,比如锁相同步模式或者动态锁相同步模式。

具体的关于时钟同步模式的介绍,可以通过DocNav工具查阅官方文档pg020,page38-42的页码。更多的关于其他寄存器的作用介绍,也可以参阅pg020

软核Video Timing Controller

Video Timing Controller,XILINX提供的视频时序控制器,支持AXI-Lite接口协议,即支持ARM对内部寄存器的动态配置。一般是在HDMI显示输出的分辨率,需要动态改变的情况下才使用AXI-Lite接口。

比如,XSDK的应用程序每隔半分钟,改变HDMI显示输出的图像大小,这就要求视频时序随之改变,这时候就需要在VIVADO使能这个AXI-Lite控制接口了,如下图的ctrl端口:

如果在应用程序,不需要动态的改变图像显示的分辨率大小,这时候可以不勾选“Include AXI4-Lite Interface”,直接选择某个常见的视频模式,

如下图的800*600p,它会自动的配置好,符合HDMI协议的参数(行、场同步;行、场前消隐;行、场后消隐的像素时钟个数):

软核AXI4-Stream to Video Out

在前面的介绍,知道了,PL端调用rgb2dvi这个现成的IP,可以完成RGB888或其他颜色空间/数据格式的图像信号,到HDMI显示器的TMDS差分信号的输出。

前面也介绍了,VDMA通过AXI4协议,从ARM/PS的DDR搬运的帧图像数据,最终是以“流”的格式与PL端的其他模块进行通信的。

所以,这时候就需要一个“中介”,完成VDMA输出的AXI-Stream流格式的图像、视频到rgb2dvi所要求的RGB888图像格式的转换。

如下图所示,XILINX直接提供了现成的软核AXI4-Stream to Video Out,完成上述的AXIS到RGB的格式转换。

上图的aclk是AXI-Stream流协议的时钟输入,vid_io_out_clk是这个软核输出每帧RGB图像的时钟来源

下面详细的介绍,配置软核AXI4-Stream to Video Out的Clock Mode和Timing Mode这两个参数的作用:

软核的Clock Mode,可以理解为aclk与vid_io_out_clk两个时钟的来源,是否直接共用AXI-Stream流协议的时钟aclk。一般不选择Common共用,选择的是Independent模式。

因为完成HDMI差分转换的rgb2dvi软核,它的输入时钟就是像素时钟。Independent模式下,软核AXI4-Stream to Video Out的vid_io_out_clk时钟,可以直接的连接到,整个ZYNQ系统的像素时钟,以保证AXIS到RGB输出,再到HDMI显示的同步。

软核的Timing Mode,有Slave、Master模式的选择,一般是“根据”视频时序控制器Video Timing Controller的配置,进行主从模式的选择。

比如,Video Timing Controller配置了AXI-LITE接口,这意味着,可以在应用程序动态的改变视频时序(根据不同的显示分辨率),那么这时候,软核的Timing Mode选择Slave模式。

如果Video Timing Controller没有配置AXI-LITE接口,意味着,图像输出的是固定的分辨率,视频时序也就是固定的了,那么Timing Mode可以选择Master模式,这表示Video Timing Controller的运行,可以完全的脱离AXI4-Streamto Video Out。

软核Clocking Wizard

相信每一位亲爱的FPGAer,对这个IP并不陌生。它就是一个时钟管理模块,或是一个锁相环,可以输出倍频、分频、单端转差分的时钟,等等。

所以,不一定是图像处理,包括在信号处理和通信领域,clocking wizard应该是用的比较频繁的一个IP。

本次Demo显示的静态图像,分辨率大小是800*600,可以计算出所需要的像素时钟40MHz,可以由ZYNQ IP输出100Mhz的时钟到clockingwizard的输入端,经过内部的配置转换之后,得到像素时钟以及HDMI编码要用到的串行时钟(40*5=200MHz)的输出,配置如下图所示:


同时,40MHz的像素时钟也可以连接到前面介绍的Video Timing Controller、AXI4-Stream to Video Out和rgb2dvi等软核,以保证HDMI显示的“同步”。

当然了,这是在显示分辨率固定不变的情况下,配置的像素时钟和串行时钟输出,如果Video Timing Controller配置了AXI-lite接口,XSDK的应用程序也正好需要,改变HDMI输出的图像分辨率的时候,这就要求像素时钟随之改变了。

这时候,比较直接的笨方法,就是在VIVADO改变ZYNQ的块设计工程,重新的配置clocking wizard的时钟输出(频率)。

显然,这是一种低效的行为,比较科学的省时间的方法,应该是在最开始设计VIVADO工程的时候,调用支持动态配置的时钟IP(下次Demo再详细介绍)。

VIVADO搭建静态图像通路

在VIVADO工具,调用、例化上述的IP,最终的工程设计如下图:

XSDK编写Demo应用程序

导出硬件比特流之后,在XSDK编写应用的驱动程序,如下图:

Demo实验现象

ZYNQ板子供电之后,下载应用程序,测试结果如下图:

文章转载自: 佛系入门ZYNQ图像处理
*本文由作者授权转发,如需转载请联系作者本人

推荐阅读