这次设计一个VGA、TFT显示模块,其特点如下:
- 行同步信号、场同步信号、数据有效信号的延迟数可调。(应用时方便与存储模块数据对齐)
- 分辨率可以通过调整参数来改变。
- 数据格式为RGR565,可简单修改位宽来修改成其他数据格式。
TFT的接口时序和VGA的时序相似,但是TFT接口比VGA多了数据有效信号和背光信号。
所以该模块可以用在TFT上,也可以用在VGA显示上。
VGA时序
RGB 接口的 TFT 屏扫描方式和 VGA (Video Graphics Array)标准类似,使用行列扫描的方式。在介绍 TFT 屏扫描原理之前,先来介绍下 VGA 显示器的扫描原理。
在 VGA 标准兴起的时候,常见的彩色显示器一般由 CRT(阴极射线管)构成,色彩是由 RGB 三基色组成。显示是用逐行扫描的方式解决。阴极射线枪发出的电子束打在涂有荧光粉的荧光屏上,产生 RGB 三基色,合成一个彩色像素,扫描从屏幕的左上方开始,从左到右,从上到下进行扫描,每扫完一行,电子束都回到屏幕的下一行左边的起始位置。
在这期间,CRT 对电子束进行消隐。每行结束时,用行同步信号进行行同步;扫描完所有行,用场同步信号进行场同步,并使扫描回到屏幕的左上方。同时进行场消隐,预备下一场的扫描。
随着显示技术的发展,出现了液晶显示器,液晶显示器的成像原理与 CRT 不同,液晶显示器是通过对液晶像素点单元施加电压与否,来实现液晶单元的透明程度,并添加三色滤光片、分别使 R、G、B 这 3 中光线透过滤光片,最后通过 3 个像素点合成一个彩色像素点,从而实现彩色显示。由于液晶技术晚于 CRT 显示技术诞生,为了能够兼容传统的显示接口,液晶显示器通过内部电路实现了对 VGA 接口的完全兼容。因此,在使用显示器时,只要该显示器带有标准的 VGA 接口,就不用去关注其成像原理,直接用标准的 VGA 时序即可驱动。
RGB 接口的 TFT 屏,扫描方式与 VGA 完全一致。不同之处只是在于,VGA 显示器是接收模拟信号,而 TFT 屏则省略了这一过程,直接接受数字信号。例如,在驱动 VGA 时首先产生对应像素的颜色数字信号编码,再使用数模转换电路(例如 ADV7123)将数字转换为模拟信号,然后通过 VGA 线缆将模拟信号传输到 VGA 显示器上进行显示。而 TFT 屏则直接省略了数模转换这一过程,直接将接收到的数字信号进行显示。因此在控制器设计端,并没有任何区别,因此本章学习结束可以只适当修改时序参数便可驱动学习套件中的 VGA 接口。
如图所示为该屏接口的行扫描时序图。
以 5 寸 TFT 屏(分辨率 800*480)为例,对行扫描时序要求如下(单位:输出一个像素的时间间隔,即像素时钟)。
如图所示为屏幕场扫描的时序图。
5 寸 TFT 屏中对场扫描时序要求如下(单位:输出一行 Line 的时间间隔)。
整个 TFT 屏的图像扫描示意图如下。
(以上介绍摘抄自小梅哥的教材文档,侵权删)
总之就是在行和场同步信号都是可视区域的时间时输出图像数据即可。
一、VGA显示模块
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: GDUT
// Engineer: Lclone
//
// Create Date: 2023/02/07 13:58:13
// Design Name: VGA_Display
// Module Name: VGA_Display
// Project Name: VGA_Display
// Target Devices:
// Tool Versions:
// Description:
// 行同步信号、场同步信号、数据有效信号的延迟数可调。(应用时方便与存储模块数据对齐)
// 分辨率可以通过调整参数来改变。
// 数据格式为RGR565,可简单修改位宽来修改成其他数据格式。
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module VGA_Display
# ( parameter HS_DELAY = 0, //信号延迟参数
parameter VS_DELAY = 0,
parameter DE_DELAY = 0 )
(
//-----------内部接口------------
input Clk, //时钟信号
input Rst_n, //复位信号
output Data_Req, //数据请求信号
input [15:0] RGB_Data, //图像数据输入
output reg [11:0] H_addr, //数据行地址
output reg [11:0] V_addr, //数据列地址
//-----------外部接口------------
output Disp_Pclk, //像素时钟
output [ 4:0] Disp_Red, //数据红色
output [ 5:0] Disp_Green, //数据绿色
output [ 4:0] Disp_Blue, //数据蓝色
output HS, //行同步信号
output VS, //场同步信号
output DE, //数据有效信号
output BL //背光信号(可以通过PWM来调节亮度,这里直接输出1)
);
localparam H_PULSE_BEGIN = 0;
localparam H_PULSE_END = 128;
localparam H_DATA_BEGIN = 128 + 88 + 0;
localparam H_DATA_END = 128 + 88 + 0 + 800;
localparam H_END = 128 + 88 + 0 + 800 + 40 + 0;
localparam V_PULSE_BEGIN = 0;
localparam V_PULSE_END = 2;
localparam V_DATA_BEGIN = 2 + 25 + 8;
localparam V_DATA_END = 2 + 25 + 8 + 480;
localparam V_END = 2 + 25 + 8 + 480 + 8 + 2;
reg [11:0] H_cnt; //行计数
reg [11:0] V_cnt; //场计数
reg HS_act; //行 有效信号
reg VS_act; //场 有效信号
reg DE_act; //数据有效 有效信号
reg [3:0] HS_reg; //行同步信号延迟寄存器
reg [3:0] VS_reg; //场同步信号延迟寄存器
reg [3:0] DE_reg; //数据有效信号延迟寄存器
always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0)
H_cnt <= 0;
else if(H_cnt == H_END - 1)
H_cnt <= 0;
else
H_cnt <= H_cnt + 1'b1;
end
always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0)
V_cnt <= 0;
else if(V_cnt == V_END - 1 & H_cnt == H_END - 1)