HDMI显示器驱动设计与验证

news/2025/2/21 6:25:32/

1、介绍

        HDMI,英文全称“High Definition Multimedia Interface”,高清多媒体接口。

        HDMI接口是目前最主流的接口了。它在2002年提出,现在已经发展到HDMI 2.1标准,而且随着行业发展,HDMI 2.1标准已经能够支持4K 120Hz及8K 60Hz,支持高动态范围成像(HDR),可以针对场景或帧数进行优化,向后兼容HDMI 2.0、HDMI 1.4。最主要的是,它是视音频同时传输的。

HDMI规格诞生日期支持的分辨率和对应的刷新率
HDMI2.02013年1080p 144Hz
2K 144Hz
4K 60Hz
HDMI2.12017年1080p 240Hz
2K 240Hz
4K 120Hz
8K 30Hz

        VGA接口成本低,结构简单,应用灵活,但是传输的是模拟信号,就容易受到外界干扰源的影响,受到影响会导致信号畸变,传输的图像就会出现问题,VGA接口体积大,不利于便携设备的使用。后来出现了DVI接口,DVIA(只传输模拟信号)、DVID(只传输数字信号)、DVII(兼容数字信号和模拟信号),数字信号比较不容易受到干扰,体积比VGA还大,只能传输图像,不能传输音频信号。后来出现了HDMI接口,体积小,抗干扰能力更强,可以实现音频和数字信号的同步传输,兼容性好。不同接口的区别如下:

接口类型设计年代 最大支持分辨率刷新率 特点
VGA1987年   1080p 60Hz1.传输的是模拟信号
2.画面传输质量不高
3.不能传输声音信号
DVI 1999年    2K  120Hz(1080p下)或60Hz(2K下)1.传输的是数字信号
2.画面传输质量不高
3.不能传输声音信号
HDMI2002年   8K 240Hz(1080P下)  1.传输的是数字信号
2.画面传输质量高
3.可以传输声音信号
DP2006年   16K 240Hz(4K下)  1.传输的是数字信号
2.画面传输质量高
3.可以传输声音信号

HDMI引脚:

引脚定义引脚定义
1数据2+11时钟屏蔽
2数据2屏蔽12时钟-
3数据2-13CEC
4数据1+14保留
5数据1屏蔽15DDC时钟线(SCL)
6数据1-16DDC数据线(SDA)
7数据0+17DDC / CEC地
8数据0屏蔽18+5V电源
9数据0-19热插拔检测
10时钟+

 引脚分类:

(1)TMDS,是一种传输技术,引脚1~引脚12,用于发送音频、视频和各种辅助数据,遵循DVI编码方式,引脚1和引脚3、引脚4和引脚6、引脚7和引脚9、引脚10和引脚12是四对差分信号
(2)DDC通道,显示数据通道,引脚15~引脚17,只需要单向获取接收端的信息,也就是显示器,其实就是I2C接口
(3)CEC通道,引脚13和引脚17
(4)其他,保留、电源、热插拔检测

HDMI显示原理:

发送端将图像数据、音频数据和控制信号转换成4对差分信号,传给接收方,供接收方解码使用。

TMDS传输原理 : 

         发送端收到表示RGB信号的24bit并行数据,这些数据在行场同步信号和使能信号下,与时钟信号一起进行编码和并串转换,之后将3个表示RGB的数据和1个时钟信号分别分配到4个独立的通道发送出去。

        接收端接收到发送端发过来的串行信号,进行解码和串并转换,之后发送到显示器的控制端,在时钟信号的同步下进行显示。

信号传输步骤:

(1)8bit视频、音频数据转换为10bit的最小传输、直流均衡数据,编码
(2)并行10bit编码后的数据转换为串行差分信号,并串转换

