前面简单提了下HDMI的理论部分,这篇就涉及到“实战”,下面先放张效果图,实现的黑白方格(因为是在晚上拍的,效果不是很好)。
再来说说实现环境:
本工程采用的米联的MZ20B的板子(这块板子1500大洋呢,不过功能真的很强),这块板子上搭载了一块HDMI接口,采用I/O模拟HDMI信号,输出可以达到1080P 60Hz高清传输,输入可以到720P 60Hz。原理图如下
对应引脚如下
工程文件包含2个IP核,2个.v文件,IP核一个是vivado中自带的clocking wizard,这个IP主要用来产生时钟信号,输入时钟为100MHz,输出有2个时钟,一个当作VGA时序信号的工作时钟(本工程采用的分辨率为1280*768 60HZ),另一个是时序信号时钟的5倍,具体的用处在下面会提到。
另一个IP核的作用在本工程中至关重要,不是xilinx提供的,需要自己添加,它的作用就是将产生的VGA时序信号进行编码输出。它会用到2个时钟,一个就是VGA的工作时钟,一个为VGA工作时钟的5倍,主要的输入信号为VGA_HS VGA_VS VGA_DE VGA_RGB[23:0],这些都是从VGA工作时序中产生的,输出信号在前面的理论中已经提到。我上传了2个IP在这里HDMI的IP。2个IP实现方法差不多。
.v文件主要的是hdmi_data_gen文件,主要实现VGA时序的程序设计,VGA时序我传的文档在这里VGA分辨率时序。具体实现代码如下:
module hdmi_data_gen
(
input pix_clk,
output [7:0] VGA_R,
output [7:0] VGA_G,
output [7:0] VGA_B,
output VGA_HS,
output VGA_VS,
output VGA_DE
);
//---------------------------------//
// 水平扫描参数的设定1280*720 60HZ
//--------------------------------//
parameter H_Total = 1680; //e
parameter H_Sync = 136; //a
parameter H_Back = 200; //b
parameter H_Active = 1280; //c
parameter H_Front = 64; //d
parameter H_Start = 336;
parameter H_End = 1616;
//-------------------------------//
// 垂直扫描参数的设定1280*720 60HZ
//-------------------------------//
parameter V_Total = 828;
parameter V_Sync = 3;
parameter V_Back = 24;
parameter V_Active = 800;
parameter V_Front = 1;
parameter V_Start = 27;
parameter V_End = 827;
reg[11:0] x_cnt;
always @(posedge pix_clk) //水平计数
begin
if(1'b0)
x_cnt <= 1;
else if(x_cnt==H_Total)
x_cnt <= 1;
else
x_cnt <= x_cnt + 1;
end
reg[11:0] y_cnt;
always @(posedge pix_clk)
begin
if(1'b0)
y_cnt <= 1;
else if(y_cnt==V_Total)
y_cnt <= 1;
else if(x_cnt==H_Total)
y_cnt <= y_cnt + 1;
end
wire hs_de = (x_cnt
接下来就是例化文件HDMI_display_Demon文件,具体实现代码如下:
module HDMI_display_Demon(
input clk_100M,
output HDMI_CLK_P,
output HDMI_CLK_N,
output HDMI_D2_P,
output HDMI_D2_N,
output HDMI_D1_P,
output HDMI_D1_N,
output HDMI_D0_P,
output HDMI_D0_N
);
wire pixclk;
wire[7:0] R,G,B;
wire HS,VS,DE;
hdmi_data_gen u_hdmi_data_gen
(
.pix_clk (pixclk),
.VGA_R (R),
.VGA_G (G),
.VGA_B (B),
.VGA_HS (HS),
.VGA_VS (VS),
.VGA_DE (DE)
);
wire serclk;
wire lock;
wire[23:0] RGB;
assign RGB={R,G,B};
HDMI_FPGA_ML_0 u_HDMI
(
.PXLCLK_I (pixclk),
.PXLCLK_5X_I (serclk),
.LOCKED_I (lock),
.RST_N (1'b1),
.VGA_HS (HS),
.VGA_VS (VS),
.VGA_DE (DE),
.VGA_RGB (RGB),
.HDMI_CLK_P (HDMI_CLK_P),
.HDMI_CLK_N (HDMI_CLK_N),
.HDMI_D2_P (HDMI_D2_P),
.HDMI_D2_N (HDMI_D2_N),
.HDMI_D1_P (HDMI_D1_P),
.HDMI_D1_N (HDMI_D1_N),
.HDMI_D0_P (HDMI_D0_P),
.HDMI_D0_N (HDMI_D0_N)
);
clk_wiz_0 u_clk
(
.clk_in1 (clk_100M),
.resetn (1'b1),
.clk_out1 (pixclk),
.clk_out2 (serclk),
.locked (lock)
);
endmodule
整个工程我已上传到这里工程文件。同时,在此推荐一篇文章HDMI实现。