HDMI数据的接收发送实验(十八)

一、 概况

之前已经讲述了如何用时钟的动态偏移来实现数据的自动校准。本章节来说明时钟的动态偏移的使用情况,和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 ;

wire11:0 h_pixel_num ;

wire11:0 v_pixel_num ;

wire pixel_clk ;

wire clk_5x ;

wire9:0 r_10bit ;

wire9:0 g_10bit ;

wire9:0 b_10bit ;

reg9: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

reg1: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_10bitb_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_num2)

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数据信号计算像素的过程。

本文章由威三学社威三学院出品

对课程感兴趣可以私信联系

相关推荐
续写烂尾16 小时前
SD NAND vs SPI NAND:接口协议、坏块管理与开发成本全面对比
fpga开发
叶子野格17 小时前
《Verilog学习:数字系统设计基础》
学习·fpga开发
花 满 楼19 小时前
TPWM — PWM 测量模式(TIM PWM Measurement Mode)
单片机·嵌入式硬件·fpga开发
叶子野格19 小时前
《Verilog学习:前置知识》
学习·fpga开发
科恒盛远1 天前
RFSoC XCZU47DR 100G UDP高速数据传输的实现与调试(PCIE908 板卡技术系列三)
fpga开发
小麦嵌入式2 天前
FPGA入门(十一):受控线性序列机 UART 发送升级
stm32·单片机·嵌入式硬件·mcu·fpga开发·硬件工程
X_xcccc2 天前
2026硬核拆解:高性能异构计算板卡选型指南
fpga开发
tju新生代魔迷3 天前
Verilog HDL 学习笔记(十)| 第10章 时序和延迟
笔记·学习·fpga开发
aprilaaaaa4 天前
(TC397 学习笔记)二、ICU和TIM的时钟计算
笔记·学习·fpga开发
X_xcccc4 天前
2026高端FPGA开发平台权威评测与选型指南
fpga开发