2、HDMI显示器驱动设计与验证

 ① 模块设计

        可以使用前面的vga_coloarbar工程,得到rgb、hsync、vsync信号,clk由PPL锁相环得到,DE使能信号可以用从vga_ctrl模块引出的rgb_valid信号代替;经过了vga_pic和vga_ctrl,就可以得到基于TMDS传输原理的hdmi_ctrl模块输入端口信号,R、G、B信号,hsync、vsync行场同步和DE使能信号。

在这里插入图片描述

        hdmi_ctrl模块要完成TMDS传输方式,需要有两组逻辑实现,encode对接收过来的数据进行编码、par_to_ser对编码后的10bit数据进行串行发送,可以给里面安排独立的两个模块逻辑。

在这里插入图片描述

        HDMI的15、16引脚分别是DDC时钟线(SCL)、DDC数据线(SDA),这两路信号连接的是显示器的ROM,采用的是I2C协议,用于读取显示器ROM中的数据,比如生产厂商、型号、支持的分辨率等。这两个接口暂时不使用,强制置位高电平。

encode模块代码:

module encode (input	wire			vga_clk		,input	wire			sys_rst_n	,input	wire			hsync		,input	wire			vsync		,input	wire			rgb_valid	,input	wire	[ 7: 0]	data_in		,output	reg		[ 9: 0]	data_out
);wire				ctrl_1		;		// 组合逻辑计算D数据1的个数wire				ctrl_2		;wire				ctrl_3		;wire	[ 8: 0]		q_m			;		// 8bit到9bit扩展reg		[ 3: 0]		data_in_n1	;reg		[ 7: 0]		data_in_reg	;		// 输入数据打拍	reg		[ 4: 0]		cnt			;		// 后面要计算(cnt(t-1) + (N0{q_m[0:7]} - N1{q_m[0:7]})),8+8就需要4bit,再加上一个符号位reg		[ 3: 0]		q_m_n1		;reg		[ 3: 0]		q_m_n0		;reg		[ 8: 0]		q_m_reg		;reg					de_reg1		;reg					de_reg2		;reg					c0_reg1		;reg					c0_reg2		;reg					c1_reg1		;reg					c1_reg2		;always @ (posedge vga_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)data_in_n1	<=	4'd0;elsedata_in_n1	<=	data_in[0] + data_in[1] + data_in[2] + data_in[3] + data_in[4] + data_in[5] + data_in[6] + data_in[7];always @ (posedge vga_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)data_in_reg	<=	8'b0;elsedata_in_reg	<=	data_in;assign	ctrl_1	=	((data_in_n1 > 4'd4) || ((data_in_n1 == 4'd4) && (data_in_reg[0] == 1'b0)))? 1'b1 : 1'b0 ;assign	q_m[0]	=	data_in_reg[0];assign	q_m[1]	=	(ctrl_1 == 1'b1) ? (q_m[0] ^~ data_in_reg[1]) : (q_m[0] ^ data_in_reg[1]) ;assign	q_m[2]	=	(ctrl_1 == 1'b1) ? (q_m[1] ^~ data_in_reg[2]) : (q_m[1] ^ data_in_reg[2]) ;assign	q_m[3]	=	(ctrl_1 == 1'b1) ? (q_m[2] ^~ data_in_reg[3]) : (q_m[2] ^ data_in_reg[3]) ;assign	q_m[4]	=	(ctrl_1 == 1'b1) ? (q_m[3] ^~ data_in_reg[4]) : (q_m[3] ^ data_in_reg[4]) ;assign	q_m[5]	=	(ctrl_1 == 1'b1) ? (q_m[4] ^~ data_in_reg[5]) : (q_m[4] ^ data_in_reg[5]) ;assign	q_m[6]	=	(ctrl_1 == 1'b1) ? (q_m[5] ^~ data_in_reg[6]) : (q_m[5] ^ data_in_reg[6]) ;assign	q_m[7]	=	(ctrl_1 == 1'b1) ? (q_m[6] ^~ data_in_reg[7]) : (q_m[6] ^ data_in_reg[7]) ;assign	q_m[8]	=	(ctrl_1 == 1'b1) ? 1'b0 : 1'b1;always @ (posedge vga_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)beginq_m_n1	<=	4'd0;q_m_n0	<=	4'd0;endelsebeginq_m_n1	<=	q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];q_m_n0	<=	4'd8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);end//	assign	ctrl_2	=	((cnt == 5'd0) || (q_m_n1 == q_m_n0)) ? 1'b1 : 1'b0;
//	assign	ctrl_3	=	(((cnt > 5'd0) && (q_m_n1 > q_m_n0)) 
//						|| ((cnt < 5'd0) && (q_m_n0 > q_m_n1)))
//						? 1'b1 : 1'b0;/* cnt是由符号位的,所以不能简单的进行大于小于判断,而是应该判断符号位*/assign	ctrl_2	=	((cnt == 5'd0) || (q_m_n1 == q_m_n0)) ? 1'b1 : 1'b0;assign	ctrl_3	=	(((cnt[4] == 1'b0) && (q_m_n1 > q_m_n0)) || ((cnt[4] == 1'b1) && (q_m_n0 > q_m_n1)))? 1'b1 : 1'b0;// 打拍信号统一赋值always @ (posedge vga_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)beginq_m_reg	<=	9'b0;de_reg1	<=	1'b0;de_reg2	<=	1'b0;c0_reg1	<=	1'b0;c0_reg2	<=	1'b0;c1_reg1	<=	1'b0;c1_reg2	<=	1'b0;endelsebeginq_m_reg	<=	q_m;de_reg1	<=	rgb_valid;de_reg2	<=	de_reg1;c0_reg1	<=	hsync;c0_reg2	<=	c0_reg1;c1_reg1	<=	vsync;c1_reg2	<=	c1_reg1;endalways @ (posedge vga_clk or negedge sys_rst_n)if (sys_rst_n == 1'b0)begindata_out	<=	10'b0;cnt			<=	5'd0;endelsebeginif (de_reg2 == 1'b1)beginif (ctrl_2 == 1'b1)begindata_out[9]		<=	~q_m_reg[8];data_out[8]		<=	q_m_reg[8];data_out[ 7: 0]	<=	(q_m_reg[8] ? q_m_reg[ 7: 0] : ~q_m_reg[ 7: 0]);cnt	<=	(q_m_reg[8] == 1'b0) ? (cnt + (q_m_n0 - q_m_n1)) : (cnt + (q_m_n1 - q_m_n0));endelsebeginif (ctrl_3 == 1'b1)begindata_out[9]		<=	1'b1;data_out[8]		<=	q_m_reg[8];data_out[ 7: 0]	<=	~q_m_reg[ 7: 0];cnt	<=	cnt + {q_m_reg[8], 1'b0} + (q_m_n0 - q_m_n1);endelsebegindata_out[9]		<=	1'b0;data_out[8]		<=	q_m_reg[8];data_out[ 7: 0]	<=	q_m_reg[ 7: 0];cnt	<=	cnt - {~q_m_reg[8], 1'b0} + (q_m_n1 - q_m_n0);endendendelsebegincase ({c1_reg2, c0_reg2})2'b00:	data_out	<=	10'b00_1010_1011;2'b01:	data_out	<=	10'b11_0101_0100;2'b10:	data_out	<=	10'b00_1010_1010;2'b11:	data_out	<=	10'b11_0101_0101;default:	;endcasecnt	<=	5'd0;endendendmodule

