当前位置: 首页 > news >正文

FPGA 20个例程篇:16.HDMI显示彩色风景图

第六章 图像显示处理,经典再现

16.HDMI显示彩色风景图

       HDMI接口在消费类电子行业,比如笔记本电脑、液晶电视、投影仪等产品中均得到了广泛的应用,一些专业的视频设备如摄像机、视频切换器、机顶盒等也都会集成HDMI接口,HDMI是新一代的多媒体接口标准即高清多媒体接口,作为应用最为广泛的音视频传输接口,熟练掌握HDMI接口的FPGA开发,一方面可以加深对底层8B/10B编码和并转串的理解,另一方面丰富简历的同时也更加方便工作中验证FPGA图像视频处理。

      HDMI接口可以同时传输视频和音频,极大简化了设备的接口和连线,也提供了更高的数据传输带宽,能传输无压缩的数字音频和高分辨率视频信号。HDMI向下兼容DVI即数字视频接口,但DVI只能用来传输视频,不能同时传输音频,这也是两者主要的差别,如图1所示是豌豆开发板Artix7上HDMI电路。

图1 豌豆开发板Artix7上HDMI电路

        下面我们来对照原理图,比较详细地说明HDMI接口中各个引脚的作用,如下图2所示是HDMI接口HDMI_D_N/P[2:0]、HDMI_CLK_N/P、HDMI_HPD引脚示意图,大家可以清楚地看到3个数据通道HDMI_D_N/P[2:0]和1个时钟通道HDMI_CLK_N/P作为数据传输总线直接与HDMI接口线束的差分引脚相连。HDMI_HPD即为热拔插检测,当视频设备与接收设备通过HDMI连接时,接收设备将HDMI_HPD置为高电平并通知发送设备,当发送设备检测到HDMI_HPD为低电平时则表明断开连接。

        如图3所示是HDMI接口中HDMI_OUT_EN引脚示意图,HDMI_OUT_EN信号用于设置HDMI接口的输入输出模式,当其为高电平时作为输出端,这时候由豌豆开发板输出 HDMI接口的5V电源,HDMI_HPD将作为输入信号使用;当HDMI_OUT_EN为低电平时,开发板上的HDMI接口作为输入端,接口上的5V电源将由外部连接设备提供,同时HDMI_HPD将输出高电平,用于指示HDMI连接状态。

图2 HDMI接口HDMI_D_N/P[2:0]、HDMI_CLK_N/P、HDMI_HPD引脚示意图

图3 HDMI接口HDMI_OUT_EN引脚示意图

      如图4所示,HDMI_SCL和 HDMI_SDA是HDMI接口的显示数据通道,用于HDMI发送端和接收端之间交换一些配置信息,并通过I2C协议通信。发送端通过显示数据通道,读取接收端保存在EEPROM中的EDID数据,获取接收端的信息,确认接收端终端显示的设置和功能,决定跟接收端之间以什么格式传输音视频数据。

图4 HDMI接口HDMI_SDA、HDMI_SCL引脚示意图

        DVI和HDMI接口协议在物理层均用了TMDS标准传输音视频数据,TMDS即最小化传输差分信号,如图5所示是HDMI接口引脚定义,DVI和HDMI视频接口中使用差分信号传输高速串行数据,TMDS差分传输技术用两个引脚作为一组差分对传输一路信号,例如“数据2+”、“数据2-”;“数据1+”、“数据1-”;“数据0+”、“数据0-”来传输一路信号,用这两个引脚间的电压差的正负极性和大小来决定传输数据的数值0或者1。

图5 HDMI接口引脚定义

       因为这个例程中只使用了HDMI接口来显示图像,并没有传输音频数据,所以暂时只需要实现DVI接口的驱动逻辑即可,在这里我们再简单了解一下TMDS视频传输协议。

       如图6所示是TMDS发送端和接收端的连接示意图,DVI或者HDMI视频传输所用的TMDS连接通过4个串行通道实现,即为3个TMDS数据通道和1个TMDS时钟通道,而TMDS时钟通道又以某个固定的速率运行,显然这个速率和视频的分辨率成比例。

