HDMI接口简述
HDMI接口是现在特别常用的音视频接口,另一个常用的视频流接口是VGA接口,他们主要的区别如下:
HDMI接口:是数字信号接口,可传输音频和视频,硬件接口较小
VGA接口:是模拟信号接口,只可传输视频流数据,硬件接口较大
现在的电脑一般都带有HDMI接口,其中HDMI接口也分为三种大小,但是他们三者之间的协议是完全相同的,所以只需要购买相应的连接线即可。而且HDMI与VGA之间也有相互转换的转接线,通过这种转接线也可实现两者协议的相互转换。通过本次实验我们也可以发现,HDMI接口就是在VGA接口的基础上发展而来的,至于HDMI接口为什么可以做到那么小,主要是数据与VGA不同,是串行传输的。
HDMI的实现方法有两种,一种是使用HDMI芯片,另一种因为HDMI协议本身就是数字协议,所以我们来使用IO模拟,本次实验使用的是第二种方法。
项目描述,本次实验是通过HDMI在显示屏上显示三个彩条,本次的实验也是在VGA协议的基础上改来的。
软件环境:vivado2019.1 软件
硬件环境:米联客MA7035(100T)开发板
HDMI协议简述
一个 HDMI 连接包括三个 TMDS 数据通道,一个 TMDS 时钟通道。 TMDS 时钟通道以某种定常的速率运行,该速率和视频的像素率成比例。在每个 TMDS 时钟通道周期中,三个 TMDS 数据通道每个都发送 10 比特数据。这个 10 位的字被编码,采用某种不同的编码技术。输入到信源端的输入流,包含视频像素,数据包,和控制数据。数据包包括音频数据和辅助以及相关的纠错码。
对上面进一步解释得,HDMI一共存在三条数据通道和一条时钟通道,上面传来的数据通过编码与串行化传输到外面去。其中channel0是连接到blue数据,它的两个控制端是连接场同步信号和行同步信号,其余两个通道分别连接green与red信号,通道的控制端连接音频信号,一般我们设置成0即可。
HDMI接口设计
这里给出HDMI输出接口得设计框图:
从上面得图形中我们也可以发现,HDMI设计主要包括三个模块,VGA模块,encode模块,par2ser模块,关于par2ser模块我们上一篇文章已经进行了讲解,encode模块也就是著名得8bit转10bit编码(xilinx官网下载即可)。其中上面最后一个par2ser模块是时钟模块,输入得数据10‘b11111_00000经过串行转换之后正好作为HDMI得随路时钟,这里这样做而不是直接输出一个时钟得原因是为了让时钟和数据对齐。
HDMI代码
经过上面得框图与上一篇论文关于串行化的设计,相信大家对HDMI协议已经有了初步的了解,接下来我们将给出该项目的代码,因为在家中没有硬件实验条件,所以代码没有下板验证,代码中有可能存在一些小错误无法发现。
hdmi_top模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : hdmi_top.v
// Create Time : 2020-02-24 09:18:16
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module hdmi_top(
//System Interfaces
input sclk ,
input rst_n ,
//HDMI Interfaces
output wire [ 2:0] hdmi_data_p ,
output wire [ 2:0] hdmi_data_n ,
output wire hdmi_clk_p ,
output wire hdmi_clk_n ,
output wire hdmi_oen
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
wire clk_65mhz ;
wire clk_325mhz ;
wire locked ;
wire hsync ;
wire vsync ;
wire [ 7:0] vga_data_r ;
wire [ 7:0] vga_data_g ;
wire [ 7:0] vga_data_b ;
wire vga_de ;
wire [ 9:0] vga_data_r_10bit;
wire [ 9:0] vga_data_g_10bit;
wire [ 9:0] vga_data_b_10bit;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign hdmi_oen = 1'b1;
clk_wiz_0 clk_wiz_0_inst(
// Clock out ports
.clk_out1 (clk_65mhz ), // output clk_out1
.clk_out2 (clk_325mhz ), // output clk_out2
// Status and control signals
.resetn (rst_n ), // input resetn
.locked (locked ), // output locked
// Clock in ports
.clk_in1 (sclk )
);
vga_drive vga_drive_inst(
.vga_clk (clk_65mhz ),
.rst_n (~locked ),
.hsync (hsync ),
.vsync (vsync ),
.vga_data_r (vga_data_r ),
.vga_data_g (vga_data_g ),
.vga_data_b (vga_data_b ),
.vga_de (vga_de )
);
encode encode_blue(
.clkin (clk_65mhz ), // pixel clock input
.rstin (~locked ), // async. reset input (active high)
.din (vga_data_b ), // data inputs: expect registered
.c0 (hsync ), // c0 input
.c1 (vsync ), // c1 input
.de (vga_de ), // de input
.dout (vga_data_b_10bit ) // data outputs
);
encode encode_green(
.clkin (clk_65mhz ), // pixel clock input
.rstin (~locked ), // async. reset input (active high)
.din (vga_data_g ), // data inputs: expect registered
.c0 (1'b0 ), // c0 input
.c1 (1'b0 ), // c1 input
.de (vga_de ), // de input
.dout (vga_data_g_10bit ) // data outputs
);
encode encode_red(
.clkin (clk_65mhz ), // pixel clock input
.rstin (~locked ), // async. reset input (active high)
.din (vga_data_r ), // data inputs: expect registered
.c0 (1'b0 ), // c0 input