par_to_ser模块代码:

  1. 并行转串行
  2. 单端信号到差分信号的转换
  3. 单沿到双沿的转换

该模块分为两部分:

        第一部分,将并行的10bit数据在25MHz下经过重组、移位,变成串行的10bit数据,再将这10bit数据分成两组5bit信号data_rise、data_fall,方便区分双沿发送,在125MHz下,以移位寄存的方式从低位逐比特发送

        第二部分,调用ddio模块,在125MHz下,上升沿发送送入的data_rise[0]、下降沿发送送入的data_fall[0]

module par_to_ser (input	wire			clk_5x	,input	wire	[ 9: 0]	data_in	,output	wire			ser_p	,output	wire			ser_n
);wire	[ 4: 0]		data_rise	;	// 偶数位上升沿发送wire	[ 4: 0]		data_fall	;	// 奇数位下降沿发送reg		[ 4: 0]		data_rise_s	= 0;reg		[ 4: 0]		data_fall_s	= 0;reg		[ 2: 0]		cnt = 0;assign	data_rise = {data_in[8], data_in[6], data_in[4], data_in[2], data_in[0]};assign	data_fall = {data_in[9], data_in[7], data_in[5], data_in[3], data_in[1]};always @ (posedge clk_5x)begincnt	<=	(cnt[2] == 1'b1) ? 3'd0 : (cnt + 1'b1);data_rise_s	<=	(cnt[2] == 1'b1) ? data_rise : {1'b0, data_rise_s[4:1]};data_fall_s	<=	(cnt[2] == 1'b1) ? data_fall : {1'b0, data_fall_s[4:1]};end// 时钟取反的好处:源clk_5x上升沿数据传送过来,取反后ddio相当于在源clk_5x的下降沿位置进行数据采样,更稳定	
ddio_out	ddio_out_inst (.datain_h ( data_rise_s[0] ),.datain_l ( data_fall_s[0] ),.outclock ( ~clk_5x ),.dataout ( ser_p ));
// 对data_in进行取反,两根线传输
ddio_out	ddio_out_inst1 (.datain_h ( ~data_rise_s[0] ),.datain_l ( ~data_fall_s[0] ),.outclock ( ~clk_5x ),.dataout ( ser_n ));endmodule