图6 TMDS发送端和接收端的连接示意图

       对于DVI来说,其中3个通道分别用于传输视频中每个像素点的红、绿、蓝三个颜色分量,HDMI默认也是使用3个RGB通道,但它却可以选择传输像素点的亮度和色度信息等。第4个通道是时钟通道,用于传输像素时钟,独立的TMDS时钟通道为接收端提供接收的参考频率,用来保证数据在接收端可以被正确接收。

      每个TMDS链路都包括3个传输RGB信号的数据通道和1个传输时钟信号的通道,且每个数据通道都会通过编码算法,将8位的视、音频数据转换成最小化传输、直流平衡的10位数据,这也就使得数据的传输和恢复更加可靠。

        简单地总结如下:如果每个像素点的颜色深度为24位,即RGB每个颜色分量各占8位,那么首先每个通道上的颜色数据将通过一个8B/10B的编码器来转换成一个10位的像素字符,接着这10位的字符通过并串转换器转换成串行数据,最后再由TMDS数据通道发送出去,需要注意的是这个10:1的并转串过程所生成的串行数据速率则是实际像素时钟速率的10倍,如图7所示是FPGA基于IO模拟HDMI的实现原理示意图。

        在系统地了解过FPGA基于IO模拟HDMI的实现原理后,实际上对于用户而言,如果想要在FPGA上去IO模拟实现HDMI成像,那么只需要解决2个问题即可:1.还原TMDS视频传输协议即8B/10B编码;2.实现并转串的过程即把8B/10B编码后的10位数据通过HDMI接口上的差分对把数据传输出去。

图7 FPGA基于IO模拟HDMI的实现原理示意图

      那么下面我们就来详细地介绍:如何还原TMDS视频传输协议、如何实现10位数据并转串成1位数据送HDMI差分对收发,如图8所示是TMDS编码算法的示意图,TMDS通过逻辑算法实际上是将8位字符数据通过最小转换编码为10位字符数据,首先前8位数据由原始信号经运算后获得,第9位表示运算的方式,其中1表示异或0表示异或非,接着经过直流平衡后,就获得了第10位,而第10位本质是一个反转标志位,1表示进行了反转而0表示没有反转,从而达到直流平衡,整个过程中采用差分信号传输数据。

       直流平衡就是指在编码过程中保证信道中直流偏移为零,方法便是在原来的9位数据的后面加上第10位数据,这样传输的数据则趋于直流平衡,使信号对传输线的电磁干扰减少,从而提高信号传输的可靠性。

       在这里我们不动手还原整个TMDS编码算法,调用官方VHDL已经编写好的TMDSEncoder模块,直接把这个模块例化到整个工程的顶层文件当中即可,感兴趣的同学可以查阅“HDMI1.4规范中文版”文档对此有深入说明。

 

图8 TMDS编码算法示意图

        如图8所示是Oserdes通过DDR双边缘触发传输HDMI数据流示意图,大家不妨回忆回忆之前我们在千兆网口时候学习到的SelectIO IP核,实际上并转串、串转并也可以说是FPGA高速接口中常用到的设计,朋友们可以通过直接例化Iserdes和Oserdes原语来实现,Iserdes模块的作用在于实现高速源同步输入数据的串并转换,而Oserdes模块的作用在于实现高速源同步输出数据的并串转换。

      Serdes支持sdr和ddr两个模式,前者是单边缘触发传输,后者是双边缘触发传输,当然每个FPGA工程师的习惯不同,有的喜欢直接例化原语来实现Serdes串并转换或者并串转换的目的,有的则喜欢通过例化SelectIO IP核来实现,毕竟IP核图形化界面配置以及对应的说明手册看起来可能比原语更直观一些。

       大家可以对照图9,思考下如何实现并转串的过程即把8B/10B编码后的10位数据通过HDMI接口上的差分对把数据传输出去,这里假设video_driver驱动模块的模块时钟是pixel_clk,显然为了实现10位到1位的并转串处理,如果是sdr单边缘触发传输,那么 需要一个相对于pixel_clk时钟快十倍的pixel_clk_sdr时钟作为数据传输的参考时钟,如果是ddr双边缘触发传输,那么则需要一个相对于pixel_clk时钟快五倍的pixel_clk_ddr时钟作为数据传输的参考时钟即可。

图9 Oserdes通过DDR双边缘触发传输HDMI数据流示意图

        在这个例程中,我们去实现一个HDMI接口显示彩色风景图片的目标,考虑XC7A35T的BRAM资源有限,所以这里用ROM表事先存储一张分辨率是320*240分辨率的风景图片,通过HDMI接口显示在分辨率是640*480屏幕的正中间,如图10所示是Img2Lcd插件,利用这个插件我们可以把.jpg格式的图片每个像素值都提取出来并转换为RGB565格式的文件保存,为了方便实验,笔者为大家准备了10张已经提取好的.jpg文件,先通过word保存再把它们从格式上转换为ROM IP核支持的.coe文件。

 图10 Img2Lcd插件提取.jpg图片的各点像素值

       如表1所示是video_driver模块信号列表,在这个模块中和上个例程中VGA相似,我们需要实现底层的RGB565驱动、行场信号和hdmi接口使能信号时序,如图11所示是HDMI驱动模块的代码设计,注意到几个地方:1.屏幕的分辨率是640*480,而图片的大小是320*240,所以需要通过代码实现人为把图片放到屏幕显示区域的正中间;2.需要把video_en信号在显示图片的区域内拉高,在其区域外拉低,如图6-20所示是HDMI驱动模块的代码设计。

信号列表

