HDMI数据的接收发送实验(十八)
2026/7/9 6:43:17 网站建设 项目流程

一、 概况
之前已经讲述了如何用时钟的动态偏移来实现数据的自动校准。本章节来说明时钟的动态偏移的使用情况,和HDMI数据接收的处理流程。
二、 HDMI接收处理
处理流程:
1、差分时钟接收与动态相位调整
2、串并转换(ser2par模块)
3、TMDS 解码(decode模块)
4、像素信息统计(pixel_message子模块)
hdmi_in模块接收处理HDMI的输入信号,先通过时钟的相位偏移实现数据的自动校正,再通过decode模块进行信号的10bit到8bit转换,算出RGB信号和行场同步及de信号。再由行场同步及de信号可以算出每一帧图像里,行同步有多少,场同步有多少,这就是接收到的视频的像素值。接口连接如图1:

hdmi_in模块接口列表:

module hdmi_in(
input wire clk ,//50M
input wire rst_n ,
input wire clk_200 ,
input wire tmds_clk_p ,
input wire tmds_clk_n ,
input wire tmds_r_p ,
input wire tmds_r_n ,
input wire tmds_g_p ,
input wire tmds_g_n ,
input wire tmds_b_p ,
input wire tmds_b_n ,

output clk_1x ,
output [7:0] r_pixel ,
output [7:0] g_pixel ,
output [7:0] b_pixel ,

output h_sync ,
output v_sync ,
output vga_de ,

output wire r_hdmi_en
);
wire h_sync_r ;
wire v_sync_r ;
wire vga_de_r ;

wire[11:0] h_pixel_num ;
wire[11:0] v_pixel_num ;
wire pixel_clk ;

wire clk_5x ;
wire[9:0] r_10bit ;
wire[9:0] g_10bit ;
wire[9:0] b_10bit ;
reg[9:0] b_10bit_reg ;
wire locked ;
reg hdmi_calib_done ;

parameter CTRL0 = 10’h354;//h_sync = 0,v_sync = 0,vga_de = 0
parameter CTRL1 = 10’h0ab;//h_sync = 1,v_sync = 0,vga_de = 0
parameter CTRL2 = 10’h154;//h_sync = 0,v_sync = 1,vga_de = 0
parameter CTRL3 = 10’h2ab;//h_sync = 1,v_sync = 1,vga_de = 0

reg[1:0] cnt_num ;

reg psen;
wire psincdec;
reg [10:0] cnt_psen;
reg [4:0] cnt_psclk;

assign r_hdmi_en = 1’b1 ;

//pixel_10bit_reg
always@(posedge clk_1x)
if(locked==1’b0)
b_10bit_reg <= 10’b0;
else
b_10bit_reg <= b_10bit;

//cnt_num
always@(posedge clk_1x)
if(locked1’b0)
cnt_num <= 2’b0;
else if(b_10bit
b_10bit_reg)
cnt_num <= cnt_num;
else if(b_10bitCTRL1&&b_10bit_regCTRL0)
cnt_num <= cnt_num+1’b1;
else if(b_10bitCTRL0&&b_10bit_regCTRL1)
cnt_num <= cnt_num+1’b1;
else if((b_10bit!=CTRL0)&&(b_10bit!=CTRL1))
cnt_num <= 2’b0;

//hdmi_calib_done
always@(posedge clk_1x)
if(locked1’b0)
hdmi_calib_done <= 1’b0;
else if(cnt_num
2)
hdmi_calib_done <= 1’b1;

always @(posedge clk_200 ) begin
if(!rst_n) begin
cnt_psclk <= 0;
end
else if (hdmi_calib_done == 1 ) begin
cnt_psclk <= 0;
end
else if (hdmi_calib_done == 0)begin
cnt_psclk <= cnt_psclk +1;
end
end

