本文转载自:FpgaHome微信公众号
1. 前言
1.1 HDMI介绍
HDMI是(High Definition Multimedia Interface)的缩写,意思是高清晰度多媒体接口,是一种数字化视频/音频接口技术,适合影像传输的专用型数字化接口,可同时传送音频和影像信号,最高数据传输速度为48Gbps(2.1版)。
本实验使用FPGA通过HDMI接口输出彩条、色带、方块等图像。实验使用的硬件平台为ZedBoard,ZedBoard开发板使用了ADV7511 HDMI编码芯片,硬件框图如下。
1.2 TMDS介绍
HDMI采用和DVI相同的传输原理——TMDS(Transition MinimizedDifferential signal),最小化传输差分信号。
TMDS传输系统分为分为两个部分:发送端和接收端。 TMDS发送端收到HDMI 接口传来的表示RGB信号的24位并行数据(TMDS对每个像素的RGB三原色分别按8bit编码,即R信号有8位,G信号有8位,B信号有8位),然后对这些数据进行编码和并/串转换,再将表示3个RGB信号的数据分别分配到独立的传输通道发送出去。接收端接收来自发送端的串行信号,对其进行解码和串/并转换,然后发送到显示器的控制端。与此同时也接收时钟信号,以实现同步。
HDMI TMDS传输的数据类型有三种(加上Hsync与Vsync就算4种):
(1) Preamble(控制信息),主要用于控制接下来传输的数据是Data Island或者Video Data
(2) Data Island(数据包),各种类型的包信息,包括音频数据包,图像信息包等
(3) Video Data (视频信息),视频像素数据,HDMI可以传输RGB与YUV两种格式的像素数据
(4) 还有Hsync与Vsync
如果是8bit的数据进入TMDS编码器,得到抗干扰性强的10bitTMDS信号,然后再进行串行化输出;在接收端收到串行的HDMI信号后,进行信号复原,得到10bit的TMDS信号,最后用TMDS解码器解码得到原来的8bit数据。
HDMI的数据传输有TMDS0,TMDS1,TMDS2三个通道,每个通道的传输流程都是一样的:
(1)如果传输的是Video Data,并且格式为RGB,那么会占用三个通道的所有24bit输入,Channel0[7:0]用于传输B,Channel1[7:0]用于传输G,Channel2[7:0]用于传输R。
(2)如果传输的是Data Island,则占用三个通道共10bit输入,Channel0[3:2]用于传输Data Island Header(包头),Channel1[0:3]与Channel2[0:3]用于传输Data Island Content(包内数据)。
(3)如果传输的是Preamble,则占用1,2两个通道共4bit输入,Channel1[1:0]与Channel2[1:0]分别为CTL0,CTL1,CTL2,CTL3,用于判断接下来输入的是Video Data或者Data Island。
1.3 HDMI传输周期
HDMI的TMDS数据传输可以分为三个传输周期:
(1) Control Period期间会传输Hsync,Vsync,并且在该时期的最后阶段会传输Preamble
(2) Data Island Period期间会传输Data Island(数据包),也会有Hsync与Vsync
(3) Video Data Period期间会传输Video Data(视频像素数据)
某帧的总体周期如下:
三个传输周期示意图如下:
(1) 左边是Control Period,传输有Hsync,Vsync与Preamble
(2) 中间是Data Island Period,传输有Hsync,Vsync,以及两个Packet Header与Packet(每32个clock 一个packet);另外Data Island的两端会用Guard Band保护并隔开Data Island的数据,因为这个阶段传输的数据大多是非常重要的,比如其中就有图像分辨率,决定后面的Video Data数据的显示方式
(3) 右边是Video Data Island,传输视频像素数据,在该时期的开头也有Guard Band
2. Vivado工程的编写
(1)本实验使用的Vivado工程如下:
其中“design_1_wrapper.v”为顶层例化代码、“hdmi_data_gen.v”负责产生用于HDMI输出的图像(图像包括纯色块、渐变条、彩色带等)、“design_1.bd”模块为block design模块,负责将RGB信号转换为TMDS信号以及提供ADV7511 HDMI芯片的底层驱动。
(2)“design_1.bd”模块的设计如下:
“clk_wiz_0”为时钟产生模块,输出时钟给HDMI模块使用。
“hdmi_display_0”为RGB信号转换为TMDS信号模块,是一个自定义IP核。
“processing_system7_0”为ARM核。
(3)“hdmi_data_gen.v”文件中定义了1280*720P的视频时序参数,
(4)Vivado工程建立方式可以参考文章《ZYNQ 串口打印输出——FPGA Vitis篇》。
3. Vitis工程的编写
(1)点击 Vivado 菜单“Tools-> Launch Vitis IDE”,启动 Vitis。
(2)新建 Vitis平台工程。Vitis工程的建立可以参考以前的文章《ZYNQ串口打印输出——FPGA Vitis篇》。
(5)最后建立的Vitis工程如下,“EMIO_init.x”为EMIO设备驱动、“I2C_ctrl.x”为I2C总线驱动、“helloworld.c”为“main”函数所在文件。
(6)Vitis工程的实现流程很简单,主要是初始化EMIO接口、通过I2C总线读取ADV7511芯片ID号、配置ADV7511的寄存器、程序结束。
(7)编译工程,将工程下载到硬件板卡上(编译和下载方式见《ZYNQ 串口打印输出——FPGA Vitis篇》)。
实验结果为:通过按图中的按钮,可以切换HDMI输出的图像。
(3)新建 Vitis应用工程。该工程主要用于通过I2C总线配置ADV7511寄存器来实现该HDMI芯片的驱动。
(4)配置ADV7511寄存器需要参考官方手册“ADV7511_Programming_Guide”。可以着重先看手册中“SECTION3 – QUICK START GUIDE”。根据该“快速开始”步骤来配置ADV7511的寄存器。
以下为HDMI显示结果:
4. 工程源码下载
该工程对应的源码以及“ADV7511_Programming_Guide.pdf”文档,可以在公众号输入ZYNQ_HDMI来获取工程和文档的下载链接。