手机扫码
链接直达
https://item.taobao.com/item.htm?ft=t&id=776516984361
概述
HDMI
HDMI(High Definition Multimedia Interface)是一种全数字化影像和声音发送接口, 可以发送未压缩的音频及视频信号。 HDMI 可用于机顶盒、 DVD 播放机、 个人电脑、 投影仪与电视等设备, HDMI 发送音频和视频信号采用同一条线材, 大大简化系统线路的安装难度。
TMDS
TMDS(Transition Minimized Differential signal), 过渡调制差分信号, 也被称为最小化传输差分信号, 是指通过异或及异或非等逻辑算法将原始信号数据转换成 10 位, 前 8 位数据由原始信号经运算后获得, 第 9 位指示运算的方式, 第 10 位用来对应直流平衡(DC-balanced, 就是指在编码过程中保证信道中直流偏移为零, 电平转化实现不同逻辑接口间的匹配), 转换后的数据以差分传动方式传送。其具体编码过程可查阅 HDMI1.4 标准的规格书。
这个实验我们将利用EG4 FPGA的LVDS实现HDMI TX的功能,因为EG4没有serdes,所以只能支持到HDMI1.4,且考虑到图像质量我们只支持到720P(对于我们入门图像处理学习完全够用了),至于1080P不太稳定不推荐。
本工程里面的HDMI_TX是安路提供的一个相对简单易用的版本,安路新提供的APUG058有演示1080P EDID,AUDIO等功能,但使用较复杂不便于入门,感兴趣者可以自己参考APU058。
硬件原理图
FPGA侧
可以看到实现HDMI,只需要使用FPGA侧的LVDS接口即可,在HDMI_*开头的网络即为HDMI所使用的LVDS。
HDMI接口侧
从图上可以看到HDMI接口侧主要就一个HDMI的母座,然后就是 RCLAMP0524P 这个ESD管子,由于HDMI的母座引入静电所以加了这个。另外就是RN1 RN2两个排阻,起到一个上拉作用,阻值为 499R电阻与RX端50R上拉3.3V电阻分压形成3V的共模电压 。
工程分析
代码分析
我们看工层的层次图
- hdmi_720p是本工程的顶层
- clk_hdmi_pll_inst是本工程的PLL,用于产生测试pattern画面和HDMI显示所需要的时钟
- u3_hdmi_tx是安路早期提供的HDMI的720P的网表。
- u_vga_tc是用来控制HDMI测试画面的时序,即 timming control的缩写。
- u_vga_tpg就是产生HDMI的各种测试画面的数据。
接下来逐步分析顶层的每个模块。
clk_hdmi_pll
用板载10M时钟产生了两路高速时钟75M和375M,PLL IP配置如下图:
hdmi_tx
安路提供的简化版的720P的HDMI网表
//HDMI TX Module
hdmi_tx #(.FAMILY("EG4")) //EF2、EF3、EG4、AL3、PH1
u3_hdmi_tx
(
.PXLCLK_I (clk_pixel),
.PXLCLK_5X_I (clk_pixel_5x),
.RST_I (~locked),
//VGA
.VGA_HS (VGA_HS ),
.VGA_VS (VGA_VS ),
.VGA_DE (VGA_DE ),
.VGA_RGB (VGA_RGB),
//HDMI
.HDMI_CLK_P (HDMI_CLK_P),
.HDMI_D2_P (HDMI_TX_P[2] ),
.HDMI_D1_P (HDMI_TX_P[1] ),
.HDMI_D0_P (HDMI_TX_P[0] )
);
- .PXLCLK_I 就是PLL生成的75M就是pixel的像素时钟
- .PXLCLK_5X_I 就是PLL生成的375M是串行时钟
- .RST_I PLL的LOCK信号取反生成HDMI的复位信号,HDMI接口是高电平复位。
- .HDMI_* 是输出到HDMI母座的信号。
- VGA_*是输入到HDMI TX的测试视频信号,下面介绍。
vga_tc#
(
.HACTIVE(1280),
.HFP(88),
.HSA(44),
.VACTIVE(720),
.VFP(4),
.VSA (5)
)
u_vga_tc
(
.vtc_rstn_i(vid_rst),
.vtc_clk_i(vid_clk),
.vtc_vs_o(VGA_VS),
.vtc_hs_o(VGA_HS),
.vtc_de_o(VGA_DE)
);
这个模块开头的参数HACTIVE、HFP、HSA、VACTIVE、VFP、VSA提供了所需测试视频的行场参数,这些具体的数值是由视频电子标准协会(英语:Video Electronics Standards Association,简称“VESA”)标准提供的,这些参数的对应关系如下图,其中HTOTAL和VTOTAL在模块内部自动计算了。
localparam HTOTAL = HACTIVE + HFP + HSA + HBP;
localparam VTOTAL = VACTIVE + VFP + VSA + VBP;
下面看看接口:
- .vtc_rstn_i(vid_rst), 复位也由PLL LOCK信号得到。
- .vtc_clk_i(vid_clk), 时钟,与HDMI的像素时钟PXCLK_I是同一个时钟。
- .vtc_vs_o(VGA_VS), 场同步信号
- .vtc_hs_o(VGA_HS), 行同步信号
- .vtc_de_o(VGA_DE),行有效(数据有效信号)
vga_tpg
vga_tpg u_vga_tpg
(
.tpg_clk_i(vid_clk),
.tpg_vs_i(VGA_VS),
.tpg_hs_i(VGA_HS),
.tpg_de_i(VGA_DE),
.tpg_vs_o(),
.tpg_hs_o(),
.tpg_de_o(),
.tpg_data_o(VGA_RGB)
);
端口说明
- .tpg_clk_i(vid_clk), 时钟,同为HDMI的像素时钟PXCLK_I。
- .tpg_vs_i(VGA_VS), vtc模块输出的场同步
- .tpg_hs_i(VGA_HS), vtc模块输出的行同步
- .tpg_de_i(VGA_DE), vtc模块输出的行有效
- .tpg_vs_o(),
- .tpg_hs_o(),
- .tpg_de_o(),
- .tpg_data_o(VGA_RGB), 产生的测试数据
这个模块的作用就是用来生成视频的测试数据,主要就是依据下面这段代码显示不同的测试数据。
case(pattern_id[10:7])
...
'd4: begin
r_reg <= grid_data; //方格
g_reg <= grid_data;
b_reg <= grid_data;
end
'd5: begin
r_reg <= 0;
b_reg <= 0;
g_reg <= 0;
end
'd6: begin
r_reg <= 8'b11111111; //白
g_reg <= 8'b11111111;
b_reg <= 8'b11111111;
end
'd7: begin
r_reg <= 8'b11111111; //红
g_reg <= 0;
b_reg <= 0;
end
'd8: begin
r_reg <= 0; //绿
g_reg <= 8'b11111111;
b_reg <= 0;
end
'd9: begin
r_reg <= 0; //蓝
g_reg <= 0;
b_reg <= 8'b11111111;
end
'd10: begin
r_reg <= h_cnt[7:0]; //水平渐变
g_reg <= h_cnt[7:0];
b_reg <= h_cnt[7:0];
end
'd11: begin
r_reg <= v_cnt[7:0]; //垂直渐变
g_reg <= v_cnt[7:0];
b_reg <= v_cnt[7:0];
end
'd12: begin
r_reg <= v_cnt[7:0]; //红垂直渐变
g_reg <= 0;
b_reg <= 0;
end
'd13: begin
r_reg <= 0; //绿垂直渐变
g_reg <= h_cnt[7:0];
b_reg <= 0;
end
'd14: begin
r_reg <= 0; //蓝垂直渐变
g_reg <= 0;
b_reg <= h_cnt[7:0];
end
...
endcase
工程约束分析
管脚约束
可以看到P11是我们板载的10M时钟,其它就是HDMI的管脚,IO电平标准是LVDS33,需要注安路的TD工具只需要约速P端,工具会自动锁定N端。
set_pin_assignment { sysclk_i } { LOCATION = P11; }
#HDMI TX
set_pin_assignment { HDMI_CLK_P } { LOCATION = P47; IOSTANDARD = LVDS33; }
set_pin_assignment { HDMI_TX_P[0] } { LOCATION = P55; IOSTANDARD = LVDS33; }
set_pin_assignment { HDMI_TX_P[1] } { LOCATION = P61; IOSTANDARD = LVDS33; }
set_pin_assignment { HDMI_TX_P[2] } { LOCATION = P64; IOSTANDARD = LVDS33; }
时序约束
第一行约束板载的主时钟为10M,第二行让TD工具自动推导PLL的时序约束。
create_clock -name SYS_CLK -period 100 -waveform {0 50} [get_ports {sysclk_i}]
derive_pll_clocks
实验结果
部分测试画面显示结果如下图(密集恐聚症^_^),更多测试画面快下到载板子自己看看吧!
没有回复内容