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

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

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

相关推荐
芯路行者11 小时前
7 HDLBits —— 验证:编写测试激励文件
fpga开发·verilog·fpga·hdlbits
芯路行者12 小时前
4.1 HDLBits —— 时序逻辑电路之锁存器与触发器
fpga开发·verilog·fpga·hdlbits
芯路行者15 小时前
5 HDLBits —— 构建更大的电路
fpga开发·verilog·fpga·hdlbits
1560820721915 小时前
直流耦合采集卡前端电路调试
嵌入式硬件·fpga开发
芯路行者15 小时前
4.3 HDLBits —— 时序逻辑电路之移位寄存器
fpga开发·verilog·fpga·hdlbits
芯路行者16 小时前
4.2 HDLBits —— 时序逻辑电路之计数器
fpga开发·verilog·fpga·hdlbits
FPGA小迷弟21 小时前
FPGA时序收敛实战:从约束编写到布局布线优化全流程
fpga开发·fpga·硬件开发
FPGA小迷弟1 天前
AXI4-Stream协议详解与Vivado自定义IP核封装实战
网络协议·tcp/ip·fpga开发·fpga·硬件开发
zlinear数据采集卡2 天前
数据采集卡从入门到精通(10):采样率与分辨率的核心关系——反比律、架构分布与过采样
arm开发·嵌入式硬件·算法·fpga开发·架构·开源
zlinear数据采集卡2 天前
数据采集卡从入门到精通(9):分辨率与精度——16位卡不等于1/65536的精度
开发语言·数据库·fpga开发·开源·c#