本帖最后由 viva_xin 于 2024-1-13 16:53 编辑
这篇来测试一下Pmod DVI/HDMI模块。
在Sipeed官方提供的GitHub仓库中有一个HDMI显示的例子,可以直接拿来作为学习参考,我也会把代码贴在后面。
在物理层,HDMI采用TMDS技术,通过3对差分接口串行的将图像数据以及行场同步信号传输给到显示器,另外还需要额外1对差分接口传输图像的时钟信号。
可以看见Pmod还将HDMI接口控制信号扩展出来了包括IIC,CEC和HPD等接口,方便实现更全的HDMI功能。
这里先不关心这些控制信号。
FPGA内部通过硬核serdes模块完成并串转换,在程序中需要调用原语来完成例化。这里使用的是“OSER10”,它的功能可以将10bit的并行数据以5倍频时钟上下沿都有效的速率串行输出。
OSER10 tmds_serdes [2:0] (
.Q(tmds_d),
.D0(tmds_d0),
.D1(tmds_d1),
.D2(tmds_d2),
.D3(tmds_d3),
.D4(tmds_d4),
.D5(tmds_d5),
.D6(tmds_d6),
.D7(tmds_d7),
.D8(tmds_d8),
.D9(tmds_d9),
.PCLK(clk_pixel),
.FCLK(clk_5x_pixel),
.RESET(~clk_pixel_resetn)
);
最后还需要在约束文件中需要设置好P/N端的线序,并且约束IO_TYPE为"LVCMOS33D",就可以让FPGA实现TMDS的传输。
IO_LOC "tmds_clk_p_0" C11,C10;
IO_PORT "tmds_clk_p_0" IO_TYPE=LVCMOS33D PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
图像数据RGB各个分量都是8bit,那么为何要使用“OSER10”,而不是“OSER8”呢,因为TMDS为了增加解码端的稳定性,采用了8b/10b的编码方式,通过加扰的方式保持高速传输时的直流平衡,弊端就是传输效率打了两折。程序中的svo_tmds模块就是完成8b/10b编码。
模块svo_tcard模拟了的内存video DMA模块,这个模块根据设定的分辨率产生一幅图像,并打包成axi stream接口送给后面模块。
module svo_tcard(
input clk, resetn,
output reg out_axis_tvalid,
input out_axis_tready,
output reg [SVO_BITS_PER_PIXEL-1:0] out_axis_tdata,
output reg [0:0] out_axis_tuser
);
模块svo_enc相当于一个axi stream master,从svo_tcard中取出图像数据,并通过fifo进行缓存,最后把rgb数据以及行场同步信号按照tmds的顺序也打包成axi stream流送给svo_tmds完成8b10b编码。
最后看一下显示效果。