HDMI接口驱动设计验证

2024-08-26 23:44
文章标签 设计 接口 驱动 验证 hdmi

本文主要是介绍HDMI接口驱动设计验证,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

        HDMI接口,high definition multimedia interface 译为高清多媒体接口。相较于vga接口,  Vga接口成本低,结构简单,应用灵活,传输数据是模拟信号,模拟信号在传输时极易受到外界干扰,受到影响后容易产生数据信号畸变,导致输出图像出现问题,另外vga接口体积较大,不利于便携设备使用。针对缺点出现了dvi接口,DVI接口又分DVIA(只传输模拟信号),DVID(只传输数字信号),DVII(兼容模拟信号数字信号),传输协议使用TMDS(最小化传输差分信号),实现无损高清传输, DVI接口主要服务于pc机,对电视平板等只支持计算机领域的RGB数字信号,对于数字化的色差信号无法支持,体积大于VGA,也不适用于便携设备, Dvi接口只能传输图像,不能传输音频信号。之后出现HDMI接口,传输协议仍然使用TMDS编码技术,首先缩小了体积,抗干扰能力也增强,在20米之内实现无争议传输,大幅度优化了分辨率和兼容性,在同一根线缆上,可以实现数字信号与音频信号的同步传输,降低系统成本和复杂程度。

正文

一、HDMI接口驱动设计验证

        1.项目需求

基于FPGA设计HDMI接口驱动实现640*480@60Hz图像显示。

        2.技术介绍

        在hdmi的规格书中规定了4种接口类型,即 Hdmi a type接口, Hdmi  b type 接口, Hdmi c type接口, Hdmi d type接口。 B type只出现在规格书中,市面上未使用,市面上经常使用acd接口,a接口较多。三种接口都使用19片引脚,三种接口不同于线序,其中体积最小的是 D type接口。

         对hdmi引脚,有19片引脚总共分为4类, Tmds类:进行音频视频数据传输和一些辅助数据;DDC类:相当于一个iic接口,常用作读取显示器的一方EEPROM内的显示器规格型号数据;CEC类:预留通道;其他类的通道(14保留引脚,18电源引脚,19热拔插检测引脚)。

 

        TMDS最小化传输差分信号,系统包括发送端与接收端,发送端接收到24位数据后在场同步信号与行同步信号,还有时钟一起进行一个编码和数据并传转换,将表示RGB信号的数据通过TMDS三路线传输出去,接收端接收到数据后,对数据进程串并转换,将并行数据传输到显示器控制器,对图像进行显示。

        对于4条通道,3条RGB通道,1条时钟通道数据进行编码,第一步:将8bit的视频音频数据转化为最小传输直流均衡(保证信道中直流偏移为0,使信道中包含1与0的个数区域相同,添加数据位数,减少电磁干扰,提高可靠性)的10bit数据(编码过程),第二步:将10bit数据转化为差分信号,并进行串行传输。

        在进行第二步时可以调用ip核ALTDDIO_OUT

        “ALTDDIO_OUT” 主要用于实现双向数据输入输出。ALTDDIO_OUT是一个专用的 I/O 元件,允许用户在 FPGA 中实现同时具备输入和输出功能的引脚。它通常用于需要双向数据传输的应用场景。可以配置为输入或输出模式。这允许设备根据需要接收或发送数据。可以在内部时钟信号的控制下进行数据的发送和接收,确保数据传输的时序稳定。支持不同的输出驱动能力及编程选项,用户可以根据电路设计的需要选择最合适的驱动方式。在串行接口(如 I2C、SPI)中常用于双向数据流。在设计总线结构(如数据总线)时,用于共享数据路径。用于连接各种传感器和外部设备,进行数据交互。

        3.顶层架构

        4.端口描述

clk时钟信号
rst_n复位信号(低电平有效)
r_p红色差分数据
r_p红色差分数据
g_p绿色差分数据
g_n绿色差分数据
b_p蓝色差分数据
b_n蓝色差分数据
clk_p时钟差分数据
clk_n时钟差分数据
ddc_sclIIC数据线
ddc_sdaIIC数据线

二、代码验证

数据8bit数据转10bit数据并进行编码