always @(posedge clk_200 ) begin
if(!rst_n) begin
cnt_psen <= 0;
end
else if (psen == 1) begin
cnt_psen <= cnt_psen +1;
end
end
always @(posedge clk_200 ) begin
if(!rst_n) begin
psen <= 0;
end
else if(cnt_psclk == 'd31)begin
psen <= 1;
end
else begin
psen <= 0;
end
end

IBUFDS #(
.DIFF_TERM(“FALSE”), // Differential Termination
.IBUF_LOW_PWR(“TRUE”), // Low power=“TRUE”, Highest performance=“FALSE”
.IOSTANDARD(“DEFAULT”) // Specify the input I/O standard
) IBUFDS_inst (
.O(pixel_clk), // Buffer output
.I(tmds_clk_p), // Diff_p buffer input (connect directly to top-level port)
.IB(tmds_clk_n) // Diff_n buffer input (connect directly to top-level port)
);

clk_wiz_5x clk_wiz_5x_inst
(
// Clock out ports
.clk_1x(clk_1x), // output clk_1x
.clk_5x(clk_5x), // output clk_5x
// Dynamic phase shift ports
.psclk(clk_200), // input psclk //clk for psen
.psen(psen), // input psen //start flag
.psincdec(0), // input psincdec //1+,0-.
.psdone(psdone), // output psdone //finish flag
// Status and control signals
.reset(!rst_n), // input reset
.locked(locked), // output locked
// Clock in ports
.clk_in1(pixel_clk)); // input clk_in1

//r
ser2par ser2par_r_inst(
.pixel_clk (clk_1x ),
.pixel_clk_5x (clk_5x ),
.rst_n (locked ),
.ser_dat_p (tmds_r_p ),
.ser_dat_n (tmds_r_n ),
.pixel_10bit (r_10bit )
);

//decode
decode decode_r(
.pixel_clk (clk_1x ),
.rst_n (locked ),
.i_par_dat (r_10bit ),
.de (),
.c0 (),
.c1 (),
.pixel_dat (r_pixel )
);
//g
ser2par ser2par_g_inst(
.pixel_clk (clk_1x ),
.pixel_clk_5x (clk_5x ),
.rst_n (locked ),
.ser_dat_p (tmds_g_p ),
.ser_dat_n (tmds_g_n ),
.pixel_10bit (g_10bit )
);

//decode
decode decode_g(
.pixel_clk (clk_1x ),
.rst_n (locked ),
.i_par_dat (g_10bit ),
.de (),
.c0 (),
.c1 (),
.pixel_dat (g_pixel )
);

//b
ser2par ser2par_b_inst(
.pixel_clk (clk_1x ),
.pixel_clk_5x (clk_5x ),
.rst_n (locked ),
.ser_dat_p (tmds_b_p ),
.ser_dat_n (tmds_b_n ),
.pixel_10bit (b_10bit )
);

//decode
decode decode_b(
.pixel_clk (clk_1x ),
.rst_n (locked ),
.i_par_dat (b_10bit ),
.de (vga_de ),
.c0 (h_sync ),
.c1 (v_sync ),
.pixel_dat (b_pixel )
);

assign h_sync_r=h_sync;
assign v_sync_r=v_sync;
assign vga_de_r=vga_de;

//pixel_message
pixel_message pixel_message_inst(
.pix_clk (clk_1x ),
.rst_n (locked ),
.h_sync (h_sync_r ),
.v_sync (v_sync_r ),
.de (vga_de_r ),
.o_h_cnt (h_pixel_num ),
.o_v_cnt (v_pixel_num )
);

endmodule

三、总结
本章节完整演示了HMDI接收链路的底层硬件实现,涵盖动态相位补偿技术,TMDS 解码算法,帧同步参数提取。
下一章节来讲述如何将10bit编码信号转换为8bit信号(TMDS 解码算法)。和通过获取HDMI数据信号计算像素的过程。
本文章由威三学社威三学院出品
对课程感兴趣可以私信联系

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询