FPGA数字图像显示原理与实现设计

01
视频图像接口概述
视频图像经过数十年的发展,已形成了一系列的规范,以vga和hdmi为主的视频图像接口协议也得到定义与推广。尽管dp、dvi、type-c等图像接口技术近年来得到了推广与应用,且vga传输性能发展逐渐落后于时代,但作为显示器和显卡等设备的通用显示接口,vga和hdmi仍是当前主流的视频图像接口技术。
1.1 vga视频接口
视频图形阵列(vga,video graphics array),也可称作d-sub,是ibm于1987年提出的一个使用模拟信号的电脑显示标准,因此vga传输信号为模拟信号,并且只能传输视频信号,不能传输音频信号。
vga接口共有15针,分成3排,每排5个孔,是显卡上应用最为广泛的接口类型,绝大多数显卡都带有此种接口。它传输红、绿、蓝模拟信号以及同步信号(水平和垂直信号)。
vga各针脚定义如下:
vga支持在640×480的较高分辨率下同时显示16种色彩或256种灰度,同时在320×240分辨率下可以同时显示256种颜色。使用vga连接设备时,线缆长度通常不超过10米,而且要注意接头是否安装牢固,否则可能引起图像中出现虚影。
1.2 hdmi视频接口
高清晰度多媒体接口(high definition multimedia interface,hdmi)是一种数字化视频/音频接口技术,是适合影像传输的专用型数字化接口,hdmi可同时传送音频和影音信号,且在信号传送前无需进行数/模或者模/数转换,是当前视音频主选接口。
hdmi自2002年提出以来,已发展到hdmi 2.1标准。该标准能够支持4k 120hz、8k 60hz以及高动态范围成像(hdr),能够针对场景或帧数进行优化,并向后兼容hdmi 2.0和hdmi 1.4,其中hdmi 1.4最高数据传输速度为10.2gbps,hdmi 2.0最高数据传输速度为18gbps。
hdmi在物理接口上主要包括以下几种类型:标准hdmi接口、mini hdmi接口和micro hdmi接口。长距离传输通常线材较硬 ,采用标准hdmi接口以确保稳固连接;而小设备通常采用mini hdmi接口和micro hdmi接口。
1.3 vga与hdmi对比
vga与hdmi的对比如下:
vga传输模拟信号,传输过程需要转换和缓存,存在一定损失;hdmi传输数字信号,数据需要无压缩,短距离无转换无损失;vga仅支持视频传输;hdmi同时支持音频传输;vga采用pc标准,色阶从0至255;hdmi采用tv标准,色阶默认从15至255;vga在高分辨率下会存在失真虚化的问题;hdmi支持4k高清分辨率;vga不存在兼容顾虑;hdmi在pc上兼容性一般,通常不支持三屏以上多屏显示。随着数字图像的发展,vga接口被淘汰已成为趋势,目前大部分新生产的pc和显示器设备都不再支持vga接口。然而,由于vga标准早期的影响较大,大量投影仪等设备仍采用vga,因此vga接口目前仍被大量使用。
02
图像显示时序分析
尽管hdmi接口为减少干扰、增强传输可靠性采用了tmds编码,但其图像扫描的本质方法与vga相同:通过行同步与场同步进行扫描控制。在设计过程中通常采用专用芯片(例如sil9134 hdmi编码芯片与sil9013 hdmi解码芯片)完成tmds编码操作,因此掌握行同步与场同步的控制时序,就可以完成视频图像的显示。
2.1 图像显示时序
视频图像显示通常采用逐行扫描的方法:从屏幕左上方开始,从左向右逐点扫描。每行扫描完成时,用行同步信号hsync进行同步,电子束回到下一行最左侧起始位置,同时crt对电子束进行行消隐;每帧所有行扫描完成时,用场同步信号vsync进行帧同步,电子束回到屏幕左上方,同时crt对电子束进行进行场消隐,开始下一帧扫描。
hsync为行同步信号(horizontal synchronization),低电平时完成图像行数据扫描,高电平时进行行同步;vsync为场同步信号(vertical synchronization),低电平时进行图像数据扫描,高电平时进行帧同步。
行同步信号hsync和场同步信号vsync均由四部分组成:sync同步脉冲 + back porch消隐后肩时间 + active video数据有效时间 + front porch消隐前肩时间。
一幅图片的显示包括有效数据部分和消隐区部分,blanking为图像的消隐区,border和addressable video部分为图像的有效数据部分,在800×600及以上分辨率中horizontal left border、horizontal right border、vertical top border、vertical bottom border四个参数为0,即不存在border区域。
行同步时序以像素为单位,场同步时序以行为单位。例如1920×1080分辨率的图像,行时序以每行1920个像素进行同步和有效传输,场时序以每帧1080行进行同步和有效传输。
2.2 不同分辨率显示参数
通过行场同步时序分析可知,对于图像分辨率为1920×1080@60hz的图像显示,时钟传输频率并非仅考虑有效数据像素1920×1080×60=124.416mhz,而应当同时考虑有效数据和消隐区数据2200×1125×60=148.5mhz。
不同分辨率图像有效数据和消隐区像素分布如下:
03
图像显示代码实现
3.1 verilog代码
通过hdmi接口显示图像信息,主要包括两部分:行场同步等信号生成模块与iic配置tmds编码芯片模块。由于iic协议配置芯片寄存器实现方法已在iic协议中介绍,所以这里给出不同分辨率下hdmi行场同步信号的生成代码:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// company: cascatrix
// engineer: carson
//
// create date: 2023/01/15
// design name: image_base
// module name: cx_image
// tool versions: v1.0
// description: image read and generate display parameters
//
//////////////////////////////////////////////////////////////////////////////////
`define pixel_1920_1080
//`define pixel_1680_1050
//`define pixel_1280_1024
//`define pixel_1280_720
//`define pixel_1024_768
//`define pixel_800_600
//`define pixel_640_480
module cx_image(
inputwireclk,
outputreghs,
outputregvs,
outputwireen,
outputwire [23:0]data
);//1920x1080 148.5mhz
`ifdef pixel_1920_1080
parameter h_active = 1920;// 行数据有效时间
parameter h_front_porch = 88; // 行消隐前肩时间
parameter h_sync_time = 44; // 行同步信号时间
parameter h_back_porch = 148; // 行消隐后肩时间
parameter v_active = 1080;// 列数据有效时间
parameter v_front_porch = 4; // 列消隐前肩时间
parameter v_sync_time = 5; // 列同步信号时间
parameter v_back_porch = 36; // 列消隐后肩时间
`endif
//1680x1050 119mhz
`ifdef pixel_1680_1050
parameter h_active = 1680;// 行数据有效时间
parameter h_front_porch = 48; // 行消隐前肩时间
parameter h_sync_time = 32; // 行同步信号时间
parameter h_back_porch = 80; // 行消隐后肩时间
parameter v_active = 1050;// 列数据有效时间
parameter v_front_porch = 3; // 列消隐前肩时间
parameter v_sync_time = 6; // 列同步信号时间
parameter v_back_porch = 21; // 列消隐后肩时间
`endif
//1280x1024 108mhz
`ifdef pixel_1280_1024
parameter h_active = 1280;// 行数据有效时间
parameter h_front_porch = 48; // 行消隐前肩时间
parameter h_sync_time = 112; // 行同步信号时间
parameter h_back_porch = 248; // 行消隐后肩时间
parameter v_active = 1024;// 列数据有效时间
parameter v_front_porch = 1; // 列消隐前肩时间
parameter v_sync_time = 3; // 列同步信号时间
parameter v_back_porch = 38; // 列消隐后肩时间
`endif
//1280x720 74.25mhz
`ifdef pixel_1280_720
parameter h_active = 1280;// 行数据有效时间
parameter h_front_porch = 110; // 行消隐前肩时间
parameter h_sync_time = 40; // 行同步信号时间
parameter h_back_porch = 220; // 行消隐后肩时间
parameter v_active = 720; // 列数据有效时间
parameter v_front_porch = 5; // 列消隐前肩时间
parameter v_sync_time = 5; // 列同步信号时间
parameter v_back_porch = 20; // 列消隐后肩时间
`endif
//1024x768 65mhz
`ifdef pixel_1024_768
parameter h_active = 1024;// 行数据有效时间
parameter h_front_porch = 24; // 行消隐前肩时间
parameter h_sync_time = 136; // 行同步信号时间
parameter h_back_porch = 160; // 行消隐后肩时间
parameter v_active = 768; // 列数据有效时间
parameter v_front_porch = 3; // 列消隐前肩时间
parameter v_sync_time = 6; // 列同步信号时间
parameter v_back_porch = 29; // 列消隐后肩时间
`endif
//800x600 40mhz
`ifdef pixel_800_600
parameter h_active = 800;// 行数据有效时间
parameter h_front_porch = 40 ;// 行消隐前肩时间
parameter h_sync_time = 128;// 行同步信号时间
parameter h_back_porch = 88 ;// 行消隐后肩时间
parameter v_active = 600;// 列数据有效时间
parameter v_front_porch = 1 ;// 列消隐前肩时间
parameter v_sync_time = 4 ;// 列同步信号时间
parameter v_back_porch = 23 ;// 列消隐后肩时间
`endif
//640x480 25.175mhz
`ifdef pixel_640_480
parameter h_active = 640; // 行数据有效时间
parameter h_front_porch = 16 ; // 行消隐前肩时间
parameter h_sync_time = 96 ; // 行同步信号时间
parameter h_back_porch = 48 ; // 行消隐后肩时间
parameter v_active = 480; // 列数据有效时间
parameter v_front_porch = 10 ; // 列消隐前肩时间
parameter v_sync_time = 2 ; // 列同步信号时间
parameter v_back_porch = 33 ; // 列消隐后肩时间
`endif
parameter h_total_time = h_active + h_front_porch + h_sync_time + h_back_porch;
parameter v_total_time = v_active + v_front_porch + v_sync_time + v_back_porch;
reg h_act;
reg v_act;
reg [12:0] h_syn_cnt;
reg [12:0] v_syn_cnt;
reg [31:0] image_cnt;
// 有效数据控制
assign en = h_act & v_act;
// 行扫描计数器
always@(posedge clk)
begin
if(h_syn_cnt == h_total_time - 1)
h_syn_cnt <= 13'b0;else h_syn_cnt <= h_syn_cnt + 1'b1;end
// 列扫描计数器
always@(posedge clk)
begin
if(h_syn_cnt == h_total_time - 1)
begin
if(v_syn_cnt == v_total_time-1) v_syn_cnt <= 13'b0; else v_syn_cnt <= v_syn_cnt + 1'b1;end
end
// 行同步控制
always@(posedge clk)
begin
if(h_syn_cnt < h_sync_time) hs <= 1'b0;else hs <= 1'b1;end
// 场同步控制
always@(posedge clk)
begin
if(v_syn_cnt < v_sync_time) vs <= 1'b0;else vs <= 1'b1;end
// 行有效控制
always@(posedge clk)
begin
if(h_syn_cnt == h_sync_time + h_back_porch - 1) h_act = 1'b1;else if(h_syn_cnt == h_sync_time + h_back_porch + h_active - 1) h_act = 1'b0;end
// 列有效控制
always@(posedge clk)
begin
if(v_syn_cnt == v_sync_time + v_back_porch - 1 && h_syn_cnt == 0) v_act = 1'b1;else if(v_syn_cnt == v_sync_time + v_back_porch + v_active - 1 && h_syn_cnt == 0) v_act = 1'b0;end
// 像素数计数器
always@(posedge clk)
begin
if(image_cnt == h_active*v_active - 1)image_cnt <= 'd0;else if(h_act & v_act) image_cnt <= image_cnt + 1;end
// 图像像素值存储rom
rom_image inst_rom_image
(
.clk (clk),.en (h_act & v_act),.addr (image_cnt),.dout (data));
endmodule
rom_image为图像像素数据存储模块,根据不同地址依次存入对应像素的像素值。该模块可通过matlab生成,具体方法将在后续fpga数字图像仿真中介绍。部分代码如下:
module rom_image
(
input clk,
input[31:0] addr,
input en,
output[23:0]dout
);
reg [23:0] data;
assigndout = data;
always@(*)
begin
if(en)
case(addr)
0 : data<=24'hb18d81;
1 : data<=24'h967266;
2 : data<=24'h987468;
...
2073597 : data<=24'hae8070;
2073598 : data<=24'hae8070;
2073599 : data<=24'hc79989;
default: data<= 0;
endcase
else
data <= 0;
end
endmodule
3.2 实现效果分析
选择分辨率为1920×1080的图像:

手持万用表购买指南
智慧校园:RFID在校园物联网平台应用
旋变变压器的作用及工作原理
5G时代,AI应用全面爆发,为半导体供应链注入新动能
为什么锤子新机加入iPhone“陪护”功能?老罗一语道破
FPGA数字图像显示原理与实现设计
基于Xilinx Spartan-6 FPGA加速纹理映射的实现
晶体管放大结构定义和判断
什么是系统架构 为什么要做架构设计
客车研发生产企业宇通客车发布2022第一季度报告
新能源动力电池包温度场光纤光栅测量系统
M5256-00000U-400BG压力传感器压铸机应用
五分钟了解机智云自助接入(使用新版开发者中心)
英特尔至强D处理器的坚固和可部署性能
路由器环回接口的优点与应用
2018数据云图独家首发,包罗众多企业,来看你司“入伙”了么!
物联网对煤矿井下作业出现的改变
智慧工地的智慧主要体现在哪里
虚拟现实走向主流 得砍死这几头拦路虎
许勤:盛赞开诚发展新成就给予充分肯定