module encode(//8bit数据转10bit数据并进行编码input 			clk		,input				rst_n		,input				en			,input				hs			,//行同步信号input				vs			,//场同步信号input[7:0]		in			,//8bit数据输入output reg[9:0]data		 //10bit数据输出);wire ctrl1;//条件判断标志信号
wire ctrl2;//条件判断标志信号
wire ctrl3;//条件判断标志信号reg [3:0]data1;//计算数据中1的个数
reg [7:0]reg_data;//数据打排,使计算与数据同周期
wire [8:0]q_m;//8bit数据转9bit数据数据寄存器(添加编码位)reg [4:0]cnt;// 
reg [3:0]data2;//计算9bit数据低8位中1的个数
reg [3:0]data3;//计算9bit数据低8位中0的个数
reg [8:0]q_m_reg;//9bit数据打排
reg		de_reg1;//使能信号打一排
reg 		de_reg2;//使能信号打两排
reg		hs_reg1;//行同步信号打一排
reg		hs_reg2;//行同步信号打两排
reg		vs_reg1;//场同步信号打一排
reg		vs_reg2;//场同步信号打两排always@(posedge clk,negedge rst_n)//计算1的个数
beginif(rst_n == 0)data1 <= 4'd0;elsedata1 <= data[0] + data[1] + data[2] + data[3] + data[4] + data[5] + data[6] + data[7];
endalways@(posedge clk,negedge rst_n)//输入数据进行打排
beginif(rst_n == 0)reg_data <= 8'd0;elsereg_data <=  in;
endassign ctrl1 = ((data1 > 4'd4)||((data1 == 4'd4)&&(reg_data[0] == 1'b0)))? 1'b1:1'b0;//标志信号赋值assign q_m[0] = reg_data[0];
assign q_m[1] = (ctrl1 == 1'b1)?(q_m[0]^~reg_data[1]):(q_m[0]^reg_data[1]);
assign q_m[2] = (ctrl1 == 1'b1)?(q_m[1]^~reg_data[2]):(q_m[1]^reg_data[2]);
assign q_m[3] = (ctrl1 == 1'b1)?(q_m[2]^~reg_data[3]):(q_m[2]^reg_data[3]);
assign q_m[4] = (ctrl1 == 1'b1)?(q_m[3]^~reg_data[4]):(q_m[3]^reg_data[4]);
assign q_m[5] = (ctrl1 == 1'b1)?(q_m[4]^~reg_data[5]):(q_m[4]^reg_data[5]);
assign q_m[6] = (ctrl1 == 1'b1)?(q_m[5]^~reg_data[6]):(q_m[5]^reg_data[6]);
assign q_m[7] = (ctrl1 == 1'b1)?(q_m[6]^~reg_data[7]):(q_m[6]^reg_data[7]);
assign q_m[8] = (ctrl1 == 1'b1)?1'b0:1'b1;
//8bit数据添加编码位,最高位表示数据进行异或/或操作always@(posedge clk,negedge rst_n)//计算9bit数据低8位中1的个数,计算9bit数据低8位中0的个数
beginif(rst_n == 0)begindata2 <= 4'd0;data3 <= 4'd0;endelsebegindata2 <= q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];			data3 <= 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		
endassign ctrl2 = ((cnt == 0 )||(data2 == data3))?1'b1:1'b0;//条件判断标志信号assign ctrl3 = (((cnt[4] == 1'b0)&&(data2 > data3))||((cnt[4] == 1'b0)&&(data2 < data3)))?1'b1:1'b0;//条件判断标志信号always@(posedge clk,negedge rst_n)//数据打排进行信号同步
beginif(rst_n == 0)beginq_m_reg <= 9'd0;de_reg1 <= 1'd0;de_reg2 <= 1'd0;hs_reg1 <= 1'd0;hs_reg2 <= 1'd0;vs_reg1 <= 1'd0;vs_reg2 <= 1'd0;		endelsebeginq_m_reg <= q_m;de_reg1 <= en;de_reg2 <= de_reg1;hs_reg1 <= hs;hs_reg2 <= hs_reg1;vs_reg1 <= vs;vs_reg2 <= vs_reg1;				end	
endalways@(posedge clk,negedge rst_n)//数据输出
beginif(rst_n == 0)begindata <= 10'd0;cnt <= 5'd0;endelsebeginif(de_reg2 == 1)beginif(ctrl2 == 1)begindata[9] = ~q_m_reg[8];data[8] = q_m_reg[8];data[7:0] = (q_m_reg[8]) ? q_m_reg[7:0]:(~q_m_reg[7:0]);cnt <= (q_m_reg[8]== 1'b0)? (cnt + data3 - data2):(cnt + data2 - data3);endelsebeginif(ctrl3 == 1)begindata[9] = 1'b1;data[8] = q_m_reg[8];data[7:0] = ~q_m_reg[7:0];cnt <= cnt + {q_m_reg[8],1'b0} + (data3 - data2);endelsebegindata[9] = 1'b0;data[8] = q_m_reg[8];data[7:0] = q_m_reg[7:0];cnt <= cnt - {~q_m_reg[8],1'b0} + (data2 - data3);endend				endelsebegincase({vs_reg2,hs_reg2})2'b00 : data <= 10'b0010_1010_11;2'b01 : data <= 10'b1101_0101_00;2'b10 : data <= 10'b0010_1010_10;default : data <= 10'b1101_0101_01;endcaseendend
endendmodule

单沿转双沿时钟

module par_yo_to_ser(input 			clk_5		,//单沿转双沿时钟(传入10bit数据就需要10倍原时钟,在IP核的参与下,省调一半的时钟信号)input[9:0] 		data		,output  		ser_p		,//差分信号output 		ser_n		 //差分信号
);wire [4:0]data_rist = {data[8],data[6],data[4],data[2],data[0]};//上升沿发送的数据
wire [4:0]data_fall = {data[9],data[7],data[5],data[3],data[1]};//下降沿发送的数据reg [4:0]data_rist_s = 0;	
reg [4:0]data_fall_s = 0;
reg [2:0]cnt = 0;always@(posedge clk_5)//数据移位(并行数据转为ip核需要的类串行数据)
begincnt 			<= (cnt[2] == 1'b1) ? 3'd0: (cnt + 1'b1) ;data_rist_s <= (cnt[2] == 1'b1) ? data_rist: data_rist_s[4:1] ;data_fall_s <= (cnt[2] == 1'b1) ? data_fall: data_fall_s[4:1] ;
endmy_ddio	my_ddio_inst (//单沿数据转双沿数据.datain_h ( data_rist_s[0] ),.datain_l ( data_fall_s[0] ),.outclock ( ~clk_5 ),//保证在数据稳定时进行传输.dataout ( ser_p )//输出双沿数据);my_ddio	my_ddio_inst2 (//单沿数据转双沿数据.datain_h ( ~data_rist_s[0] ),.datain_l ( ~data_fall_s[0] ),.outclock ( ~clk_5 ),//保证在数据稳定时进行传输.dataout ( ser_n )//输出双沿数据);endmodule

vga_ctrl显示驱动模块

module vga_ctrl(input    		clk		,input    		rst_n		,input[7:0]		in_rgb	,output			volid_en ,output   		vga_hs	,output   		vga_vs	,output[9:0]   	vga_h		,//坐标output[9:0]   	vga_v		,//坐标output[7:0]  	vga_rgb
);reg [9:0] cnt_hs;//列计数器
reg [9:0] cnt_vs;//行计数器
wire hs_en;//列有效显示区域
wire vs_en;//行有效显示区域
//wire volid_en;//有效显示区域parameter 	hs_sync = 10'd96	,//同步hs_bask = 10'd40	,//后沿hs_left = 10'd8	,//左边hs_vali = 10'd640	,//有效hs_righ = 10'd8	,//右边hs_fpon = 10'd8	,//前沿hs_tota = 10'd800	;//总共parameter 	vs_sync = 10'd2	,//同步   vs_bask = 10'd25	,//后沿	  vs_left = 10'd8	,//上边   vs_vali = 10'd480	,//有效 vs_righ = 10'd8	,//底边   vs_fpon = 10'd2	,//前沿   vs_tota = 10'd525	;//总共				always @(posedge clk,negedge rst_n)
beginif(rst_n == 0)cnt_hs <= 10'd0;elseif(cnt_hs < hs_tota - 10'd1)cnt_hs <= cnt_hs + 10'd1;elsecnt_hs <= 10'd0;
end always @(posedge clk,negedge rst_n)
beginif(rst_n == 0)cnt_vs <= 10'd0;elseif(cnt_hs ==  hs_tota - 10'd1)if(cnt_vs < vs_tota - 10'd1)cnt_vs <= cnt_vs + 10'd1;else cnt_vs <= 10'd0;elsecnt_vs <= cnt_vs;
end assign vga_hs = (cnt_hs < hs_sync)?1'b0:1'b1;//行同步信号赋值assign vga_h  = (volid_en == 1'b1)?(cnt_hs - (hs_sync + hs_bask + hs_left)):10'd0;//行坐标(Y)assign vga_vs = (cnt_vs < vs_sync)?1'b0:1'b1;//场同步信号赋值assign vga_v  = (volid_en == 1'b1)?(cnt_vs - (vs_sync + vs_bask + vs_left)):10'd0;//列坐标(X)assign hs_en = ((cnt_hs >= hs_sync + hs_bask + hs_left )&&(cnt_hs <= hs_sync + hs_bask + hs_left + hs_vali))?1'b1:1'b0;assign vs_en = ((cnt_vs >= vs_sync + vs_bask + vs_left )&&(cnt_vs <= vs_sync + vs_bask + vs_left + vs_vali))?1'b1:1'b0;assign volid_en = hs_en & vs_en;//显示区域assign vga_rgb = (volid_en == 1'b1)?in_rgb:8'd0;endmodule 

vga_data显示数据生成模块

module vga_data(input               clk     	,input               rst_n   	,input[9:0]				pix_x		,input[9:0]				pix_y		,output reg[7:0]		vga_rgb);parameter 	show_h = 10'd110,//定位点X坐标show_v = 10'd100;//定位点Y坐标parameter 	show_chan = 10'd256,//图片长度show_kuan = 10'd32;//图片宽度parameter 	show_1_rgb = 8'b000_000_00,//背景show_0_rgb = 8'b111_100_00;//图片颜色reg [255:0]	char	[31:0];
wire[9:0]	char_x;
wire[9:0]	char_y;assign char_x =((pix_x >= show_h)&&(pix_x < (show_h + show_chan)))&&((pix_y >= show_v)&&(pix_y <(show_v + show_kuan)))?(pix_x - show_h):10'h3ff;
assign char_y =((pix_x >= show_h)&&(pix_x < (show_h + show_chan)))&&((pix_y >= show_v)&&(pix_y <(show_v + show_kuan)))?(pix_y - show_v):10'h3ff;always@(posedge clk)
beginchar[0  ] <= 256'h0000000000000000000000000001000000200000000100000020000000010000; char[1  ] <= 256'h0020000000010000003FFFFFFFFF0000003FFFFFFFFF0000003FFFFFFFFF0000;char[2  ] <= 256'h003FFFFFFFFF0000003000180001000000300018000100000030001800010000;char[3  ] <= 256'h0030001800010000003000180000000000300018000000000030001800000000;char[4  ] <= 256'h003000180000000000300018000000000030003C000000000030007E00000000;char[5  ] <= 256'h003803FFE00000000038000000000000003C000000000000003E000000000000;char[6  ] <= 256'h003F8000000000000003C0000000000000006000000000000000000000000000;char[7  ] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;char[8  ] <= 256'h0000000000000000000000000001000000200000000100000020000000010000;char[9  ] <= 256'h0020000000010000003FFFFFFFFF0000003FFFFFFFFF0000003FFFFFFFFF0000;char[10 ] <= 256'h003FFFFFFFFF0000003000060001000000300006000100000030000600010000;char[11 ] <= 256'h0030000600010000003000060000000000300006000000000030000600000000;char[12 ] <= 256'h00300006000000000038000E000000000038000E00000000001C001C00000000;char[13 ] <= 256'h001E003C00000000000F80F800000000000FFFF8000000000007FFF000000000;char[14 ] <= 256'h0001FFC00000000000007F000000000000000000000000000000000000000000;char[15 ] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;char[16 ] <= 256'h00000000000000000000000000000000000000FFE000000000000FFFFE000000;char[17 ] <= 256'h00007FFFFF8000000000FFFFFFE000000003FE001FF800000007E00000FC0000;char[18 ] <= 256'h000F0000003C0000001E0000000E0000001C0000000600000038000000070000;char[19 ] <= 256'h0030000000030000003000000003000000300000000300000030000100030000;char[20 ] <= 256'h00300001000300000018000100060000001C0001800E0000001E0001FFFC0000;char[21 ] <= 256'h001F8001FFF80000001FF001FFF8000000003801FFF800000000000180000000;char[22 ] <= 256'h0000000100000000000000010000000000000001000000000000000000000000;char[23 ] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;char[24 ] <= 256'h00000000000100000000000000010000000000000003000000000000001F0000;char[25 ] <= 256'h0000000001FF0000000000001FE3000000000001FC0100000000001FC0010000;char[26 ] <= 256'h000001FCC000000000001FC0C00000000001FC00C0000000001FC000C0000000;char[27 ] <= 256'h003E0000C0000000007F0000C0000000007FF000C0000000003FFF00C0000000;char[28 ] <= 256'h0001FFF0C000000000001FFFC0000000000001FFFC0100000000001FFFC10000;char[29 ] <= 256'h00000001FFFF0000000000000FFF00000000000000FF000000000000000F0000;char[30 ] <= 256'h0000000000030000000000000001000000000000000100000000000000000000;char[31 ] <= 256'h0000000000000000000000000000000000000000000000000000000000000000;
endalways @(posedge clk,negedge rst_n)
beginif(rst_n == 0)vga_rgb <= show_1_rgb;elseif(	((pix_x >= show_h - 1'b1)&&(pix_x < (show_h + show_chan - 1'b1)))&&	((pix_y >= show_v )&&(pix_y <(show_v + show_kuan)))&&	(char[char_y][10'd255 - char_x] == 1'b1))vga_rgb  <= show_0_rgb;elsevga_rgb <= show_1_rgb;
endendmodule 

HDMI数据整合

module hdmi_ctrl(input					clk		,input					rst_n		,input	[7:0]			r_data	,//红色分量input [7:0]			g_data	,//绿色分量input [7:0]			b_data	,//蓝色分量input					en			,input					hs			,//行同步信号input 				vs			,//场同步信号input					clk_5x	,//5倍时钟output				r_p		,//红色差分数据output				r_n		,//红色差分数据output				g_p		,//绿色差分数据output				g_n		,//绿色差分数据output				b_p		,//蓝色差分数据output				b_n		,//蓝色差分数据output				clk_p		,//时钟差分数据output				clk_n		 //时钟差分数据
);wire[9:0] r_data_in;
wire[9:0] g_data_in;
wire[9:0] b_data_in;encode encode1(//8bit数据转10bit数据并进行编码.clk		(clk		),.rst_n	(rst_n	),.en		(en		),.hs		(hs		),//行同步信号.vs		(vs		),//场同步信号.in		(r_data	),//8bit数据输入.data		(r_data_in) //10bit数据输出);par_yo_to_ser par_yo_to_ser1(.clk_5	(clk_5x),//单沿转双沿时钟(传入10bit数据就需要10倍原时钟,在IP核的参与下,省调一半的时钟信号).data		(r_data_in),.ser_p	(r_p),//差分信号.ser_n	(r_n) //差分信号
);encode encode2(//8bit数据转10bit数据并进行编码.clk		(clk		),.rst_n	(rst_n	),.en		(en		),.hs		(hs		),//行同步信号.vs		(vs		),//场同步信号.in		(g_data	),//8bit数据输入.data		(g_data_in) //10bit数据输出);par_yo_to_ser par_yo_to_ser2(.clk_5	(clk_5x),//单沿转双沿时钟(传入10bit数据就需要10倍原时钟,在IP核的参与下,省调一半的时钟信号).data		(g_data_in),.ser_p	(g_p),//差分信号.ser_n	(g_n) //差分信号
);encode encode3(//8bit数据转10bit数据并进行编码.clk		(clk		),.rst_n	(rst_n	),.en		(en		),.hs		(hs		),//行同步信号.vs		(vs		),//场同步信号.in		(b_data	),//8bit数据输入.data		(b_data_in) //10bit数据输出);par_yo_to_ser par_yo_to_ser3(.clk_5	(clk_5x),//单沿转双沿时钟(传入10bit数据就需要10倍原时钟,在IP核的参与下,省调一半的时钟信号).data		(b_data_in),.ser_p	(b_p),//差分信号.ser_n	(b_n) //差分信号
);par_yo_to_ser par_yo_to_ser4(.clk_5	(clk_5x),//单沿转双沿时钟(传入10bit数据就需要10倍原时钟,在IP核的参与下,省调一半的时钟信号).data		(10'b11111_00000),.ser_p	(clk_p),//差分信号.ser_n	(clk_n) //差分信号
);endmodule

顶层模块

module hdmi_driver(input 				clk		,input					rst_n		,output				r_p		,//红色差分数据output				r_n		,//红色差分数据output				g_p		,//绿色差分数据output				g_n		,//绿色差分数据output				b_p		,//蓝色差分数据output				b_n		,//蓝色差分数据output				clk_p		,//时钟差分数据output				clk_n		, //时钟差分数据output 				ddc_scl	,output				ddc_sda   
);wire clk_1;
wire clK_5;wire clk_en;
wire volid_en;wire[9:0] vga_h;
wire[9:0] vga_v;
wire[7:0] vga_rgb_in;
wire[7:0] vga_rgb_out;wire vga_hs;
wire vga_vs;assign ddc_scl	= 1'b1;
assign ddc_sda = 1'b1;  my_pll	my_pll_inst (//锁相环调用.areset 	( ~rst_n ),.inclk0 	( clk 	),.c0 		( clk_1 	),.c1 		( clK_5 	),.locked 	( clk_en )
);vga_data vga_data(.clk     (clk_1		),.rst_n   (clk_en		),.pix_x	 (vga_h		),.pix_y	 (vga_v		),.vga_rgb (vga_rgb_in)   );vga_ctrl vga_ctrl(.clk	 	(clk_1		),.rst_n	(clk_en		),.in_rgb	(vga_rgb_in	),.volid_en(volid_en   ),.vga_hs	(vga_hs     ),.vga_vs	(vga_vs     ),.vga_h	(vga_h		),//坐标.vga_v	(vga_v		),//坐标.vga_rgb (vga_rgb_out)//332色彩分量
);hdmi_ctrl hdmi_ctrl(.clk		(clk_1),.rst_n	(clk_en),.r_data	({vga_rgb_out[7:5],5'b0}),//红色分量.g_data	({vga_rgb_out[4:2],5'b0}),//绿色分量.b_data	({vga_rgb_out[1:0],6'b0}),//蓝色分量.en		(volid_en),.hs		(vga_hs),//行同步信号.vs		(vga_vs),//场同步信号.clk_5x	(clK_5),//5倍时钟.r_p		(r_p	),//红色差分数据.r_n		(r_n	),//红色差分数据.g_p		(g_p	),//绿色差分数据.g_n		(g_n	),//绿色差分数据.b_p		(b_p	),//蓝色差分数据.b_n		(b_n	),//蓝色差分数据.clk_p	(clk_p),//时钟差分数据.clk_n	(clk_n) //时钟差分数据
);endmodule

仿真代码

`timescale 1ns/1ps
module hdmi_driver_tb();reg  clk		;
reg  rst_n	;wire r_p		;
wire r_n		;
wire g_p		;
wire g_n		;
wire b_p		;
wire b_n		;
wire clk_p	;
wire clk_n	;wire ddc_scl;	
wire ddc_sda;hdmi_driver hdmi_driver(.clk		(clk		),.rst_n	(rst_n	),.r_p		(r_p		),//红色差分数据.r_n		(r_n		),//红色差分数据.g_p		(g_p		),//绿色差分数据.g_n		(g_n		),//绿色差分数据.b_p		(b_p		),//蓝色差分数据.b_n		(b_n		),//蓝色差分数据.clk_p	(clk_p	),//时钟差分数据.clk_n	(clk_n	), //时钟差分数据.ddc_scl	(ddc_scl	),.ddc_sda (ddc_sda )	 
);initial clk = 1'b1;
always #10 clk = ~clk;initial beginrst_n = 0;#20rst_n =1;#200000$stop;
endendmodule

三、仿真验证

        由下图可得,数据输出正常,显示数据应为黑色背景下,屏幕上显示“FPGA”字符,数据生成模块和显示驱动模块调用之前基于VGA的字符显示实验。

由下图可以看出,数据在cnt = 0 将数据进行载入并按位分组,在之后cnt其他时刻进行移位输入至ddio ip核中进行双沿数据转换,通过ser_p,与ser_n可以看出,数据在时钟上升沿或下降沿都可进行输出,完成了在基于基础显示时钟频率的10倍时钟上进行数据传输,在差分的方式下数据更稳定。

参考资料

VGA接口驱动设计验证

HDMI

这篇关于HDMI接口驱动设计验证的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110027

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

Java 后端接口入参 - 联合前端VUE 使用AES完成入参出参加密解密

加密效果: 解密后的数据就是正常数据: 后端:使用的是spring-cloud框架,在gateway模块进行操作 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.0-jre</version></dependency> 编写一个AES加密

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal

easyui 验证下拉菜单select

validatebox.js中添加以下方法: selectRequired: {validator: function (value) {if (value == "" || value.indexOf('请选择') >= 0 || value.indexOf('全部') >= 0) {return false;}else {return true;}},message: '该下拉框为必选项'}