[X]关闭

[米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-23 RGB转HDMI显示方案

文档创建者:FPGA课程
浏览次数:444
最后更新:2024-07-31
文档课程分类-安路-DR1
安路-DR1: FPSOC-DR1-FPGA部分 » 2_FPGA实验篇(仅旗舰) » 1-FPGA基础入门实验
本帖最后由 FPGA课程 于 2024-7-31 19:49 编辑

软件版本:Anlogic -TD5.9.1-DR1_ES1.1
操作系统:WIN10 64bit
硬件平台:适用安路(Anlogic)FPGA
实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板
板卡获取平台:https://milianke.tmall.com/
登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

1概述
本实验通过FPGA内部资源实现HDMI协议,使用HDMI直接驱动HDMI接口显示器,这是成本非常低廉的一种方案,可以实现HDMI输出1080P@60fps的视频图像。本实验需要用到前面课程中的VTC模块产生视频时序,以及TPG模块产生测试图形,只使用 HDMI 接口来显示图像,没有传输音频。关于VTC视频时序参数的设置,读者可以阅读前面VTC相关的课程内容。
在完成本实验前,请确保已经完成前面的实验,包括已经掌握以下能力:
1:完成了TD软件安装
2:完成了modelsim安装以及TD库的编译
3:掌握了TD仿真环境的设置
4:掌握了modesim通过do文件启动仿真
1.1 HDMI简介
HDMI,全称为(High Definition Multimedia Interface)高清多媒体接口,能够同时无压缩的传输视频和音频信号,无需在信号传送前进行数/模或者模/数转换,因此有较高质量的影音信号。HDMI兼容DVI,通过转换接口可以让以其中一种接口标准发送的视频数据直接接入另一种接口标准的LCD显示器上显示。
HDMI接口种类:
2504661-20240731190247297-1694916449.jpg
种类
引脚数
规格
应用场景
A类(Type A)
19
4.45mm×13.9mm
主要用于蓝光播放器、笔记本电脑、液晶电视、投影机等
B类(Type B)
29
4.45mm×21.2mm
主要用于专业的影音设备上
C类(Type C)
19
2.42mm×10.42mm
主要用于便携式设备上,如数码相机、便携式播放机等设备
D类(Type D)
19
2.8mm×6.4mm
主要用于小型的移动设备,如手机、平板电脑等
E类(Type E)
/
/
主要用于汽车设备上,包含锁定片和外壳来防止接口松动、灰尘湿气进入


HDMI版本:
2504661-20240731190248314-436719046.jpg
2504661-20240731190248928-1880894412.jpg
1.1.1 HDMI _TypeA接口引脚图
HDMI有A,B,C,D,E五种引脚类型,目前市面中比较常见的接口是Type A:
2504661-20240731190249453-1398229548.jpg 2504661-20240731190250424-1152669617.jpg
1-9:TMDS数据传输实际上用到的引脚,分为0,1,2三组差分线,分别传输R、G、B三种信号,为了加强抗干扰能力,每对差分线之间还加入了一根屏蔽线,比如数据2+与数据2-之间加入数据2屏蔽线,1、2、3信号线组成1个数据传输通道
10-12:TMDS时钟信号,即像素时钟。
13:CEC(consumer electronic control)HDMI的扩展功能,一种消费电子兼容的传输协议,可以控制视听设备。
14:保留引脚,也可以作为CEC引脚
15-16:I2C引脚,用于DDC(Display Data Channel)传输,进行EDID(相当于一个信息表,会存放显示器的制造商、型号、分辨率等信号)的交互,显示设备和主机可以相互读取。
17:接地引脚
18:5v AC引脚
19:热拔插引脚,用于监测HDMI设备有没有存在。
1.1.2传输协议
HDMI传输的编码格式中要包括视频数据、控制数据和数据包(数据包中包括音频数据和附加信息数据,例如纠错码等)。HDMI传输由4组TMDS通道组成,TMDS channel 0传输B信号,H信号和V信号也在该通道,TMDS channel 1传输G信号,TMDS channel 2传输R信号,R和G通道的多余位置用来传输音频信号。TMDS channel clock传输视频信号的pixel频率,即像素时钟。传输的数据经过TMDS进行编码及并串转换,将编码的数据通过高速串行接口传送,接收端对编码后的数据进行解码,还原成原始的输入信号,最终将数据输入到显示器接口上。
2504661-20240731190251050-1626352402.jpg
TMDS原理:
HDMI采用TMDS (Time Minimized Differential Signal) 最小化传输差分信号传输技术,是美国Silicon Image 公司开发的一项高速数据传输技术,将视频、音频、控制信号进行编码并串转换后发送。TMDS是一种微分信号机制,采用的是差分传动方式。利用2个引脚间电压差来传送信号,由两脚间电压正负极性和大小决定传送"0"还是"1"。采用2根线来传输信号,一根线上传输原来的信号,另一根线上传输与原来信号相反的信号,接收端就可以通过让一根线上的信号减去另一根线上的信号的方式来屏蔽电磁干扰,从而得到正确的信号。
2504661-20240731190251616-999318891.jpg
2504661-20240731190252475-1801854557.jpg
TMDS传输通道编码解码示意图
TMDS 模块包含三个相同的编码和发送模块,每个TMDS通道都能传送10bit的数据流。每个发送模块包含8 位的像素数据,2 个控制信号,一个四位数据信号。
每个数据通道的8bit的数据在source经过TMDS编码(异或、异或非等)后得到10bit数据,前8为数据由原始信号经运算后获得,第9位为编码位,指示运算的方式,第10位为直流平衡,使TMDS发送的"0"、"1"数量保持基本一致,让传输的数据趋于直流平衡,减少信号对传输线的电磁干扰,提高信号传输的可靠性。10bit数据经过并串转换器serializer后通过TMDS数据通道串行输出,并转串过程所生成的串行数据速率是实际像素时钟速率的10 倍;在sink端先进行复原成并行的10bit的数据,再通过TMDS 解码得到8bit的源数据。此外,HDMI视频是stream式的传输,不涉及packet式的传输。
(1)使用channel0的D[1:0]传输HSYNC, VSYNC,占用2bit,控制信号被编码成10位传输,00、01、10、11编码后分别是10'b1101010100,10'b0010101011,10'b0101010100,和10'b1010101011。
(2)Preamble控制信息,图中的CTLx,可用来表示后面传输的是data island还是video data。通过channel1和2的D[1:0]传输,占用4bit,控制信号被编码成10位传输。
     CTL0
CTL1
CTL2
CTL3
date period type
1
0
0
0
video data
1
0
1
0
data island


(3)Video Data,视频数据,数据格式为RGB888,Channel0[7:0]用于传输B,Channel1[7:0]用于传输G,Channel2[7:0]用于传输R。经过TMDS最小转换编码后成为10位数据,在对应的通道上传输。
(4)Data Island,数据岛,如音频数据包。数据岛以包数据的格式传输的,由包头和包体构成。包头用于指定包体的类型,包体是具体数据岛周期中的音频信号,通过3个channel的D[3:0]传输,Channel0[1:0]用于传输HSYNC, VSYNC,Channel0[3:2]用于传输Data Island Header(包头数据),Channel1[3:0]与Channel2[3:0]用于传输Data Island Content(包内数据),经过TMDS最小转换编码后成为10位数据,在对应的通道上传输。
在HDMI 传输视频图像的过程中,数据通道上传输的是编码后的有效像素,消隐期内传输的是编码后的控制字符,还可以用于传输音频等数据,本课我们只考虑传输视频的情况。
  • 硬件电路分析
    下图为单向的HDMI输出接口连线示意图,差分数据线和时钟线通过RCLAMP0524P低电容TVS二极管阵列后接到FPGA管脚上,并上拉到3.3V。RCLAMP0524低电容TVS(Transient Voltage Suppressor)二极管阵列,四路静电保护器件,用于保护高速数据接口,避免电路受到静电放电(ESD)和其他瞬态电压事件的影响。CEC引脚依旧没有使用,此处接到3.3V。比较复杂的是IIC、SDA的电平转换电路,由于FPGA的引脚电压一般小于等于3.3V,而HDMI的引脚需要5V的电压来驱动,所以这里通过NMOS管的方式对电平进行转换。SDA是双向通信的信号线,所以无论是FPGA控制外设,还是外设控制FPGA,都可以进行5V、3.3V的电平转换。由于这里HDMI只作为输出,所以热插拔检测引脚就只作为输入,输入信号经过分压连接到FPGA管脚上来检测HOT PLUG是否连接上。
    2504661-20240731190253343-859789422.jpg
    2 程序设计2.1系统框图
    2504661-20240731190253868-1724335064.jpg
    2.2 PLL时钟设置
    对于PLL的设置需要产生1:5的时钟
    2504661-20240731190254733-1934481984.jpg
    2504661-20240731190255758-702614710.jpg
    2.3 hdmi_tx IP使用介绍
    本IP由安路提供。HDMI(High Definition Multimedia Interface)是一种全数字化影像和声音发送接口,可以发送未压缩的音频及视频信号。HDMI可用于机顶盒、DVD播放机、个人电脑、投影仪与电视等设备,HDMI发送音频和视频信号采用同一条线材,大大简化系统线路的安装难度。
    本HDMI Transmitter设计支持的功能如下:

  • 最高支持1080p60显示分辨率。
  • 支持两路音频输入。
  • 支持RGB444和YUV444。
  • 支持内部视频测试源。
  • 支持EDID读取。
2.3.1 hdmi_tx IP系统框图
2504661-20240731190256460-2053618590.jpg
HDMI Transmitter设计包含以下三部分:
HDMI_TX_controller:HDMI的协议层,用于将音频数据、视频数据以及配置数据打包编码,输出TMDS编码数据。
HDMI_TX_PHY:HDMI的物理层,用于将协议层传输的TMDS编码数据转换为串行数据并发送出去。
EDID_Receiver:读取HDMI接收端的EDID数据。
2.3.2 HDMI IP时钟架构
HDMI Transmitter工作需要两个时钟,像素时钟pixel_clk和串行发送时钟serial_clk。两个时钟都是通过PLL生成,其中serial_clk的频率是pixel_clk频率的五倍。 2504661-20240731190257042-819620541.jpg
2.3.3 HDMI IP视频接口时序
视频接口时序图如图2-9所示。
2504661-20240731190257593-54532936.jpg
图 09 视频接口时序
I_video_in_user信号是帧起始信号,为一个单时钟周期信号,在第一行第一个有效数据拉高。I_video_in_valid是数据有效信号,I_video_in_last是行结束信号,在一行数据的结尾拉高。O_video_in_ready是接收端准备信号,为高表示可以写入数据,在I_video_in_last为高之后会拉低。
为了让IP支持RGB格式的视频输入,米联客对安路的HDMI IP输入时序稍作修改,修改后可以支持RGB输入时序,或者stream接口时序,修改后的IP 顶层源码如下:
  1. /********************************************************************
  2. 本IP由上海安路科技提供,米联客根据自己使用习惯接口部分增加了RGB输入接口方式,
  3. 核心功能描述如下:
  4. HDMI Transmitter工作需要两个时钟,像素时钟pixel_clk和串行发送时钟serial_clk。两个时钟都是通过PLL生成,其中serial_clk的频率是pixel_clk频率的五倍。
  5. HDMI Transmitter的三个接口EDID_Read_interface、Video_interface和Audio_interface都是工作在pixel_clk时钟域下,因此用户逻辑需要使用pixel_clk来生成音视频数据。
  6. HDMI Transmitter的pixel_clk频率和serial_clk频率需要根据显示分辨率进行计算。以1080p60的分辨率为例,有效分辨率为1920x1080,在计算频率的时候需要加上消隐区,
  7. 图像总的长宽为2200x1125,每秒60帧,因此像素时钟的频率为:
  8. F_pixel=Htotal×Vtotal×FrameRate
  9. F_pixel=2200×1125×60=148500000Hz=148.5MHz
  10. 串行发送时钟serial_clk频率为像素时钟频率的五倍,因此串行发送时钟频率为:
  11. F_serial=5×F_pixel=5×148.5MHz=742.5MHz

  12. 1-最高支持1080p60显示分辨率。
  13. 2-支持两路音频输入。
  14. 3-支持RGB444和YUV444。
  15. 4-支持内部视频测试源。
  16. 5-支持EDID读取。
  17. *********************************************************************/
  18. `timescale 1ns / 1ns //仿真时间刻度/精度

  19. module hdmi_tx#(
  20.     parameter H_ActiveSize  =   1980, //视频时间参数,行视频信号,一行有效(需要显示的部分)像素所占的时钟数,一个时钟对应一个有效像素
  21.     parameter H_SyncStart   =   1920+88, //视频时间参数,行同步开始,即多少时钟数后开始产生行同步信号
  22.     parameter H_SyncEnd     =   1920+88+44, //视频时间参数,行同步结束,即多少时钟数后停止产生行同步信号,之后就是行有效数据部分
  23.     parameter H_FrameSize   =   1920+88+44+148,  //视频时间参数,行视频信号,一行视频信号总计占用的时钟数

  24.     parameter V_ActiveSize  =   1080,  //视频时间参数,场视频信号,一帧图像所占用的有效(需要显示的部分)行数量,通常说的视频分辨率即H_ActiveSize*V_ActiveSize
  25.     parameter V_SyncStart   =   1080+4, //视频时间参数,场同步开始,即多少行数后开始产生场同步信号
  26.     parameter V_SyncEnd     =   1080+4+5,//视频时间参数,场同步结束,多少行后停止产生长同步信号
  27.     parameter V_FrameSize   =   1080+4+5+36,  //视频时间参数,场视频信号,一帧视频信号总计占用的行数量      
  28.    
  29.     parameter VIDEO_TPG         = "Enable",//"Enable”:使能测试视频源,外部视频输入无效;"Disable”:禁用测试视频源
  30.     parameter VIDEO_FORMAT      = "RGB444",//“RGB444”:外部输入视频格式为RGB;“YUV444”:外部输入视频格式为YUV
  31.     parameter VIDEO_VIC         = 16,//VIDEO_VIC参数用于设定HDMI辅助视频信息包中的VIC参数,具体看APUG058

  32.     parameter AUDIO_CTS         = 148500,//音频时钟参数“CTS”
  33.     parameter AUDIO_N           = 6144,  //音频时钟参数“N”
  34.     parameter AUDIO_SAMPLE_RATE = "48K", //音频采样率

  35.     parameter IIC_SCL_DIV       = 125   //EDID IIC时钟分频系数
  36. )(
  37.    
  38.     input wire       I_pixel_clk, //像素时钟
  39.     input wire       I_serial_clk,//串行发送时钟
  40.     input wire       I_rst, //异步复位信号,高电平有效

  41.     input wire       I_edid_read_trig,//EDID读触发信号
  42.     output wire      O_edid_read_valid,//EDID读有效信号
  43.     output wire[7:0] O_edid_read_data,//EDID读数据
  44.    
  45. ///**********************  video rgb input  *****************************  
  46.     input wire       I_video_rgb_enable,  //是否使能RGB输入接口,设置1使能,否则采用stream video时序接口
  47.     input wire       I_video_in_de, //RGB 输入de有效
  48.     input wire       I_video_in_vs, //RGB 输入VS 帧同步
  49. ///**********************  video stream input  ***************************
  50.     input wire       I_video_in_user,  //视频输入帧起始信号
  51.     input wire       I_video_in_valid, //视频输入有效信号
  52.     input wire       I_video_in_last,  //视频输入行结束信号
  53.     output wire      O_video_in_ready, //视频输入ready信号
  54.     input wire[23:0] I_video_in_data,  //视频输入数据
  55. ///*********************  audio stream input  ***************************
  56.     input wire       I_audio_valid,     //音频输入有效信号
  57.     input wire[23:0] I_audio_left_data, //音频左声道数据
  58.     input wire[23:0] I_audio_right_data,//音频左声道数据

  59.     output wire      O_edid_iic_scl,    //EDID IIC时钟信号
  60.     inout wire       IO_edid_iic_sda,   //EDID IIC数据信号

  61.     output           O_hdmi_clk_p, //HDMI输出时钟P端
  62.     output    [2:0]  O_hdmi_tx_p,  //HDMI输出数据P端

  63.     output wire      O_tmds_ch0_p, //HDMI数据通道0
  64.     output wire      O_tmds_ch1_p, //HDMI数据通道1
  65.     output wire      O_tmds_ch2_p, //HDMI数据通道2
  66.     output wire      O_tmds_clk_p  //HDMI时钟通道
  67. );

  68. //重新计算视频信号参数,以符合安路IP参数
  69.     localparam HTOTAL            = H_FrameSize;  //一行总长度,包括行消隐和行有效,单位为时钟个数
  70.     localparam HSA               = H_SyncEnd   - H_SyncStart;//行同步脉冲宽度,单位为时钟个数
  71.     localparam HFP               = H_SyncStart - H_ActiveSize;//行显示前沿,单位为时钟个数
  72.     localparam HBP               = H_FrameSize - H_SyncEnd;//行显示后沿,单位为时钟个数
  73.     localparam HACTIVE           = H_ActiveSize;//一行有效显示长度,单位为时钟个数
  74.    
  75.     localparam VTOTAL            = V_FrameSize;//总列数,包括场消隐和场有效部分,单位为图像行数
  76.     localparam VSA               = V_SyncEnd - V_SyncStart;//场同步脉冲宽度,单位为图像行数
  77.     localparam VFP               = V_SyncStart - V_ActiveSize;//场显示前沿,单位为图像行数
  78.     localparam VBP               = V_FrameSize - V_SyncEnd;//场显示后沿,单位为图像行数
  79.     localparam VACTIVE           = V_ActiveSize;//有效列数,单位为图像行数

  80. //**********************  video stream input  ***************************
  81. //如果是输入RGB时序,那么转为stream时序,否则仅对信号打一个节拍
  82.     reg       I_video_in_de_r1;
  83.     reg       I_video_in_vs_r1;
  84.     reg       I_video_in_user_r1,I_video_in_user_r2;
  85.     reg       I_video_in_valid_r1,I_video_in_valid_r2;
  86.     reg       I_video_in_last_r2;
  87.     reg[23:0] I_video_in_data_r1,I_video_in_data_r2;
  88.     reg       O_video_in_ready_r;
  89.     reg       vs_start;
  90.   
  91.     always @(posedge I_pixel_clk)begin
  92.         I_video_in_de_r1 <= I_video_in_de;
  93.         I_video_in_vs_r1 <= I_video_in_vs;
  94.     end
  95.       
  96.     always @(posedge I_pixel_clk or posedge I_rst )begin
  97.         if(I_rst)begin
  98.             I_video_in_last_r2  <= 1'b0;
  99.             I_video_in_valid_r1 <= 1'b0;
  100.             I_video_in_data_r1  <= 24'd0;
  101.             I_video_in_user_r1  <= 1'b0;
  102.             I_video_in_valid_r2 <= 1'b0;
  103.             I_video_in_data_r2  <= 24'd0;
  104.             I_video_in_user_r2  <= 1'b0;
  105.         end   
  106.         else if(I_video_rgb_enable == 1'b1)begin
  107.             I_video_in_last_r2  <= ~I_video_in_de & I_video_in_de_r1; //产生stream video last 延迟于数据输入2拍
  108.             I_video_in_valid_r1 <= I_video_in_de;//I_video_in_valid延迟1拍
  109.             I_video_in_data_r1  <= I_video_in_data;//I_video_in_data延迟1拍
  110.             I_video_in_user_r1  <= ~I_video_in_user_r1 & vs_start & I_video_in_de;//I_video_in_user延迟1拍
  111.             
  112.             I_video_in_valid_r2 <= I_video_in_valid_r1;//I_video_in_valid对输入信号延迟2拍,以和I_video_in_last_r2信号配套同步
  113.             I_video_in_data_r2  <= I_video_in_data_r1; //I_video_in_data 对输入信号延迟2拍,以和I_video_in_last_r2信号配套同步
  114.             I_video_in_user_r2  <= I_video_in_user_r1; //I_video_in_user 对输入信号延迟2拍,以和I_video_in_last_r2信号配套同步
  115.         end     
  116.         else begin
  117.             I_video_in_last_r2  <= I_video_in_last; //I_video_in_last对输入信号直接寄存1次
  118.             I_video_in_valid_r2 <= I_video_in_valid;//I_video_in_valid对输入信号直接寄存1次
  119.             I_video_in_data_r2  <= I_video_in_data;//I_video_in_data对输入信号直接寄存1次
  120.             I_video_in_user_r2  <= I_video_in_user;//I_video_in_user对输入信号直接寄存1次      
  121.         end
  122.     end
  123.    
  124.     always @(posedge I_pixel_clk or posedge I_rst )begin
  125.         if(I_rst)
  126.             vs_start <= 1'b0;
  127.         else if(I_video_in_user_r1)//清除VS帧同步
  128.             vs_start <= 1'b0;
  129.         else if(I_video_in_vs && I_video_in_vs_r1==1'b0)//当I_video_in_vs发生上升沿跳变代表一帧开始
  130.             vs_start <= 1'b1;
  131.     end         
  132.             
  133.       
  134.     wire[9:0]   S_ch0_tmds_code_data;               
  135.     wire[9:0]   S_ch1_tmds_code_data;               
  136.     wire[9:0]   S_ch2_tmds_code_data;               
  137.     wire[9:0]   S_clk_tmds_code_data;

  138. //音频部分
  139.     hdmi_edid_wrapper #(
  140.         .IIC_SCL_DIV ( IIC_SCL_DIV )
  141.     ) u_hdmi_edid_wrapper(
  142.         .I_clk             ( I_pixel_clk       ),
  143.         .I_rst             ( I_rst             ),

  144.         .I_edid_read_trig  ( I_edid_read_trig  ),
  145.         .O_edid_read_valid ( O_edid_read_valid ),
  146.         .O_edid_read_data  ( O_edid_read_data  ),

  147.         .O_iic_scl         ( O_edid_iic_scl    ),
  148.         .IO_iic_sda        ( IO_edid_iic_sda   )
  149.     );

  150. //HDMI IP
  151.     hdmi_tx_controller_wrapper #(
  152.         .HTOTAL               ( HTOTAL            ),
  153.         .HSA                  ( HSA               ),
  154.         .HFP                  ( HFP               ),
  155.         .HBP                  ( HBP               ),
  156.         .HACTIVE              ( HACTIVE           ),
  157.         .VTOTAL               ( VTOTAL            ),
  158.         .VSA                  ( VSA               ),
  159.         .VFP                  ( VFP               ),
  160.         .VBP                  ( VBP               ),
  161.         .VACTIVE              ( VACTIVE           ),

  162.         .VIDEO_TPG            ( VIDEO_TPG         ),
  163.         .VIDEO_FORMAT         ( VIDEO_FORMAT      ),
  164.         .VIDEO_VIC            ( VIDEO_VIC         ),
  165.         
  166.         .AUDIO_CTS            ( AUDIO_CTS         ),
  167.         .AUDIO_N              ( AUDIO_N           ),
  168.         .AUDIO_SAMPLE_RATE    ( AUDIO_SAMPLE_RATE )
  169.     )u_hdmi_tx_controller_wrapper(
  170.         .I_pixel_clk          ( I_pixel_clk          ),
  171.         .I_rst                ( I_rst                ),

  172.         .I_video_in_user      ( I_video_in_user_r2   ),
  173.         .I_video_in_valid     ( I_video_in_valid_r2  ),
  174.         .I_video_in_last      ( I_video_in_last_r1   ),
  175.         .I_video_in_data      ( I_video_in_data_r2   ),
  176.         .O_video_in_ready     ( O_video_in_ready     ),

  177.         .I_audio_valid        ( I_audio_valid        ),
  178.         .I_audio_left_data    ( I_audio_left_data    ),
  179.         .I_audio_right_data   ( I_audio_right_data   ),

  180.         .O_ch0_tmds_code_data ( S_ch0_tmds_code_data ),
  181.         .O_ch1_tmds_code_data ( S_ch1_tmds_code_data ),
  182.         .O_ch2_tmds_code_data ( S_ch2_tmds_code_data ),
  183.         .O_clk_tmds_code_data ( S_clk_tmds_code_data )
  184.     );

  185.    
  186.     hdmi_phy_wrapper u_hdmi2phy_wrapper(
  187.         .I_pixel_clk        ( I_pixel_clk          ),
  188.         .I_serial_clk       ( I_serial_clk         ),
  189.         .I_rst              ( I_rst                ),

  190.         .I_tmds_channel_0   ( S_ch0_tmds_code_data ),
  191.         .I_tmds_channel_1   ( S_ch1_tmds_code_data ),
  192.         .I_tmds_channel_2   ( S_ch2_tmds_code_data ),
  193.         .I_tmds_channel_clk ( S_clk_tmds_code_data ),

  194.         .O_tmds_ch0_p       ( O_hdmi_tx_p[0]       ),
  195.         .O_tmds_ch1_p       ( O_hdmi_tx_p[1]       ),
  196.         .O_tmds_ch2_p       ( O_hdmi_tx_p[2]       ),
  197.         .O_tmds_clk_p       ( O_hdmi_clk_p         )
  198.     );
  199. endmodule
复制代码
更多关于IP HDMI IP介绍可以阅读"APUG058_HDMI Transmitter Over Lvds.pdf"该文档在对应的工程路径uisrc/06_doc路径下
2504661-20240731190258129-295500881.jpg
以上源码中,关键有2个地方需要设置好
3 顶层调用接口源码
关于VTC ip 和TPG ip的源码在前文中已经给出,这里我们主要看下顶层调用接口。
  1. `timescale 1ns / 1ns //仿真时间刻度/精度

  2. module rgb2hdmi
  3. (
  4. input  I_sysclk,       //系统时钟输入
  5. output O_hdmi_clk_p,     //HDMI输出时钟P端
  6. output O_hdmi_clk_n,     //HDMI输出时钟N端
  7. output [2:0]O_hdmi_tx_p, //HDMI输出数据P端
  8. output [2:0]O_hdmi_tx_n  //HDMI输出数据N端
  9. );

  10. wire vtc_rstn,vtc_clk,vtc_vs,vtc_hs,vtc_de_valid;//vtc vid 视频相关信号
  11. wire pclkx1,pclkx5,locked;//HDMI输出需要2个时钟,pclkx1是和内部视频同步的时钟,pclkx5是HDMI IP内部用于产生输出数据和输出时钟
  12. wire S_rst;
  13. wire [7 :0] rgb_r ,rgb_g ,rgb_b;// 定义寄存器保存图像的颜色数据
  14. assign vtc_clk = pclkx1; // 内部像素时钟
  15. assign vtc_rstn = locked; //用PLL 的LOCK信号复位
  16. assign S_rst = ~locked;

  17. //PLL时钟管理IP 输出 pclkx1和pclkx5以及locked信号
  18. pll U_pll(
  19. .refclk   ( I_sysclk    ),//系统时钟输入
  20. .reset    ( 1'b0        ),
  21. .lock     ( locked      ),//PLL LOCKED
  22. .clk0_out ( pclkx1      ),//像素时钟
  23. .clk1_out ( pclkx5      ) //HDMI IO的serdes 时钟 5倍的像素时钟
  24. );

  25. uivtc#
  26. (
  27. .H_ActiveSize(1280),          //视频时间参数,行视频信号,一行有效(需要显示的部分)像素所占的时钟数,一个时钟对应一个有效像素
  28. .H_SyncStart(1280+88),        //视频时间参数,行同步开始,即多少时钟数后开始产生行同步信号
  29. .H_SyncEnd(1280+88+44),       //视频时间参数,行同步结束,即多少时钟数后停止产生行同步信号,之后就是行有效数据部分
  30. .H_FrameSize(1280+88+44+239), //视频时间参数,行视频信号,一行视频信号总计占用的时钟数
  31. .V_ActiveSize(720),          //视频时间参数,场视频信号,一帧图像所占用的有效(需要显示的部分)行数量,通常说的视频分辨率即H_ActiveSize*V_ActiveSize
  32. .V_SyncStart(720+4),         //视频时间参数,场同步开始,即多少行数后开始产生场同步信号
  33. .V_SyncEnd (720+4+5),        //视频时间参数,场同步结束,多少行后停止产生长同步信号
  34. .V_FrameSize(720+4+5+28)     //视频时间参数,场视频信号,一帧视频信号总计占用的行数量   
  35. )
  36. uivtc_inst
  37. (
  38. .I_vtc_clk(vtc_clk),  //系统时钟
  39. .I_vtc_rstn(vtc_rstn),//系统复位
  40. .O_vtc_vs(vtc_vs),//场同步输出
  41. .O_vtc_hs(vtc_hs),//行同步输出
  42. .O_vtc_de_valid(vtc_de_valid),//视频数据有效
  43. .O_vtc_user(vtc_user),    //满足stream时序产生 user 信号,用于帧同步
  44. .O_vtc_last(vtc_last)     //满足stream时序产生 later 信号,用于每行结束
  45. );

  46. uitpg uitpg_inst   
  47. (
  48. .I_tpg_clk(vtc_clk),   //系统时钟
  49. .I_tpg_rstn(vtc_rstn), //系统复位
  50. .I_tpg_vs(vtc_vs),   //图像的vs信号
  51. .I_tpg_hs(vtc_hs),   //图像的hs信号
  52. .I_tpg_de(vtc_de_valid),   //de数据有效信号
  53. .O_tpg_vs(),//和vtc_vs信号一样
  54. .O_tpg_hs(),//和vtc_hs信号一样
  55. .O_tpg_de(),//和vtc_de信号一样      
  56. .O_tpg_data({rgb_r,rgb_g,rgb_b})//测试图像数据输出         
  57. );

  58. //hdmi 输出IP
  59. hdmi_tx#(
  60. //HDMI视频参数设置      
  61. .H_ActiveSize       (1280), //视频时间参数,行视频信号,一行有效(需要显示的部分)像素所占的时钟数,一个时钟对应一个有效像素
  62. .H_SyncStart        (1280+88), //视频时间参数,行同步开始,即多少时钟数后开始产生行同步信号
  63. .H_SyncEnd          (1280+88+44),//视频时间参数,行同步结束,即多少时钟数后停止产生行同步信号,之后就是行有效数据部分
  64. .H_FrameSize        (1280+88+44+148), //视频时间参数,行视频信号,一行视频信号总计占用的时钟数

  65. .V_ActiveSize       (720),//视频时间参数,场视频信号,一帧图像所占用的有效(需要显示的部分)行数量,通常说的视频分辨率即H_ActiveSize*V_ActiveSize
  66. .V_SyncStart        (720+4),//视频时间参数,场同步开始,即多少行数后开始产生场同步信号
  67. .V_SyncEnd          (720+4+5), //视频时间参数,场同步结束,多少行后停止产生长同步信号  
  68. .V_FrameSize        (720+4+5+36),  //视频时间参数,场视频信号,一帧视频信号总计占用的行数量               
  69.      
  70. .VIDEO_VIC          ( 16       ),
  71. .VIDEO_TPG          ( "Disable"),//设置disable,用户数据驱动HDMI接口,否则设置eable产生内部测试图形
  72. .VIDEO_FORMAT       ( "RGB444" )//设置输入数据格式为RGB格式
  73. )u_hdmi_tx
  74. (
  75. .I_pixel_clk        ( pclkx1           ),//像素时钟
  76. .I_serial_clk       ( pclkx5           ),//串行发送时钟
  77. .I_rst              ( S_rst              ),//异步复位信号,高电平有效

  78. //.I_video_in_user    ( vtc_user         ),//视频输入帧起始信号
  79. //.I_video_in_valid   ( vtc_de_valid     ),//视频输入有效信号
  80. //.I_video_in_last    ( vtc_last         ),//视频输入行结束信号
  81. //.I_video_in_data    ( video_hdmi_data  ),//视频输入数据

  82. .I_video_rgb_enable (1'b1               ),//是否使能RGB输入接口,设置1使能,否则采用stream video时序接口  
  83. .I_video_in_vs      (vtc_vs            ),//RGB 输入VS 帧同步
  84. .I_video_in_de      (vtc_de_valid       ),//RGB 输入de有效
  85. .I_video_in_data    ({rgb_r,rgb_g,rgb_b} ), //视频输入数据     

  86. .O_hdmi_clk_p       ( O_hdmi_clk_p       ),//HDMI时钟通道
  87. .O_hdmi_tx_p        ( O_hdmi_tx_p        )//HDMI数据通道
  88. );

  89. endmodule
复制代码

4 FPGA工程
fpga工程的创建过程不再重复
2504661-20240731190258893-49364163.jpg
米联客的代码管理规范,在对应的FPGA工程路径下创建uisrc路径,并且创建以下文件夹
01_rtl:放用户编写的rtl代码
02_sim:仿真文件或者工程
03_ip:放使用到的ip文件
04_pin:放fpga的pin脚约束文件或者时序约束文件
05_boot:放编译好的bit或者bin文件(一般为空)
06_doc:放本一些相关文档(一般为空)
2504661-20240731190259365-1632598763.jpg
5下载演示
下载程序前,先确保FPGA工程已经编译。
5.1硬件连接
(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)
请确保下载器和开发板已经正确连接,并且开发板已经上电(注意JTAG端子不支持热插拔,而USB接口支持,所以在不通电的情况下接通好JTAG后,再插入USB到电脑,之后再上电,以免造成JTAG IO损坏)
2504661-20240731190300517-2085385592.jpg
5.2运行结果
显示器循环输出测试图形
2504661-20240731190301165-1762607816.jpg

copycode.gif
copycode.gif
copycode.gif
copycode.gif
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则