本帖最后由 UT发布 于 2025-4-19 09:54 编辑
软件版本: TD_ 5.6.4 _Release_ 97693
操作系统: WIN11 64bit
硬件平台:适用安路 (Anlogic)FPGA
1概述 本实验通过FPGA内部资源实现 H DMI协议,使用 H DMI直接驱动 H DMI接口显示器,这是成本非常低廉的一种方案,可以实现 H DMI输出 1 080P@60f ps的视频图像。 本实验需要用到前面课程中的 V TC模块产生视频时序,以及 T PG模块产生测试图形,只使用 HDMI 接口来显示图像,没有传输音频 。关于 V TC视频时序参数的设置,读者可以阅读前面 V TC相关的课程内容。
在完成本实验前,请确保已经完成前面的实验,包括已经掌握以下能力:
1.1 HDMI 简介 HDMI ,全称为( High Definition Multimedia Interface )高清多媒体接口, 能够同时无压缩的传输视频和音频信号,无需在信号传送前进行数 / 模或者模 / 数转换,因此有较高质量的影音信号。 HDMI 兼容 DVI ,通过转换接口可以让以其中一种接口标准发送的视频数据直接接入另一种接口标准的 LCD 显示器上显示。
HDMI 接口种类 :
HDMI 版本 :
1.1.1 HDMI _TypeA 接口引脚图 HDMI 有 A,B,C,D,E 五种引脚类型,目前市面中比较常见的 接口是 Type A :
1-9:TMDS数据传输实际上用到的引脚,分为 0,1,2 三组差分线 ,分别传输 R 、 G 、 B 三种信号,为了加强抗干扰能力,每对差分线之间还加入了一根屏蔽线,比如数据 2+ 与数据 2- 之间加入数据 2 屏蔽线, 1 、 2 、 3 信号线组成 1 个数据传输通道
13:CEC( consumer electronic control ) HDMI 的扩展功能,一种消费电子兼容的传输协议 ,可以控制视听设备 。
15-16:I2C引脚,用于 DDC ( Display Data Channel )传输 ,进行 EDID (相当于一个信息表,会存放显示器的制造商、型号、分辨率等信号)的交互,显示设备和主机可以相互读取。
19:热拔插引脚 ,用于监测 HDMI设备有没有存在 。
1.1.2 传输协议 HDMI传输 的编码格式中要包括视频数据、控制数据和数据包(数据包中包括音频数据和附加信息数据,例如纠错码等)。 HDMI传输由 4 组 TMDS通道组成, TMDS channel 0传输 B 信号, H 信号和 V 信号也 在该通道 ,TMDS channel 1传输 G 信号 , T MDS channel 2传输 R 信号, R 和 G 通道的多余位置用来传输音频信号 。TMDS channel clock传输视频信号的 pixel频率, 即像素时钟。传输的数据经过 TMDS 进行编码及并串转换,将编码的数据通过高速串行接口传送,接收端对编码后的数据进行解码,还原成原始的输入信号,最终将数据输入到显示器接口上。
TMDS 原理:
HDMI 采用 TMDS (Time Minimized Differential Signal) 最小化传输差分信号传输技术,是美国 Silicon Image 公司开发的一项高速数据传输技术,将视频、音频、控制信号进行编码并串转换后发送。 TMDS 是一种微分信号机制,采用的是差分传动方式。利用 2 个引脚间电压差来传送信号,由两脚间电压正负极性和大小决定传送“ 0 ”还是“ 1 ”。采用 2 根线来传输信号,一根线上传输原来的信号,另一根线上传输与原来信号相反的信号,接收端就可以通过让一根线上的信号减去另一根线上的信号的方式来屏蔽电磁干扰,从而得到正确的信号。
TMDS 传输通道编码解码示意图
TMDS 模块包含三个相同的编码和发送模块,每个 TMDS 通道都能传送 10bit 的数据流。每个发送模块包含 8 位的像素数据, 2 个控制信号,一个四位数据信号。
每个数据通道的 8bit 的数据在 source 经过 TMDS 编码(异或、异或非等)后得到 10bit 数据,前 8 位数据由原始信号经运算后获得,第 9 位为编码位,指示运算的方式,第 10 位为直流平衡,使 TMDS 发送的 "0" 、 "1" 数量保持基本一致,让传输的数据趋于直流平衡,减少信号对传输线的电磁干扰,提高信号传输的可靠性。 10bit 数据经过并串转换器 serializer 后通过 TMDS 数据通道串行输出,并转串过程所生成的串行数据速率是实际像素时钟速率的 10 倍;在 sink 端先进行复原成并行的 10bit 的数据,再通过 TMDS 解码得到 8bit 的源数据。此外, HDMI 视频是 stream 式的传输,不涉及 packet 式的传输。
( 1 )使用 channel0 的 D[1:0] 传输 HSYNC, VSYNC ,占用 2bit ,控制信号被编码成 10 位传输, 00 、 01 、 10 、 11 编码后分别是 10'b1101010100,10'b0010101011,10'b0101010100,和 10'b1010101011。
( 2 ) Preamble 控制信息,图中的 CTLx ,可用来表示后面传输的是 data island 还是 video data 。通过 channel1 和 2 的 D[1:0] 传输,占用 4bit ,控制信号被编码成 10 位传输。
( 3 ) Video Data ,视频数据,数据格式为 RGB888 , Channel0[7:0] 用于传输 B , Channel1[7:0] 用于传输 G , Channel2[7:0] 用于传输 R 。经过 TMDS 最小转换编码后成为 10 位数据,在对应的通道上传输。
( 4 ) Data Island ,数据岛,如音频数据包。数据岛以包数据的格式传输的,由包头和包体构成。包头用于指定包体的类型,包体是具体数据岛周期中的音频信号,通过 3 个 channel 的 D[3:0] 传输, Channel0[1:0] 用于传输 HSYNC, VSYNC , Channel0[3:2] 用于传输 Data Island Header (包头数据), Channel1[3:0] 与 Channel2[3:0] 用于传输 Data Island Content (包内数据),经过 TMDS 最小转换编码后成为 10 位数据,在对应的通道上传输。
在 HDMI 传输视频图像的过程中,数据通道上传输的是编码后的有效像素,消隐期内传输的是编码后的控制字符,还可以用于传输音频等数据,本课我们只考虑传输视频的情况。
1.1 硬件电路分析 下图为单向的 HDMI 输出接口连线示意图,差分数据线和时钟线通过 RCLAMP0524P 低电容 TVS 二极管阵列后接到 FPGA 管脚上,并上拉到 3.3V 。RCLAMP0524 低电容 TVS (Transient Voltage Suppressor )二极管阵列,四路静电保护器件,用于保护高速数据接口,避免电路受到静电放电( ESD )和其他瞬态电压事件的影响 。 CEC 引脚依旧没有使用,此处接到 3.3V 。 比较复杂的是IIC 、SDA 的电平转换电路,由于 FPGA 的引脚电压一般小于等于 3.3V ,而 HDMI 的引脚需要 5V 的电压来驱动,所以这里通过 NMOS 管的方式对电平进行转换。 SDA 是双向通信的信号线,所以无论是 FPGA 控制外设,还是外设控制 FPGA ,都可以进行 5V 、 3.3V 的电平转换。 由于这里 HDMI 只 作为输出,所以热插拔检测引脚就只作为输入,输入信号经过分压连接到 FPGA 管脚上 来检测 HOT PLUG 是否连接上 。
2 程序设计
2 .1 系统框图 2.2 PLL 时钟设置 对于 PLL的设置需要产生 1:5 的时钟 ,为了实现HDMI1.0协议,需要完成10:1的并串转换。对于 PLL 的设置需要产生1:5的时钟,对于演示demo中 720 P的设置如下:
2. 3 hdmi_tx IP使用介绍 本 IP由安路提供。 HDMI(High Definition Multimedia Interface) 是一种全数字化影像和声音发送接口,可以发送未压缩的音频及视频信号。 HDMI 可用于机顶盒、 DVD 播放机、个人电脑、投影仪与电视等设备, HDMI 发送音频和视频信号采用同一条线材,大大简化系统线路的安装难度。
本 HDMI Transmitter设计支持的功能如下:
2. 3.1 hdmi_tx IP系统框图
HDMI Transmitter设计包含以下三部分:
HDMI_TX_controller: HDMI 的协议层,用于将音频数据、视频数据以及配置数据打包编码,输出 TMDS 编码数据。
HDMI_TX_PHY: HDMI 的物理层,用于将协议层传输的 TMDS 编码数据转换为串行数据并发送出去。
EDID_Receiver:读取 HDMI 接收端的 EDID 数据。
2. 3.2 HDMI IP时钟架构 HDMI Transmitter工作需要两个时钟,像素时钟 pixel_clk 和串行发送时钟 serial_clk 。两个时钟都是通过 PLL 生成,其中 serial_clk 的频率是 pixel_clk 频率的五倍。
2. 3.3 HDMI IP视频接口时序
图 2- 9 视频接口时序
I_video_in_user信号是帧起始信号,为一个单时钟周期信号,在第一行第一个有效数据拉高。 I_video_in_valid 是数据有效信号, I_video_in_last 是行结束信号,在一行数据的结尾拉高。 O_video_in_ready 是接收端准备信号,为高表示可以写入数据,在 I_video_in_last 为高之后会拉低。
3 顶层调用接口源码 关于 VTC ip 和 TPG ip 的源码在前文中已经给出,这里我们主要看 一下顶层调用接口。
module display(
input I_sysclk,//系统时钟输入
output O_HDMI_CLK_P,//HDMI输出时钟P端
output O_HDMI_CLK_N,//HDMI输出时钟N端
output [2:0]O_HDMI_TX_P,//HDMI输出数据P端
output [2:0]O_HDMI_TX_N //HDMI输出数据N端
);
wire clk_25m;
wire vid_rst,vid_clk,vid_vs,vid_hs,vid_de;//vtc vid 相关信号
wire pclkx1,pclkx5,locked;//HDMI输出需要2个时钟,pclkx1是和内部视频同步的时钟,pclkx5是HDMI IP内部用于产生输出数据和输出时钟
wire [7 :0] rgb_r ,rgb_g ,rgb_b;//定义寄存器保存图像的颜色数据
assign vid_clk = pclkx1;//内部像素时钟
assign vid_rst = locked;//用PLL的LOCK信号复位
reg [7:0] rst_cnt=0;
always @(posedge I_sysclk)
begin
if (rst_cnt[7])
rst_cnt <= rst_cnt;
else
rst_cnt <= rst_cnt+1'b1;
end
//PLL时钟管理IP 输出 pclkx1和pclkx5以及locked信号
clk_hdmi_pll clk_hdmi_pll_inst(
.refclk(I_sysclk),//系统时钟输入
.reset(!rst_cnt[7]),
.extlock(locked),//PLL LOCKED
.clk0_out(clk_25m),
.clk1_out(pclkx1),//像素时钟
.clk2_out(pclkx5) //HDMI IO的serdes 时钟 5倍的像素时钟
);
//hdmi 输出IP
uihdmitx #
(
.FAMILY("EG4")
)
uihdmitx_inst
(
.RSTn_i(locked),//异步复位信号,高电平有效
.HS_i(vid_hs),//RGB输入hs行同步
.VS_i(vid_vs),//RGB输入vs场同步
.DE_i(vid_de),//RGB输入de有效
.RGB_i({rgb_r,rgb_g,rgb_b}), //视频输入数据
.PCLKX1_i(pclkx1),//像素时钟
.PCLKX5_i(pclkx5),//串行发送时钟
.HDMI_CLK_P(O_HDMI_CLK_P),//HDMI时钟通道
//.HDMI_CLK_N(O_HDMI_CLK_N),
.HDMI_TX_P(O_HDMI_TX_P)//HDMI数据通道
//.HDMI_TX_N(O_HDMI_TX_N)
);
uivtc#
(
.H_ActiveSize(1280), //视频时间参数,行视频信号,一行有效(需要显示的部分)像素所占的时钟数,一个时钟对应一个有效像素
.H_SyncStart(1280+88), //视频时间参数,行同步开始,即多少时钟数后开始产生行同步信号
.H_SyncEnd(1280+88+44), //视频时间参数,行同步结束,即多少时钟数后停止产生行同步信号,之后就是行有效数据部分
.H_FrameSize(1280+88+44+239), //视频时间参数,行视频信号,一行视频信号总计占用的时钟数
.V_ActiveSize(720), //视频时间参数,场视频信号,一帧图像所占用的有效(需要显示的部分)行数量,通常说的视频分辨率即H_ActiveSize*V_ActiveSize
.V_SyncStart(720+4), //视频时间参数,场同步开始,即多少行数后开始产生场同步信号
.V_SyncEnd (720+4+5), //视频时间参数,场同步结束,多少行后停止产生长同步信号
.V_FrameSize(720+4+5+28) //视频时间参数,场视频信号,一帧视频信号总计占用的行数量
)
uivtc_inst
(
.I_vtc_rstn(vid_rst),
.I_vtc_clk(vid_clk),
.O_vtc_vs(vid_vs),//场同步输出
.O_vtc_hs(vid_hs),//行同步输出
.O_vtc_de(vid_de)//视频数据有效
);
uitpg uitpg_inst
(
.I_tpg_clk(vid_clk), //系统时钟
.I_tpg_vs(vid_vs),//图像的vs信号
.I_tpg_hs(vid_hs),//图像的hs信号
.I_tpg_de(vid_de),//de数据有效信号
.O_tpg_vs(),//和vtc_vs信号一样
.O_tpg_hs(),//和vtc_hs信号一样
.O_tpg_de(),//和vtc_de信号一样
.O_tpg_data({rgb_r,rgb_g,rgb_b})//测试图像数据输出
);
endmodule 复制代码
4 FPGA工程
米联客的代码管理规范 ,在对应的 FPGA 工程路径下创建 uisrc 路径,并且创建以下文件夹
04_pin:放 fpga 的 pin 脚约束文件或者时序约束文件
05_boot:放编译好的 bit 或者 bin 文件 ( 一般为空 )
5下载演示 5. 1硬件连接
(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)
请确保下载器和开发板已经正确连接,并且开发板已经上电 (注意 JTAG 端子不支持热插拔,而 USB 接口支持,所以在不通电的情况下接通好 JTAG 后,再插入 USB 到电脑,之后再上电,以免造成 JTAG IO 损坏 )
5. 2运行结果