Step1: 硬件清单

项目选用的是Digilent Nexys Video开发板。坦白说,此板可能是市面上性价比最高的音视频处理FPGA口袋实验室了。作为一款专用于音视频处理教学以及视频和视觉应用原型开发的评估板,此板搭载了Xilinx Artix-7系列中资源最大的器件Aritx-7 XC7A200T FPGA。


先来看下此板所集成的支持视频接收、处理和生成/输出的下列I/O和外设接口:

●  HDMI输入

●  HDMI输出

●  显示输出端口

●  以太网

●  UART

●  USB

●  512MB DDRSDRAM

●  线路输入(Line In)/麦克输入/耳机输出/线路输出(Line Out)

●  FMC

Step2: 图像处理流水线架构概述

使用VHDL与RTL方法,要创建一个简单的图像处理流水线,我们需要实现如上图所示架构。


监控处理器(本例中采用Xilinx Artix-7 FPGA实现的MicroBlaze软核RISC处理器)用于监控与用户接口间的通信并根据应用的要求配置图像处理流水线。在本例这个简单的架构中,HDMI输入口接收的数据从原始的并行格式的视频数据、Hsync和VSync转换为AXI Streaming(AXIS)格式。我们想要将数据转换成AXIS格式是因为Vivado提供多个使用这种数据格式的图像处理IP。如果我们使用Vivado HLS来创建我们自己的图像处理模块,那么能够支持AXIS接口也很重要。


MicroBlaze处理器需要支持如下外围设备:

● AXI UART – 支持系统的通信和控制

● AXI Timer – 使MicroBlaze可以实时运行事件

● MicroBlaze调试模块 – 支持MicroBlaze的调试

● MicroBlaze本地存储 – 连接到DLMB和ILMB(数据&指令本地存储总线)


我们将使用存储接口生成器来创建与板上SDRAM对接的DDR接口。这个接口和SDRAM创建了一个公共的存储框架,可以访问图像处理管道以及使用AXI interconnect访问监控处理器。

Step3: 图像处理流水线IP概述

创建一个简单的图像处理流水线需要使用如下IP:

●  DVI2RGB – Digilent提供的HDMI输入IP

●  RGB2DVI – Digitlent提供的HDMI输出IP

●  Video In to AXI4-Stream – 将并行视频输入转换为AXI Streaming协议(Vivado IP)

●  AXI4-Stream to Video Out – 将AXI-Stream转换为并行视频输出(Vivado IP)

●  Video Timing Controller Input – 检测输入视频流参数(Vivado IP)

●  Video Timing Controller Output – 生成输出视频流时序参数(Vivado IP)

●  Video Direct Memory Access – 支持图像写入和从DDR SDRAM读出


视频处理链的核心是VDMA,我们借助它来将图像移动到DDR内存中。


上图1中展示了IP如何将流式数据转换为读和写管道中内存映射的数据。两个VDMA通道都提供了在流式数据和内存映射数据之间转换的能力。写通道支持流到内存映射的转换而读通道提供内存映射到流的转换。


当把所有这些集中到Vivado中创建初始的基本系统,我们得到了如上图2所显示的架构,这是Nexys Video HDMI示例提供的。

Step4: 图像处理流水线所需的软件配置

在Nexys Video Artix-7 FPGA开发卡上启动并运行MicroBlaze软核处理器系统后,我们需要使用一些软件来生成视频输出信号。在这个示例中,我们将使用MicroBlaze处理器生成测试模式。为了实现这个设计,我们将向Nexys Video板卡的DDR SDRAM中写入数据,然后VDMA读出这些数据并且通过HDMI输出。


软件部分我们首选要做的是定义视频帧,它将会被存储到内存并通过VDMA输出。我们将在内存中定义三个视频帧。每个视频帧的定义采用二维阵列:


u8 frameBuf[DISPLAY_NUM_FRAMES][DEMO_MAX_FRAME];


将参数DISPLAY_NUM_FRAME设置为3,DEMO_MAX_FRAME设置为1920 * 1080 * 3。这里需要考虑到最大帧分辨率,最后乘以3适用到每个像素(红,黄,蓝像素都采用8位来表示)。


为了能够访问这些帧,我们使用数组指针指向每个帧缓存空间。用这种方式定义会简化我们与视频帧之间的交互。


定义好视频帧后,下一步就是初始化和配置这个设计的流水线。具体如下:

● VDMA – 使用DMA将数据从板上的DDR SDRAM搬运到视频输出链路中。

● 动态时钟IP – 输出像素时钟频率以及这个频率的倍数用于HDMI输出。

● 视频时序控制器0 – 根据分辨率定义输出显示时序。

● 视频时序控制器 1 – 在输出接收端决定视频时序。在这个示例中,这个控制器从一个源获取输入视频帧。


为了确保VDMA功能的正常,我们需要定义步幅,即DDR内存中每行之间的间隔。对于本项目,步幅设置为3 * 1920,这是每行的最大长度。


在这一项目中,我们能设置不同的显示分辨率,从640x480 到 1920x1080(见图1)。 


无论我们选择什么样的分辨率,我们都能够使用测试模式在屏幕上借助软件功能向DDR SDRAM写入数据。当我们改变功能时,我们还需要重新配置VDMA、视频时序生成器 0和动态时钟模块。


下一步则是生成视频输出。在这个示例中主应用程序有很多功能可以生成、采集和显示视频。具体如下:

1、Bar测试模式 – 在屏幕上生成多个颜色条

2、混合测试模式 – 在屏幕上生成混合颜色测试条

3、流模式,从HDMI输入到HDMI输出

4、抓取一个输入帧将颜色反转

5、抓取一个输入帧并按比例扩展到当前的显示分辨率


按照下方的代码就可以轻松的实现设置红、蓝、绿像素的值。每个像素的颜色值都是无符号8位整数。


frame[iPixelAddr] = wRed;

frame[iPixelAddr + 1] = wBlue;

frame[iPixelAddr + 2] = wGreen;


当运行应用时,通过UART终端窗口我们可以看到输出的选项菜单,通过选择我们可以执行不同的功能来进行测试,参考图2。


设置程序输出颜色条,混合测试模式输出的效果如3图所示。


好了,到这里,相信大家现在已经知道如何向DDR内存中写入信息并将它显示到屏幕上啦。

评论