hdmi_ctrl模块:
        hdmi_ctrl是采用TDMS原理实现的,需要将输入数据进行扩展编码、双沿发送差分信号,差分信号也就是一组数据和该组数据的反,比如有一组数据3’b010,那么它本身和3’b101就是一组差分信号,分成两个字模块实现,hdmi_ctrl内部就没有逻辑代码,全都是连线。

module hdmi_ctrl(input	wire	vga_clk,input	wire	clk_5x,input	wire	sys_rst_n,input	wire	hsync,input	wire	vsync,input	wire	rgb_valid,input	wire	[7:0]rgb_blue,input	wire	[7:0]rgb_green,input	wire	[7:0]rgb_red,output	wire	hdmi_r_p,output	wire	hdmi_r_n,output	wire	hdmi_g_p,output	wire	hdmi_g_n,output	wire	hdmi_b_p,output	wire	hdmi_b_n,output	wire	hdmi_clk_p,output	wire	hdmi_clk_n);wire	[9:0]	red;
wire	[9:0]	green;
wire	[9:0]	blue;encode encode_inst_r(.vga_clk(vga_clk)		,.sys_rst_n(sys_rst_n)	,.hsync(hsync)			,.vsync(vsync)			,.rgb_valid(rgb_valid)	,.data_in(rgb_red)		,.data_out(red)
);
encode encode_inst_g(.vga_clk(vga_clk)		,.sys_rst_n(sys_rst_n)	,.hsync(hsync)			,.vsync(vsync)			,.rgb_valid(rgb_valid)	,.data_in(rgb_green)		,.data_out(green)
);
encode encode_inst_b(.vga_clk(vga_clk)		,.sys_rst_n(sys_rst_n)	,.hsync(hsync)			,.vsync(vsync)			,.rgb_valid(rgb_valid)	,.data_in(rgb_blue)		,.data_out(blue)
);par_to_ser par_to_ser_inst_r(.clk_5x(clk_5x)	,.data_in(red)	,.ser_p(hdmi_r_p)	,.ser_n(hdmi_r_n)
);
par_to_ser par_to_ser_inst_g(.clk_5x(clk_5x)	,.data_in(green)	,.ser_p(hdmi_g_p)	,.ser_n(hdmi_g_n)
);
par_to_ser par_to_ser_inst_b(.clk_5x(clk_5x)	,.data_in(blue)	,.ser_p(hdmi_b_p)	,.ser_n(hdmi_b_n)
);
par_to_ser par_to_ser_inst_clk(.clk_5x(clk_5x)	,.data_in(10'b11111_00000)	,.ser_p(hdmi_clk_p)	,.ser_n(hdmi_clk_n)
);endmodule

顶层文件:

module hdmi_colorbar(input	wire	sys_clk,input	wire	sys_rst_n,output	wire	ddc_scl,output	wire	ddc_sda,output	wire	hdmi_r_p,output	wire	hdmi_r_n,output	wire	hdmi_g_p,output	wire	hdmi_g_n,output	wire	hdmi_b_p,output	wire	hdmi_b_n,output	wire	hdmi_clk_p,output	wire	hdmi_clk_n
);wire	vga_clk;
wire	clk_5x;
wire	locked;
wire	rst_n;
wire	[15:0]pix_data;wire	[9:0]pix_x;
wire	[9:0]pix_y;
wire	hsync;
wire	vsync;
wire	[15:0]vga_rgb;
wire	rgb_valid;assign	rst_n = (sys_rst_n & locked);
assign	ddc_scl = 1'b1;
assign	ddc_sda = 1'b1;clk_gen	clk_gen_inst (.areset ( ~sys_rst_n ),.inclk0 ( sys_clk ),.c0 ( vga_clk ),.c1 ( clk_5x ),.locked ( locked ));vga_pic vga_pic_inst
(.vga_clk(vga_clk),.sys_rst_n(rst_n),.pix_x(pix_x),.pix_y(pix_y),.pix_data(pix_data));vga_ctrl vga_ctrl_inst
(.vga_clk(vga_clk),.sys_rst_n(rst_n),.pix_data(pix_data),.pix_x(pix_x),.pix_y(pix_y),.hsync(hsync),.vsync(vsync),.vga_rgb(vga_rgb),.rgb_valid(rgb_valid)
);hdmi_ctrl hdmi_ctrl_inst(.vga_clk(vga_clk),.clk_5x(clk_5x),.sys_rst_n(rst_n),.hsync(hsync),.vsync(vsync),.rgb_valid(rgb_valid),.rgb_blue({vga_rgb[4:0],3'b0}),.rgb_green({vga_rgb[10:5],2'b0}),.rgb_red({vga_rgb[15:11],3'b0}),.hdmi_r_p(hdmi_r_p),.hdmi_r_n(hdmi_r_n),.hdmi_g_p(hdmi_g_p),.hdmi_g_n(hdmi_g_n),.hdmi_b_p(hdmi_b_p),.hdmi_b_n(hdmi_b_n),.hdmi_clk_p(hdmi_clk_p),.hdmi_clk_n(hdmi_clk_n));endmodule

testbench文件:

`timescale  1ns/1ns
module  tb_hdmi_colorbar();
//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//wire  define
wire            ddc_scl     ;
wire            ddc_sda     ;
wire			hdmi_r_p    ;
wire			hdmi_r_n    ;
wire			hdmi_g_p    ;
wire			hdmi_g_n    ;
wire			hdmi_b_p    ;
wire			hdmi_b_n    ;
wire			hdmi_clk_p  ;
wire			hdmi_clk_n  ;
//reg   define
reg             sys_clk     ;
reg             sys_rst_n   ;//********************************************************************//
//**************************** Clk And Rst ***************************//
//********************************************************************////sys_clk,sys_rst_n初始赋值
initialbeginsys_clk     =   1'b1;sys_rst_n   <=  1'b0;#30sys_rst_n   <=  1'b1;end//sys_clk:产生时钟
always  #10 sys_clk = ~sys_clk  ;//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************////------------- hdmi_colorbar_inst -------------hdmi_colorbar hdmi_colorbar_inst(.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.ddc_scl(ddc_scl),.ddc_sda(ddc_sda),.hdmi_r_p(hdmi_r_p),.hdmi_r_n(hdmi_r_n),.hdmi_g_p(hdmi_g_p),.hdmi_g_n(hdmi_g_n),.hdmi_b_p(hdmi_b_p),.hdmi_b_n(hdmi_b_n),.hdmi_clk_p(hdmi_clk_p),.hdmi_clk_n(hdmi_clk_n)
);endmodule

 

 


http://www.ppmy.cn/news/284180.html

相关文章

浪潮信息m5服务器,浪潮英信服务器NF8480M5

功能特性 产品定位 浪潮英信NF8480M5是一款采用英特尔至强可扩展计算平台技术的高端四路服务器&#xff0c;具备强大的计算能力、扩展能力和优秀的RAS特性&#xff0c;是内存数据库、ERP、CRM、商业智能分析系统、大型虚拟化应用和数据密集型应用程序的理想选择。 产品特性 超高…

浅谈HDMI 技术问题及解决方案

浅谈HDMI 技术问题及解决方案 HDMI&#xff08;高清晰度多媒体接口&#xff09;已经成为高清电视和消费电子行业的全球性连接标准。它是第一个也是唯一的数字接口可在单一接口结合无压缩高清视频&#xff0c;多声道环绕音频&#xff0c;和智能命令数据。对于客户&#xff0c;它…

浪潮服务器raid虚拟驱动,浪潮服务器RAID 卡驱动

【实例简介】 浪潮服务器的RAID卡驱动,下载直接可使用,欢迎下载使用 【实例截图】 【核心代码】 浪潮RAID卡驱动 └── SmartIOC2000_HBA1000_Drivers ├── Smartioc_hba1000_Linux_DRIVER_Release_B54013 │ ├── DRV-DKMS-ADAP │ │ ├── deb │ │ │ …

HDMI显示驱动设计及验证

项目场景&#xff1a; HDMI:High Definition Multimedia Interface(高清多媒体接口&#xff09;2004 VGA:Video Graphics Array(视频图形阵列&#xff09;1987 DVI:Digital Visual Interface(数字视频接口&#xff09;DVI_D、DVI_A、DVI_I HDMI 1.0 TMDS:Transition-minimized…

浪潮服务器安装windows操作系统找不到硬盘、识别不到阵列卡、找不到驱动器,免去各种驱动安装烦恼,浪潮懒人工程师福利

各种自研raid卡系统没驱动 不知看到此文的伙伴有没有浪潮服务器实施工程师&#xff0c;很多老铁第一次装服务器都会在这一步卡很久吧&#xff1f; 还有客户不会装机&#xff0c;整天电话让指导装系统&#xff0c;就很烦&#xff01;&#xff01; 熟练装机的老铁早已——将驱动…

HR SaaS一体化:Moka把这件事想明白了

Moka推出一体化的背后是对系统进行精细化投入。 数科星球原创 作者丨苑晶 编辑丨大兔 作为SaaS行业的细分赛道&#xff0c;过去几年中&#xff0c;HR SaaS受到了多方关注。对广大用户和投资者而言&#xff0c;该行业经历了从无到有、从陌生再到熟悉的过程。据数科星球&#x…

总结vue3 的一些知识点:MySQL 运算符

MySQL 运算符 本章节我们主要介绍 MySQL 的运算符及运算符的优先级。 MySQL 主要有以下几种运算符&#xff1a; 算术运算符比较运算符逻辑运算符位运算符 算术运算符 MySQL 支持的算术运算符包括: 运算符作用加法-减法*乘法/ 或 DIV除法% 或 MOD取余 在除法运算和模运算中…

鼠标的功能

鼠标的功能一般由侧键&#xff0c;左键&#xff0c;右键&#xff0c;滚轮组成&#xff0c;侧键用于网页前进和后退&#xff0c;左键单击是选择&#xff0c;左键双击是打开&#xff0c;右键单击是属性&#xff0c;滚轮单击是自动。