项目名称
Vga驱动接口设计
项目说明
VGA 图像显示方式是通过光栅扫描的方式,电子束在显示屏幕上有规律地从左到右、 从上到下的逐行扫描。即从屏幕左上角一点开始,从左像右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT 对电子束进行消隐,每行结束时, 用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。
VGA 的时序包括水平时序和垂直时序,且两者都包含的时序参数有:水平(垂直)同步 脉冲、水平(垂直)同步脉冲结束到有效显示数据区开始之间的宽度(后沿)、有效显示区宽度、 有效数据显示区结束到水平(垂直)同步脉冲宽度开始之间的宽度(前沿)。水平有效显示区宽 度与垂直有效显示区宽度逻辑与的区域为可视区域,其他区域为消隐区。 标准 VGA 一共 15 个接口,真正用到的信号接口只有 5 个,HSYNC 是行同步信号,VSYNC 是场同步信号,VGA_R、VGA_G、VGA_B 是 RGB 三原色信号。
常用的专用VGA视频编码芯片有ADV/GM7123,然后通过标准的VGA物理接口输出,实现与VGA显示器通信。本项目采用的adv7123视频编码芯片.
本项目采用640*480@60的显示模式
分辨率(长*宽@帧率) | 时钟(mhz) | 行时序(像素) | 场时序(像素) | ||||||||
a | b | c | d | e | a | b | c | d | e | ||
640*480@60hz | 25.175mhz | 96 | 48 | 640 | 16 | 800 | 2 | 33 | 480 | 10 | 525 |
时序图
rgb三原色模型:一般包括rgb332,rgb565,rgb444,rgb888等,本项目采用rgb888的显示模式,可以显示的颜色种类有 种
具体要求
显示任意颜色,比如红色
设计架构
代码设计
verilog代码设计
创建pll ipcore生成25m的vga驱动时钟
顶层模块设计
module vga_color_top(
input clk,
input rst_n,
output [23:0] vga_rgb,
output vga_hs,//行时序,计数一行中每列的像素
output vga_vs,//场时序,计数一列中每行的像素
output lcd_dclk////adv7123像素时钟输入
// output lcd_blank,//显示空白输入
// output lcd_sync//显示同步引脚可以一直为低
);
wire clk_25m;
wire locked;
my_pll my_pll (
.areset(!rst_n),
.inclk0(clk),
.c0(clk_25m),
.locked(locked)
);
vga_color vga_color
(
.clk(clk_25m),
.rst_n(locked),
.vga_rgb(vga_rgb),
.vga_hs(vga_hs),//行时序,计数一行中每列的像素
.vga_vs(vga_vs),//场时序,计数一列中每行的像素
.lcd_dclk(lcd_dclk),////adv7123像素时钟输入
.lcd_blank(),//显示空白输入
.lcd_sync()//显示同步引脚可以一直为低
);
endmodule
vga控制模块设计
//640*480@60hz
module vga_color
(
input clk,
input rst_n,
output reg[23:0] vga_rgb,
output reg vga_hs,//行时序,计数一行中每列的像素
output reg vga_vs,//场时序,计数一列中每行的像素
output lcd_dclk,////adv7123像素时钟输入
output lcd_blank,//显示空白输入
output lcd_sync//显示同步引脚可以一直为低
);
localparam red=24'hff0000;
localparam green=24'h00ff00;
localparam blue=24'h0000ff;
localparam white=24'hffffff;
localparam black=24'h000000;
localparam yellow=24'hffff00;
reg [10:0] cnt1;//行像素计数器
reg [10:0] cnt2;//列像素计数器
//行时序计满799,从0开始计数
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt1<=11'd0;
else if(cnt1<11'd799)
cnt1<=cnt1+1'b1;
else
cnt1<=11'd0;
//场时序计满524
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt2<=11'd0;
else if(cnt1==11'd799)begin
if(cnt2<11'd524)
cnt2<=cnt2+1;
else
cnt2<=0;
end
else
cnt2<=cnt2;
//行同步时序
always@(*)
if(!rst_n)
vga_hs<=0;
else if(cnt1==11'd0)
vga_hs<=0;
else if(cnt1==11'd96) //0-95总共120个像素点为低电平,计数到96同步输出高电平
vga_hs<=1;
//场同步时序
always@(*)
if(!rst_n)
vga_vs<=0;
else if(cnt2==11'd0)
vga_vs<=0;
else if(cnt2==11'd2)
vga_vs<=1;
//显示区域
reg flag;//显示区域标志信号
always@(*)
if(!rst_n)
flag<=0;
else if((cnt1>=11'd144 && cnt1<11'd784) && (cnt2>=11'd35 && cnt2<11'd515))
flag<=1;
else
flag<=0;
always@(*)
if(!rst_n)
vga_rgb<=0;
else if(flag)
vga_rgb<=red;
else
vga_rgb<=0;
assign lcd_sync=1'd0;
assign lcd_blank=vga_hs & vga_vs;
assign lcd_dclk=~clk;
endmodule
仿真代码
`timescale 1ns/1ns
module vga_color_top_tb;
reg clk;
reg rst_n;
wire [23:0] vga_rgb;
wire vga_hs;//行时序,计数一行中每列的像素
wire vga_vs;//场时序,计数一列中每行的像素
wire lcd_dclk;////adv7123像素时钟输入
// output lcd_blank,//显示空白输入
// output lcd_sync//显示同步引脚可以一直为低
vga_color_top vga_color_top(
.clk(clk),
.rst_n(rst_n),
.vga_rgb(vga_rgb),
.vga_hs(vga_hs),//行时序,计数一行中每列的像素
.vga_vs(vga_vs),//场时序,计数一列中每行的像素
.lcd_dclk(lcd_dclk)////adv7123像素时钟输入
// output lcd_blank,//显示空白输入
// output lcd_sync//显示同步引脚可以一直为低
);
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#200;
rst_n=1;
end
endmodule
仿真结果
行同步时序满足时序要求在0-95为低,96-799为高
场时序也满足要求,仿真时间较长
标志信号也满足设计要求,由于仿真时间较长,不再赘述。