软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用XILINX A7/K7/Z7/ZU/KU系列FPGA
登录米联客(MILIANKE)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!
1 概述
米联客开发板上集成的HDMI输入芯片方案采用ADV7611实现,对于没有集成HDMI输入芯片的开发板可以采用FEP扩展卡实现HDMI输入,本文介绍HDMI输入方案ADV7611的实现,对于通过FEP子卡实现的方案相关的配套课程会做出介绍。本文采用的ADV7611可以实现1080P60fps视频输出,默认我们输出的格式为RGB888。本文要实现的功能也很简单,只要完成HDMI视频输入后再通过前面一节课的HDMI输入IP把视频信号正确输出就可以。
本文内容也有一个重要的阶段就是我们会利用前面一些编写好的IP模块应用于新的方案中,比如前面的I2C控制器IP和HDMI输出IP,这也是我们米联客编写代码注重代码可重复利用,注重构架的优势。我们以后会把一些常用IP模块做一个列表说明方便大家使用。
2 ADV7611参数介绍
ADV7611采用先进的CMOS工艺制造,提供64引脚、10 mm × 10 mm LQFP_EP表贴封装,符合RoHS标准,是一款高质量、单输入HDMI®接收器,内置HDMI兼容型接收器,支持HDMI 1.4a规定的所有强制性3D电视格式, 和最高UXGA 60 Hz、8位的分辨率。它集成一个CEC控制器,支持能力发现和控制(CDC)特性。并且提供汽车级、专业级(无HDCP)和工业级三种版本,工作温度范围为−40 ℃至+85 ℃。
具有一个音频输出端口,用于输出从HDMI流提取的音频数据。HDMI接收器具有高级静音控制器,可消除音频输出中的外来声频噪声。
可以访问下列音频格式:
1、来自I2S 串行器的音频流(两个音频通道)
2、来自S/PDIF串行器的音频流(两个未压缩通道或N个压缩通道,例如AC3)
3、DST音频流
HDMI端口具有专用的5 V检测和热插拔(Hot Plug™)置位引脚。该HDMI接收器还集成一个均衡器,用于确保与长电缆的接口具有鲁棒的工作性能。
3 硬件电路分析
硬件接口和子卡模块请阅读"附录 1"
配套工程的 FPGA PIN 脚定义路径为 fpga_prj/uisrc/04_pin/ fpga_pin.xdc。
4 ADV7611配置说明
ADV7611是一款高质量、单输入HDMI®接收器,内置HDMI兼容型接收器,支持HDMI 1.4a规定的所有强制性3D电视格式,和最高UXGA 60 Hz、8位的分辨率。
4.1 I2C从机地址
同时,ADV7611还包含几个IIC地址可配置的功能寄存器,它们的配置方式如下图所示。
可以看到,CEC、EDID、CP等功能寄存器的IIC地址都可以通过对应的IO寄存器来配置它们的默认地址。这里,可以使用上面给出的默认的地址。比如以EDID的IIC地址为例,只需要在IO寄存器地址0x98,子寄存器地址为0xFA的寄存器写入数值0x6C,那么EDID的IIC地址就配置为了0x6c。
4.2 主模式和视频制式
设置主模式和选择视频标准是配置ADV7611时最基本的设置。adv7611有两种主要模式HDMI-component and HDMI-graphic modes 。也就是hdmi组件和hdmi图形两种模式。通过寄存器PRIM_MODE[3:0]来配置。
在HDMI模式下,ADV7611可以通过DVI/HDMI接收器前端接收和解码HDMI或DVI数据。来自HDMI接收器的视频数据被传递到组件处理器CP模块,而音频数据在音频接口上可用。可以通过选择hdmi组件或hdmi图形主模式来启用其中一种模式。
这里需要说明的是,HDMI接收器可以解码和处理任何应用的HDMI流,而不关心视频分辨率。然而,许多主要模式和视频标准组合可以用来定义如何处理传输到DPP和CP块的视频数据流。这允许一些系统可能需要的自由运行特性和数据抽取模式。
所谓的free run自由运行模式就是在没有接受到正常HDMI信号或者没有接入信号时,可以自动生成一个HDMI视频流,给到后级系统用于测试或者其他应用。比如,可以设置一个蓝屏的信号。这在实际使用中很有用处。
这里主模式和视频制式设置很大的作用其实就是设置这个free run所执行的模式和视频标准。
PRIM_MODE[3:0]寄存器地址为0x98,0x01[3:0],功能描述如下图:
VID_STD[5:0][3:0]寄存器地址为0x98,0x00[5:0],该寄存器为6bits,它与PRIM_MODE[3:0]配合使用,设置如下图:
V_FREQ[2:0]寄存器地址为0x98,0x01[6:4],用于设置帧率,功能描述如下图:
4.3 像素输出
从上面两个表可以看到,ADV7611具有非常灵活的像素端口,可以各种格式配置以适应下游ic。
OP_FORMAT_SEL对应的寄存器地址为0x98,0x03 。如下图所示:
可以看到,默认情况下,P23-P16引脚对应的RGB模式的R分量输出,P15-P8引脚对应的RGB模式的G分量输出,P7-P0引脚对应的RGB模式的B分量输出。在444的YCBCR模式下,P23-P16引脚对应的为V分量输出,P15-P8引脚对应的Y分量输出,P7-P0引脚对应的U分量输出。在422的YCBCR模式下,P23-P16引脚无对应分量输出,P15-P8引脚对应的Y分量输出,P7-P0引脚对应的CBCR分量输出。同样的,可以通过配置寄存器将引脚和分量自由绑定。
CP CSC配置为自动模式后,CSC矩阵、agc增益值、偏移量都能够通过下面的几个寄存器自动配置。
INP_COLOR_SPACE[3:0]寄存器地址为0x98,0x02[7:4],对应功能如下:
注意这个寄存器设置的是输入视频的色彩空间。通常我们不做特别的变换,使用默认值1111即可。
RGB_OUT寄存器地址为0x98,0x02[1],对应的功能如下:
可以看到,为0时是YCBCR的色彩空间输出,为1时是RGB的色彩空间输出。这里YPBPR是ycbcr是在模拟分量上的叫法,读者可以认为它们是一样的。
ALT_GAMMA寄存器地址0x98 ,0x02[3],对应的功能如下:
可以看到,该寄存器主要是做YUV601和yuv709之间的转换,默认为0不做转换,为1则输入为YUV601时转换为YUV709,输入为YUV709时转换为YUV601。
可以看到,这几个寄存器对应的地址都是0x98,0x02。它们的配置方式如下:
上面说的都是数据总线接口,还离不开时钟和同步信号,这里的时钟叫做LLC,行锁定时钟,其实就是常说的像素时钟。
OP_SWAP_CB_CR寄存器地址为0x98,0x05[0],功能描述如下图:
同时,时钟引脚LLC,同步输出引脚VS/FIELD/ALSB、HS、DE的极性也可以通过对应寄存器设置。
ADV7611通过LLC引脚提供的像素时钟的极性可以使用INV_LLC_POL位进行反转。注意,这种反转只影响LLC输出引脚。其他输出引脚不受INV_LLC_POL影响。
为了满足处理ADV7611输出数据的下游设备的设置和保持时间预期,可能需要改变LLC时钟输出的极性。无论传输的视频数据是什么类型,INV_LLC_POL都适用。这其实相当于调整了时钟相位180度。
INV_LLC_POL寄存器地址为0x98, 0x06[0],功能描述如下图:
INV_HS_POL寄存器地址为0x98, 0x06[1],功能描述如下图:
INV_VS_POL寄存器地址为0x98, 0x06[2],功能描述如下图:
INV_F_POL寄存器地址为0x98, 0x06[3],功能描述如下图:
其实,到了这里我们就可以将adv7611使用起来了,可以看到,最关键的就是配置IO寄存器的前面几个寄存器。如下图将输出配置为24bits SDR 444 RGB输出。
那么,如果我需要的输出为24bits SDR 444 YCBCR输出怎么设置?只需要将RGB_OUT寄存器(地址为0x98,0x02[1])置为1即可。
同样的,调整对应寄存器,可以修改为16bits SDR 422 YCBCR输出。
4.1 uicfg7611.v
always@(posedge I_clk ) begin if(rst_cnt[7] == 1'b0)begin //复位初始化寄存器 reg_index<= 9'd0; iic_req <= 1'b0; wr_data <= 32'd0; O_cfg_done <= 1'b0; TS_S <= 2'd0; end else begin case(TS_S) 0:if(reg_index == REG_SIZE) //如果配置完成 O_cfg_done <= 1'b1; //设置 O_cfg_done标准 else if(O_cfg_done == 1'b0) //如果未配置完成 TS_S <= 2'd1; //下一个状态 1:if(!iic_busy)begin //当总线非忙,才可以操作I2C控制器 iic_req <= 1'b1; //请求操作I2C控制器 wr_data[7 :0] <= REG_DATA[23:16]; //器件地址 wr_data[15 :8] <= REG_DATA[15: 8]; //寄存器地址 wr_data[23:16] <= REG_DATA[7 : 0]; //寄存器数据 TS_S <= 2'd2; //下一个状态 end 2:if(iic_busy)begin iic_req <= 1'b0; //重置 iic_req =0 TS_S <= 2'd3; //下一个状态 end 3:if(!iic_busy)begin //当总线非忙,才可以操作I2C控制器 reg_index<= reg_index + 1'b1;//寄存器索引加1 TS_S <= 2'd0;//回到初始状态 end endcase end end |
/*******************************uicfg7611*************************** --1.ADV7611芯片配置驱动程序 *********************************************************************/
`timescale 1ns / 1ns
module uicfg7611# ( parameter CLK_DIV = 16'd999 ) ( input I_clk, //系统时钟输入 input I_rst_n, //系统复位输入 output O_adv_scl, //I2C总线,SCL时钟 inout IO_adv_sda, //I2C总线,SDA数据 output reg O_cfg_done //配置完成 );
//内部计数器产生一个延迟复位 reg[7:0] rst_cnt =0; always@(posedge I_clk or negedge I_rst_n) if(I_rst_n == 1'b0) //复位初始化寄存器 rst_cnt<= 8'd0; else if(rst_cnt[7] == 1'b0) rst_cnt <= rst_cnt + 1'b1; else rst_cnt <= rst_cnt;
reg iic_req;//请求操作I2C控制器信号 wire ic_busy; //I2C控制器忙信号 reg [31:0] wr_data; //写数据寄存器 reg [1 :0] TS_S = 2'd0; //状态机寄存器 reg [8 :0] reg_index; //寄存索引 wire [23:0] REG_DATA; //寄存器数据 wire [8 :0] REG_SIZE; //寄存器数量
always@(posedge I_clk ) begin if(rst_cnt[7] == 1'b0)begin //复位初始化寄存器 reg_index<= 9'd0; iic_req <= 1'b0; wr_data <= 32'd0; O_cfg_done <= 1'b0; TS_S <= 2'd0; end else begin case(TS_S) 0:if(reg_index == REG_SIZE) //如果配置完成 O_cfg_done <= 1'b1; //设置 O_cfg_done标准 else if(O_cfg_done == 1'b0) //如果未配置完成 TS_S <= 2'd1; //下一个状态 1:if(!iic_busy)begin //当总线非忙,才可以操作I2C控制器 iic_req <= 1'b1; //请求操作I2C控制器 wr_data[7 :0] <= REG_DATA[23:16]; //器件地址 wr_data[15 :8] <= REG_DATA[15: 8]; //寄存器地址 wr_data[23:16] <= REG_DATA[7 : 0]; //寄存器数据 TS_S <= 2'd2; //下一个状态 end 2:if(iic_busy)begin iic_req <= 1'b0; //重置 iic_req =0 TS_S <= 2'd3; //下一个状态 end 3:if(!iic_busy)begin //当总线非忙,才可以操作I2C控制器 reg_index<= reg_index + 1'b1;//寄存器索引加1 TS_S <= 2'd0;//回到初始状态 end endcase end end
//例化I2C控制模块 uii2c# ( .WMEN_LEN(4), //最大支持一次写入4BYTE(包含器件地址) .RMEN_LEN(1), //最大支持一次读出1BYTE .CLK_DIV(CLK_DIV) //100KHZ I2C总线时钟 ) uii2c_inst ( .I_clk(I_clk),//系统时钟 .I_rstn(rst_cnt[7]),//系统复位 .O_iic_scl(O_adv_scl),//I2C SCL总线时钟 .IO_iic_sda(IO_adv_sda),//I2C SDA数据总线 .I_wr_data(wr_data),//写数据寄存器 .I_wr_cnt(8'd3),//需要写的数据BYTES .O_rd_data(), //读数据寄存器 .I_rd_cnt(8'd0),//需要读的数据BYTES .I_iic_mode(1'b0),//读模式设置 .I_iic_req(iic_req),//I2C控制器请求 .O_iic_busy(iic_busy)//I2C控制器忙 );
//例化ADV7611的寄存器配置表 ui7611reg ui7611reg_inst ( .O_REG_SIZE(REG_SIZE), //寄存器数量 .I_REG_INDEX(reg_index),//寄存索引 .O_REG_DATA(REG_DATA) //寄存器数据 );
endmodule
|
4.2 ui7611reg.v
/*******************************ui7611reg*************************** --1.ADV7611芯片配置寄存器配置表 *********************************************************************/
module ui7611reg ( input [8 :0] I_REG_INDEX, output reg [31:0] O_REG_DATA, output [8 :0] O_REG_SIZE );
assign O_REG_SIZE = 9'd182;
//----------------------------------------------------------------- ///////////////////// Config Data REG ////////////////////////// always@(*) case(I_REG_INDEX) //write Data Index 0 : O_REG_DATA = {8'h98,8'hF4, 8'h80}; //配置,CEC SLAVE ADDRESS 1 : O_REG_DATA = {8'h98,8'hF5, 8'h7c}; //配置,INFOFRAME SLAVE ADDRESS 2 : O_REG_DATA = {8'h98,8'hF8, 8'h4c}; //配置,DPLL SLAVE ADDRESS 3 : O_REG_DATA = {8'h98,8'hF9, 8'h64}; //配置,KSV SLAVE ADDRESS 4 : O_REG_DATA = {8'h98,8'hFA, 8'h6c}; //配置,EDID SLAVE ADDRESS 5 : O_REG_DATA = {8'h98,8'hFB, 8'h68}; //配置,HDMI SLAVE ADDRESS 6 : O_REG_DATA = {8'h98,8'hFD, 8'h44}; //配置,CP SLAVE ADDRESS 7 : O_REG_DATA = {8'h98,8'h01, 8'h05}; //[3:0]寄存器的设置HDMI工作模式为HDMI-component mode,[6:4]设置分辨率60fps 8 : O_REG_DATA = {8'h98,8'h00, 8'h13}; //设置视频输入输出set VID_STD input video HD1X1 output 1280x720 9 : O_REG_DATA = {8'h98,8'h02, 8'hF7}; //[3]=0默认不转换,[1]=1RGB色彩空间,[7:4]=1111,使用默认色彩空间 10 : O_REG_DATA = {8'h98,8'h03, 8'h40}; //OP_FORMAT_SEL=0X40 24bits 4:4:4 SDR MODE 设置SDR模式,P23~P0 输出 11 : O_REG_DATA = {8'h98,8'h04, 8'h62}; //011 - P[23:16] V/R, P[15:8] Y/G, P[7:0] U/CrCb/B ; XTAL = 28.868 MHz 12 : O_REG_DATA = {8'h98,8'h05, 8'h28}; //OP_SWAP_CB_CR寄存器[0]=0,CrCb顺序按照OP_FORMAT_SET寄存器设置来 13 : O_REG_DATA = {8'h98,8'h06, 8'ha7}; //INV_LLC_POL寄存器[0],不调整时钟数据输出相位,INV_HS_POL寄存器[1]HS极性调整,INV_VS_POL寄存器[2]极性调整,INV_F_POL寄存器[3],FIELD/DE极性调整 14 : O_REG_DATA = {8'h98,8'h0b, 8'h44}; //Powers up CP and digital sections of HDMI block; Powers up XTAL buffer to the digital core 15 : O_REG_DATA = {8'h98,8'h0C, 8'h42}; //Chip is operational,Disables power save mode,Powers up the clock to the CP core,Powers up the pads of the digital output pins 16 : O_REG_DATA = {8'h98,8'h15, 8'h80}; //Disable Tristate of Pins 17 : O_REG_DATA = {8'h98,8'h19, 8'h8a}; //LLC DLL phase 18 : O_REG_DATA = {8'h98,8'h33, 8'h40}; //LLC DLL enable 19 : O_REG_DATA = {8'h98,8'h14, 8'h3f}; // 20 : O_REG_DATA = {8'h44,8'hba, 8'h01}; //Set HDMI FreeRun when the TMDS clock is not detected on the selected HDMI port 21 : O_REG_DATA = {8'h44,8'h7c, 8'h01}; // 22 : O_REG_DATA = {8'h64,8'h40, 8'h81}; //Disable HDCP 1.1 features 23 : O_REG_DATA = {8'h68,8'h9b, 8'h03}; //ADI recommanded setting 24 : O_REG_DATA = {8'h68,8'hc1, 8'h01}; //ADI recommanded setting 25 : O_REG_DATA = {8'h68,8'hc2, 8'h01}; //ADI recommanded setting 26 : O_REG_DATA = {8'h68,8'hc3, 8'h01}; //ADI recommanded setting 27 : O_REG_DATA = {8'h68,8'hc4, 8'h01}; //ADI recommanded setting 28 : O_REG_DATA = {8'h68,8'hc5, 8'h01}; //ADI recommanded setting 29 : O_REG_DATA = {8'h68,8'hc6, 8'h01}; //ADI recommanded setting 30 : O_REG_DATA = {8'h68,8'hc7, 8'h01}; //ADI recommanded setting 31 : O_REG_DATA = {8'h68,8'hc8, 8'h01}; //ADI recommanded setting 32 : O_REG_DATA = {8'h68,8'hc9, 8'h01}; //ADI recommanded settin g 33 : O_REG_DATA = {8'h68,8'hca, 8'h01}; //ADI recommanded setting 34 : O_REG_DATA = {8'h68,8'hcb, 8'h01}; //ADI recommanded setting 35 : O_REG_DATA = {8'h68,8'hcc, 8'h01}; //ADI recommanded setting 36 : O_REG_DATA = {8'h68,8'h00, 8'h00}; //Set HDMI input Port A 37 : O_REG_DATA = {8'h68,8'h83, 8'hfe}; //Enable clock terminator for port A 38 : O_REG_DATA = {8'h68,8'h6f, 8'h08}; //ADI recommended setting 39 : O_REG_DATA = {8'h68,8'h85, 8'h1f}; //ADI recommended setting 40 : O_REG_DATA = {8'h68,8'h87, 8'h70}; //ADI recommended setting 41 : O_REG_DATA = {8'h68,8'h8d, 8'h04}; //LF gain equalizer settings for dynamic mode range 1 42 : O_REG_DATA = {8'h68,8'h8e, 8'h1e}; //HF gain equalizer settings for dynamic mode range 1 43 : O_REG_DATA = {8'h68,8'h1a, 8'h8a}; //unmute audio 44 : O_REG_DATA = {8'h68,8'h57, 8'hda}; //ADI recommended setting 45 : O_REG_DATA = {8'h68,8'h58, 8'h01}; //ADI recommended setting 46 : O_REG_DATA = {8'h68,8'h75, 8'h10}; // DDC drive strength 47 : O_REG_DATA = {8'h68,8'h6c ,8'ha3}; //enable manual HPA 48 : O_REG_DATA = {8'h98,8'h20 ,8'h70}; //HPD low 49 : O_REG_DATA = {8'h64,8'h74 ,8'h00}; //disable internal EDID
//edid par 50 : O_REG_DATA = {8'h6c,8'd0 , 8'h00}; 51 : O_REG_DATA = {8'h6c,8'd1 , 8'hFF}; 52 : O_REG_DATA = {8'h6c,8'd2 , 8'hFF}; 53 : O_REG_DATA = {8'h6c,8'd3 , 8'hFF}; 54 : O_REG_DATA = {8'h6c,8'd4 , 8'hFF}; 55 : O_REG_DATA = {8'h6c,8'd5 , 8'hFF}; 56 : O_REG_DATA = {8'h6c,8'd6 , 8'hFF}; 57 : O_REG_DATA = {8'h6c,8'd7 , 8'h00}; 58 : O_REG_DATA = {8'h6c,8'd8 , 8'h20}; 59 : O_REG_DATA = {8'h6c,8'd9 , 8'hA3}; 60 : O_REG_DATA = {8'h6c,8'd10 , 8'h29}; 61 : O_REG_DATA = {8'h6c,8'd11 , 8'h00}; 62 : O_REG_DATA = {8'h6c,8'd12 , 8'h01}; 63 : O_REG_DATA = {8'h6c,8'd13 , 8'h00}; 64 : O_REG_DATA = {8'h6c,8'd14 , 8'h00}; 65 : O_REG_DATA = {8'h6c,8'd15 , 8'h00}; 66 : O_REG_DATA = {8'h6c,8'd16 , 8'h23}; 67 : O_REG_DATA = {8'h6c,8'd17 , 8'h12}; 68 : O_REG_DATA = {8'h6c,8'd18 , 8'h01}; 69 : O_REG_DATA = {8'h6c,8'd19 , 8'h03}; 70 : O_REG_DATA = {8'h6c,8'd20 , 8'h80}; 71 : O_REG_DATA = {8'h6c,8'd21 , 8'h73}; 72 : O_REG_DATA = {8'h6c,8'd22 , 8'h41}; 73 : O_REG_DATA = {8'h6c,8'd23 , 8'h78}; 74 : O_REG_DATA = {8'h6c,8'd24 , 8'h0A}; 75 : O_REG_DATA = {8'h6c,8'd25 , 8'hF3}; 76 : O_REG_DATA = {8'h6c,8'd26 , 8'h30}; 77 : O_REG_DATA = {8'h6c,8'd27 , 8'hA7}; 78 : O_REG_DATA = {8'h6c,8'd28 , 8'h54}; 79 : O_REG_DATA = {8'h6c,8'd29 , 8'h42}; 80 : O_REG_DATA = {8'h6c,8'd30 , 8'hAA}; 81 : O_REG_DATA = {8'h6c,8'd31 , 8'h26}; 82 : O_REG_DATA = {8'h6c,8'd32 , 8'h0F}; 83 : O_REG_DATA = {8'h6c,8'd33 , 8'h50}; 84 : O_REG_DATA = {8'h6c,8'd34 , 8'h54}; 85 : O_REG_DATA = {8'h6c,8'd35 , 8'h25}; 86 : O_REG_DATA = {8'h6c,8'd36 , 8'hC8}; 87 : O_REG_DATA = {8'h6c,8'd37 , 8'h00}; 88 : O_REG_DATA = {8'h6c,8'd38 , 8'h61}; 89 : O_REG_DATA = {8'h6c,8'd39 , 8'h4F}; 90 : O_REG_DATA = {8'h6c,8'd40 , 8'h01}; 91 : O_REG_DATA = {8'h6c,8'd41 , 8'h01}; 92 : O_REG_DATA = {8'h6c,8'd42 , 8'h01}; 93 : O_REG_DATA = {8'h6c,8'd43 , 8'h01}; 94 : O_REG_DATA = {8'h6c,8'd44 , 8'h01}; 95 : O_REG_DATA = {8'h6c,8'd45 , 8'h01}; 96 : O_REG_DATA = {8'h6c,8'd46 , 8'h01}; 97 : O_REG_DATA = {8'h6c,8'd47 , 8'h01}; 98 : O_REG_DATA = {8'h6c,8'd48 , 8'h01}; 99 : O_REG_DATA = {8'h6c,8'd49 , 8'h01}; 100 : O_REG_DATA = {8'h6c,8'd50 , 8'h01}; 101 : O_REG_DATA = {8'h6c,8'd51 , 8'h01}; 102 : O_REG_DATA = {8'h6c,8'd52 , 8'h01}; 103 : O_REG_DATA = {8'h6c,8'd53 , 8'h01}; 104 : O_REG_DATA = {8'h6c,8'd54 , 8'h02}; 105 : O_REG_DATA = {8'h6c,8'd55 , 8'h3A}; 106 : O_REG_DATA = {8'h6c,8'd56 , 8'h80}; 107 : O_REG_DATA = {8'h6c,8'd57 , 8'h18}; 108 : O_REG_DATA = {8'h6c,8'd58 , 8'h71}; 109 : O_REG_DATA = {8'h6c,8'd59 , 8'h38}; 110 : O_REG_DATA = {8'h6c,8'd60 , 8'h2D}; 111 : O_REG_DATA = {8'h6c,8'd61 , 8'h40}; 112 : O_REG_DATA = {8'h6c,8'd62 , 8'h58}; 113 : O_REG_DATA = {8'h6c,8'd63 , 8'h2C}; 114 : O_REG_DATA = {8'h6c,8'd64 , 8'h45}; 115 : O_REG_DATA = {8'h6c,8'd65 , 8'h00}; 116 : O_REG_DATA = {8'h6c,8'd66 , 8'h80}; 117 : O_REG_DATA = {8'h6c,8'd67 , 8'h88}; 118 : O_REG_DATA = {8'h6c,8'd68 , 8'h42}; 119 : O_REG_DATA = {8'h6c,8'd69 , 8'h00}; 120 : O_REG_DATA = {8'h6c,8'd70 , 8'h00}; 121 : O_REG_DATA = {8'h6c,8'd71 , 8'h1E}; 122 : O_REG_DATA = {8'h6c,8'd72 , 8'h8C}; 123 : O_REG_DATA = {8'h6c,8'd73 , 8'h0A}; 124 : O_REG_DATA = {8'h6c,8'd74 , 8'hD0}; 125 : O_REG_DATA = {8'h6c,8'd75 , 8'h8A}; 126 : O_REG_DATA = {8'h6c,8'd76 , 8'h20}; 127 : O_REG_DATA = {8'h6c,8'd77 , 8'hE0}; 128 : O_REG_DATA = {8'h6c,8'd78 , 8'h2D}; 129 : O_REG_DATA = {8'h6c,8'd79 , 8'h10}; 130 : O_REG_DATA = {8'h6c,8'd80 , 8'h10}; 131 : O_REG_DATA = {8'h6c,8'd81 , 8'h3E}; 132 : O_REG_DATA = {8'h6c,8'd82 , 8'h96}; 133 : O_REG_DATA = {8'h6c,8'd83 , 8'h00}; 134 : O_REG_DATA = {8'h6c,8'd84 , 8'h80}; 135 : O_REG_DATA = {8'h6c,8'd85 , 8'h88}; 136 : O_REG_DATA = {8'h6c,8'd86 , 8'h42}; 137 : O_REG_DATA = {8'h6c,8'd87 , 8'h00}; 138 : O_REG_DATA = {8'h6c,8'd88 , 8'h00}; 139 : O_REG_DATA = {8'h6c,8'd89 , 8'h18}; 140 : O_REG_DATA = {8'h6c,8'd90 , 8'h00}; 141 : O_REG_DATA = {8'h6c,8'd91 , 8'h00}; 142 : O_REG_DATA = {8'h6c,8'd92 , 8'h00}; 143 : O_REG_DATA = {8'h6c,8'd93 , 8'hFC}; 144 : O_REG_DATA = {8'h6c,8'd94 , 8'h00}; 145 : O_REG_DATA = {8'h6c,8'd95 , 8'h48}; 146 : O_REG_DATA = {8'h6c,8'd96 , 8'h44}; 147 : O_REG_DATA = {8'h6c,8'd97 , 8'h4D}; 148 : O_REG_DATA = {8'h6c,8'd98 , 8'h49}; 149 : O_REG_DATA = {8'h6c,8'd99 , 8'h20}; 150 : O_REG_DATA = {8'h6c,8'd100, 8'h20}; 151 : O_REG_DATA = {8'h6c,8'd101, 8'h20}; 152 : O_REG_DATA = {8'h6c,8'd102, 8'h20}; 153 : O_REG_DATA = {8'h6c,8'd103, 8'h0A}; 154 : O_REG_DATA = {8'h6c,8'd104, 8'h20}; 155 : O_REG_DATA = {8'h6c,8'd105, 8'h20}; 156 : O_REG_DATA = {8'h6c,8'd106, 8'h20}; 157 : O_REG_DATA = {8'h6c,8'd107, 8'h20}; 158 : O_REG_DATA = {8'h6c,8'd108, 8'h00}; 159 : O_REG_DATA = {8'h6c,8'd109, 8'h00}; 160 : O_REG_DATA = {8'h6c,8'd110, 8'h00}; 161 : O_REG_DATA = {8'h6c,8'd111, 8'hFD}; 162 : O_REG_DATA = {8'h6c,8'd112, 8'h00}; 163 : O_REG_DATA = {8'h6c,8'd113, 8'h32}; 164 : O_REG_DATA = {8'h6c,8'd114, 8'h55}; 165 : O_REG_DATA = {8'h6c,8'd115, 8'h1F}; 166 : O_REG_DATA = {8'h6c,8'd116, 8'h45}; 167 : O_REG_DATA = {8'h6c,8'd117, 8'h0F}; 168 : O_REG_DATA = {8'h6c,8'd118, 8'h00}; 169 : O_REG_DATA = {8'h6c,8'd119, 8'h0A}; 170 : O_REG_DATA = {8'h6c,8'd120, 8'h20}; 171 : O_REG_DATA = {8'h6c,8'd121, 8'h20}; 172 : O_REG_DATA = {8'h6c,8'd122, 8'h20}; 173 : O_REG_DATA = {8'h6c,8'd123, 8'h20}; 174 : O_REG_DATA = {8'h6c,8'd124, 8'h20}; 175 : O_REG_DATA = {8'h6c,8'd125, 8'h20}; 176 : O_REG_DATA = {8'h6c,8'd126, 8'h01}; 177 : O_REG_DATA = {8'h6c,8'd127, 8'h24}; 178 : O_REG_DATA = {8'h64,8'h74 , 8'h01};// enable internal EDID 179 : O_REG_DATA = {8'h98,8'h20 , 8'hf0};// HPD high 180 : O_REG_DATA = {8'h68,8'h6c , 8'ha2};// disable manual HPA 181 : O_REG_DATA = {8'h98,8'hf4 , 8'h00}; default:O_REG_DATA =0; endcase
endmodule |
5 hdmi_in_test.v
/*************HDMI 视频采集测试************* --通过配置ADV7611工作于RGB模式,利用HDMI 输出IP 环路输出视频 *********************************************************************/ `timescale 1ns / 1ns //仿真时间刻度/精度
module hdmi_in_test ( input I_sysclk, //HDMI ADV7611视频输入 output O_adv7611_rst, //ADV7611 复位 inout IO_adv7611_sda, //ADV7611 I2C 数据总线 output O_adv7611_scl, //ADV7611 I2C 地址总线 input I_adv7611_hs, //ADV7611 I2C HS同步信号 input I_adv7611_vs, //ADV7611 I2C VS同步信号 input I_adv7611_de, //ADV7611 I2C de数据有效信号 input I_adv7611_pclk, //ADV7611 时钟输入 input [23:0]I_adv7611_rgb,//ADV7611 数据输入
//HDMI输出 output O_hdmi_tx_clk_p, //HDMI 时钟差分信号P端 output O_hdmi_tx_clk_n, //HDMI 时钟差分信号N端 output [2:0]O_hdmi_tx_p, //HDMI 数据差分信号P端 output [2:0]O_hdmi_tx_n //HDMI 数据差分信号N端
);
assign O_adv7611_rst = 1'b1; //ADV7611 复位
wire cfg_done; //ADV7611配置完成信号 wire locked ; // PLL lock 信号 wire pclkx1,pclkx5; //时钟信号
//MMCM/PLL时钟管理IP 输出 pclkx1和pclkx5以及locked信号 clk_wiz_0 clk_wiz_inst(.clk_out1(pclkx1),.clk_out2(pclkx5),.locked(locked), .clk_in1(I_adv7611_pclk));
//例化HDMI输出IP,把TPG产生的测试图像经过HDMI输出 uihdmitx # ( .FAMILY("7FAMILY") //选择芯片所支持的系列"7FAMILY" "UFAMILY" ) uihdmitx_inst ( .I_rstn(cfg_done&&locked),//复位 .I_hs(I_adv7611_hs), //hs信号 .I_vs(I_adv7611_vs), //vs信号 .I_de(I_adv7611_de), //de信号 .I_rgb(I_adv7611_rgb), //RGB数据 .I_pclkx1(pclkx1), //像素时钟 .I_pclkx2_5(1'b0), //2.5倍像素时钟,只有UFAMILY需要 .I_pclkx5(pclkx5), //5倍像素时钟 .O_hdmi_tx_clk_p(O_hdmi_tx_clk_p),//HDMI时钟输出P端 .O_hdmi_tx_clk_n(O_hdmi_tx_clk_n),//HDMI时钟输出N端 .O_hdmi_tx_p(O_hdmi_tx_p), //HDMI输出数据P端 .O_hdmi_tx_n(O_hdmi_tx_n) //HDMI输出数据N端 );
//例化ADV7611 驱动 uicfg7611# ( .CLK_DIV(50_000_000/50_000 -1 )//设置I2C时钟50K,时钟过高可能导致配置失败 ) uicfg7611_inst ( .I_clk(I_sysclk),//系统时输入 .I_rst_n(1'b1), //复位 .O_adv_scl(O_adv7611_scl),//ADV7611 I2C 数据总线 .IO_adv_sda(IO_adv7611_sda),//ADV7611 I2C 地址总线 .O_cfg_done(cfg_done) );
endmodule
|
6 硬件接线
(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)
1、开发板HDMI IN 接口连接输入源:测试使用PC机做输入源,HDMI线连接开发板HDMI IN 接口。
2、开发板HDMI OUT接口连接输出源:测试使用显示器做输出源,HDMI线连接开发板HDMI OUT 接口。