如果能够用FPGA能够驱动显示器,就可以做不少与视频相关的实验,很多FPGA开发板使用了比较简单的VGA接口,连接非常简单,如下图:
只需要5跟线就可以连接VGA显示器
连接VGA的原理图
VGA连接器
然后我们就可以用FPGA的逻辑来做各种游戏了:
经典的Pong游戏
关于如何用FPGA逻辑来驱动VGA显示器,可以参考页面:
https://www.fpga4fun.com/PongGame.html
然而,现在的显示器基本上都使用的是HDMI连接器,VGA接口的显示器只能在古老的实验室里才有。所以我们要做视频的一些项目,就要用FPGA来输出HDMI的信号,HDMI的连接器有不同大小,常用的体积比较大,信号线的定义如下图:
HDMI连接器
HDMI的信号线
标准的HMDI连接器有19个管脚,只有其中的8根是以差分信号的方式来传输高速视频信息的,所以只需要8根FPGA的管脚,配制成7对差分TMDS输出即可。
那时钟的速率需要多快呢?如果我们要生成一个640*480 RGB 24bpp的视频信号,刷新频率为60Hz,每帧有307200个像素,每一个像素为24位(R|G、B各8位),需要0.44Gbps的又用数据才能传输。再考虑一些屏外区域的信息,实际的分辨率需要大一些,比如800*525.
一个像素需要3 * 8位来传输,实际上HDMI还需要添加2bits以便对数据进行加扰,也就是需要3*10位来传输,每个像素需要30bits。
加扰用的额外数据用于接收端对接收到的数据进行同步,下面是TMDS差分信号的时序:
对于640*480分辨率的显示,我们需要至少250MHz的时钟信号,如果要获得更高的分辨率则需要更高的时钟频率,小脚丫FPGA模块中使用的Lattice的XO2-4000HC系列FPGA以及Intel的MAX10器件内部的时钟通过锁相环生成,可以达到400MHz。支持640*480分辨率是没有问题的,如果要获得更高的分辨率可以采用DDR输出的方式。
显示驱动逻辑
屏幕的分布
通过逻辑编程,可以在显示屏上实现如下的效果:
用HDMI显示器实现的Pong游戏,比VGA实现的要效果好很多
PacMan游戏
具体的代码实现可以参考页面:https://www.fpga4fun.com/HDMI.html
更多关于FPGA驱动HDMI的文章:
https://projectf.io/posts/fpga-graphics/
https://projectf.io/posts/fpga-pong/
https://projectf.io/posts/video-timings-vga-720p-1080p/
讲完了FPGA驱动HDMI,有没有可能用单片机/微控制器也能实现同样的效果呢?一般的MCU真的够呛,但树莓派基金会推出的RP2040却是可以做到的:
虽然RP2040的标称时钟为125MHz,但可以轻松超频到250MHz,能够满足640*480分辨率的时钟要求了
RP2040的PIO可以通过编程配置称为4对差分输出的串行信号
具体如何实现,看一下技术大神Luke Wren在RP2040上用GPIO通过Bitbang的方式得到的DVI接口:https://github.com/Wren6991/PicoDVI
下面是他的电路原理图(用KiCad绘制的,有源文件)
有位小哥使用他的代码,在SparkFun的RP2040板上实现的效果:
在显示屏上显示文字:
显示月亮:
当然也可以播放视频
有人专门制作了一个板子,RP2040超频到252MHz
关于用RP2040驱动HDMI的更多资源可以在Github搜索HDMI RP2040.