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

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

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

相关推荐
璞致电子12 小时前
基于 AD9361 (PZSDR‑P201Pro) 软件无线电实战综述:从板卡选型、硬件平台升级到 GNU Radio QPSK 完整收发链路
经验分享·嵌入式硬件·fpga开发·软件无线电·sdr·璞致电子
炎龙铠甲会合体14 小时前
从 SPEC 到上板:在 Zynq-7020 上用 RTL 手写一个 YOLO 卷积加速器(完整教程)
yolo·fpga开发·axi·芯片验证
FPGA小徐14 小时前
Vivado 按键消抖与复位模块代码修复详解:KEY_TOP、key、rst_gen 完整实战
fpga开发
炎龙铠甲会合体16 小时前
AXI2ICACHE— AXI4-Full 四路组相联指令 Cache 设计与 UVM 验证
fpga开发·面试·芯片验证
bingcheby16 小时前
FMQL15/20/45 (复旦微青龙系列 PSOC)新手使用说明
fpga开发
漫漫长远17 小时前
低功耗UPF介绍(一)
笔记·嵌入式硬件·学习·fpga开发
自小吃多1 天前
【Verilog/FPGA】存储器(数组)
嵌入式硬件·fpga开发
szxinmai主板定制专家1 天前
RK3588+FPGA异构架构|高速数据采集+边缘AI落地应用全解析
人工智能·嵌入式硬件·fpga开发·架构·zynq
明德扬1 天前
FPGA MIPI 多路视频聚合方案
fpga开发·mipi视频拼接·mipi多路拼接·mipi协议·mipi视频拼接方案·fpga mipi方案·mipi csi
XMAIPC_Robot1 天前
为什么大型储能需要边缘 AI 协调控制器?RK3588+FPGA 高速采集方案
人工智能·嵌入式硬件·fpga开发·arm+fpga·rk3588+fpga·协调控制器