信号名

I/O

位宽

pixel_clk

I

1

rst_n

I

1

video_hs

O

1

video_vs

O

1

video_rgb

O

16

video_en

O

1

表1 video_driver模块信号列表

图11 HDMI驱动模块的代码设计

       如下图12和13所示,大家打开Vivado后选择SelectIO IP核,这里需要对IP核数据总线和时钟类型进行如下配置,并且使IP核可以实现10位到1位的DDR并串转换的目的。

       如图12所示,在IP核的数据总线设置中选择DDR双边缘数据传输,数据传输方向为输出,数据位宽为10位,差分对传输使用标准的TMDS 33V电平。如图13所示,在IP核的时钟类型设置中也选择差分对传输使用标准的TMDS 33V电平即可。

图12 SelectIO IP核的数据总线设置

图13 SelectIO IP核的时钟类型设置

        如图14所示是HDMI显示彩色风景图顶层文件的例化,但在这里有4个地方要特别注意:

      1. 因为HDMI接口用了RGB的3个通道,对应需要3个TMDSEncoder模块去实现8B/10B编码转换,大家可以再查阅图6-15所示的TMDS发送端和接收端的连接示意图,其中红蓝色通道单独分开其TMDSEncoder模块的C0_I、C1_I的控制信号设置为0即可,而绿色通道需要把行场同步信号例化到TMDSEncoder模块的C0_I、C1_I,同时把video_en使能信号都例化到TMDSEncoder模块的DE_I;

     2. 因为是RGB565的输出格式,需要人为把HDMI驱动模块输出的16位RGB565转换成24位RGB888格式,对应位添加0即可;

      3. 例化4个SelectIO IP核实现3个TMDS数据通道和1个TMDS时钟通道的数据输出,这里把tmds_red、tmds_green、tmds_blue由TMDSEncoder模块编码后的10位数据作为SelectIO IP核输入端,同时把SelectIO IP核输出端直接引到外接接口的3个数据通道HDMI_D_N/P[2:0]和1个时钟通道HDMI_CLK_N/P即可;

      4. 在这里我们需要用PLL IP核倍频一个25Mhz的时钟给HDMI驱动模块作为模块时钟使用,感兴趣的同学也可以手工计算下1*109ns/800/525/60=39.6825ns,即大约折合成25Mhz的驱动时钟,此外还需要频一个比25Mhz快5倍的时钟提供给SelectIO IP核,用作DDR双边缘10位转1位,并转串数据传输使用。

      下载程序后通过HDMI接口连接到屏幕即可看到如图15所示的彩色风景图。

图14 HDMI显示彩色风景图顶层文件的例化

图15 HDMI显示彩色风景图

相关文章:

  • 【云原生之Docker实战】使用Docker部署NPS内网穿透工具
  • 应对过载- go-zero源码阅读
  • Python 的“self“参数是什么?
  • 模拟前端ADC芯片LH001-91,用于开发心电、脑电医疗设备
  • CAPL 封装了的SeedKey解锁函数,高复用性
  • 异常数据处理——3σ原则、箱线图
  • vue3.0 + tsx 构建el-button
  • 基于JAVA的TCP网络QQ聊天工具系统
  • 【WLAN】【调试】netsh wlan常用命令使用说明
  • 教程图文详解 - 网络安全(第八章)
  • Python数据分析案例08——预测泰坦尼克号乘员的生存(机器学习全流程)
  • 计算机四级——操作系统原理常用知识点个人总结(上)
  • 【学姐面试宝典】—— 前端基础篇Ⅰ
  • c++之二叉树
  • 字符串训练赛
  • conda常用的命令
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • JavaScript中的对象个人分享
  • JS题目及答案整理
  • Vue实战(四)登录/注册页的实现
  • 阿里研究院入选中国企业智库系统影响力榜
  • 闭包--闭包作用之保存(一)
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 服务器之间,相同帐号,实现免密钥登录
  • 工作手记之html2canvas使用概述
  • 聚簇索引和非聚簇索引
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 听说你叫Java(二)–Servlet请求
  • 小程序开发之路(一)
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #考研#计算机文化知识1(局域网及网络互联)
  • (10)STL算法之搜索(二) 二分查找
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (Java)【深基9.例1】选举学生会
  • (笔试题)分解质因式
  • (十六)串口UART
  • (十三)Flask之特殊装饰器详解
  • (四)模仿学习-完成后台管理页面查询
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .gitignore文件设置了忽略但不生效
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 设计模式—适配器模式(Adapter Pattern)
  • .NET 依赖注入和配置系统
  • .NetCore 如何动态路由
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .netcore如何运行环境安装到Linux服务器
  • ??javascript里的变量问题
  • @SpringBootApplication 包含的三个注解及其含义
  • [20170713] 无法访问SQL Server
  • [20171113]修改表结构删除列相关问题4.txt