VGA简介:
VGA,英文全称:"Video Graphics Array",译为视频图形阵列,是一种使用模拟信号进行视频传输的标准协议。由IBM公司于1987年推出,因其分辨率高、显示速度快、颜色丰富等优点,广泛应用与彩色显示器领域。
VGA视频传输协议使用的是通用的RGB色彩模式作为显示标准,通过控制三原色(Red,Green,Blue)的不同混合比例,在VGA中引脚1,2,3分别负责传输红,绿,蓝;
引脚13和引脚14分别是行同步与场同步信号,负载在VGA协议进行视频传输时负责同步图像信息的同步信号;
注:VGA只能接受模拟信号;
行扫描周期每一个时钟周期传输一个像素点;
场扫描周期每一个时钟周期传输一行;
VGA显示模式以及相关参数:
显示模式:像素 x 行 @ 帧率;
时钟频率的确定:1 / (行扫描周期 x 场扫描周期 x 帧率)
因为VGA仅接收模拟信号,但是一般经过图像以数字信号的形式输出,可以采样数模转换芯片AD7123(成本比较高),另外一种方式就是采样权电阻网络去实现DA转换;
下图为RGB565(红色,绿色,蓝色带宽)
程序设计:
顶层(vga_colorbar)程序:
module vga_colorbar
(
input wire sys_clk ,
input wire sys_rst_n ,
output wire hsync ,
output wire vsync ,
output wire [15:0] vga_rgb
);
wire vga_clk ;
wire locked ;
wire rst_n ;
wire [9:0] pix_x ;
wire [9:0] pix_y ;
wire [15:0] pix_data ;
assign rst_n = (sys_rst_n && locked);
clk_gen clk_gen_inst
(
.areset (~sys_rst_n) ,
.inclk0 (sys_clk ) ,
.c0 (vga_clk ) ,
.locked (locked )
);
vga_crtl vga_crtl_inst
(
.vga_clk (vga_clk),
.sys_rst_n (rst_n),
.pix_data (pix_data),
.pix_x (pix_x ),
.pix_y (pix_y ),
.hsync (hsync ),
.vsync (vsync ),
.vga_rgb (vga_rgb)
);
vga_pic vga_pic_inst
(
.vga_clk (vga_clk),
.sys_rst_n (rst_n),
.pix_x (pix_x),
.pix_y (pix_y),
.pix_data (pix_data)
);
endmodule
vga_pic:
module vga_pic
(
input wire vga_clk ,
input wire sys_rst_n ,
input wire [9:0] pix_x ,
input wire [9:0] pix_y ,
output reg [15:0] pix_data
);
parameter H_VALID = 10'd640,
V_VALID = 10'd480;
parameter RED = 16'hF800,
ORANGE = 16'hFC00,
YELLOW = 16'hFFE0,
GREEN = 16'h07E0,
CREEN = 16'h07FF,
CYAN = 16'h07FF,
BLUE = 16'h001F,
PURPPLE = 16'hF81F,
BLACK = 16'h0000,
WHITE = 16'hFFFF,
GRAY = 16'hD69A;
always@(posedge vga_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pix_data <= BLACK;
else if(pix_x >= 0 && pix_x < ((H_VALID / 10) * 1))
pix_data <= RED;
else if(pix_x >= ((H_VALID / 10) * 1) && pix_x < ((H_VALID / 10) * 2))
pix_data <= ORANGE;
else if(pix_x >= ((H_VALID / 10) * 2) && pix_x < ((H_VALID / 10) * 3))
pix_data <= YELLOW;
else if(pix_x >= ((H_VALID / 10) * 3) && pix_x < ((H_VALID / 10) * 4))
pix_data <= GREEN;
else if(pix_x >= ((H_VALID / 10) * 4) && pix_x < ((H_VALID / 10) * 5))
pix_data <= CYAN;
else if(pix_x >= ((H_VALID / 10) * 5) && pix_x < ((H_VALID / 10) * 6))
pix_data <= BLUE;
else if(pix_x >= ((H_VALID / 10) * 6) && pix_x < ((H_VALID / 10) * 7))
pix_data <= PURPPLE;
else if(pix_x >= ((H_VALID / 10) * 7) && pix_x < ((H_VALID / 10) * 8))
pix_data <= BLACK;
else if(pix_x >= ((H_VALID / 10) * 8) && pix_x < ((H_VALID / 10) * 9))
pix_data <= WHITE;
else if(pix_x >= ((H_VALID / 10) * 9) && pix_x < (H_VALID))
pix_data <= GRAY;
else
pix_data <= BLACK;
endmodule
vga_crtl:
module vga_crtl
(
input wire vga_clk ,
input wire sys_rst_n ,
input wire [15:0] pix_data ,
output wire [9:0] pix_x ,
output wire [9:0] pix_y ,
output wire hsync ,
output wire vsync ,
output wire [15:0] vga_rgb
);
parameter H_SYNC = 10'd96 ,
H_BACK = 10'd40 ,
H_LEFT = 10'd8 ,
H_VAILD = 10'd640 ,
H_RIGHT = 10'd8 ,
H_FRONT = 10'd8 ,
H_TOTAL = 10'd800 ;
parameter V_SYNC = 10'd2 ,
V_BACK = 10'd25 ,
V_TOP = 10'd8 ,
V_VAILD = 10'd480 ,
V_BOTTOM = 10'd8 ,
V_TOTAL = 10'd525 ;
reg [9:0] cnt_h ;
reg [9:0] cnt_v ;
wire rgb_valid ;
wire pix_data_req; //因为在仿真中pix_data会因为时序逻辑延迟一拍,所以通过pix_data_req将pix_x都提前一个值开始计数,这样仿真中的pix_data可以提前一拍被赋值,正好弥补时序逻辑延迟的一拍;
always@(posedge vga_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_h <= 10'd0;
else if(cnt_h == H_TOTAL - 1'b1)
cnt_h <= 10'd0;
else
cnt_h <= cnt_h + 1'b1;
always@(posedge vga_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_v <= 10'd0;
else if((cnt_v == V_TOTAL - 1'b1) && (cnt_h == H_TOTAL - 1'b1))
cnt_v <= 10'd0;
else if(cnt_h == H_TOTAL - 1'b1)
cnt_v <= cnt_v + 1'b1;
else
cnt_v <= cnt_v;
assign rgb_valid = (((cnt_h >= H_SYNC + H_BACK + H_LEFT)
&& (cnt_h < H_SYNC + H_BACK + H_LEFT + H_VAILD))
&& ((cnt_v >= V_SYNC + V_BACK + V_TOP)
&& (cnt_v < V_SYNC + V_BACK + V_TOP + V_VAILD)))
? 1'b1 : 1'b0;
//pix_data_req:像素点色彩信息请求信号,超前rgb_valid信号一个时钟周期
assign pix_data_req = (((cnt_h >= H_SYNC + H_BACK + H_LEFT - 1'b1)
&& (cnt_h < H_SYNC + H_BACK + H_LEFT + H_VAILD - 1'b1))
&& ((cnt_v >= V_SYNC + V_BACK + V_TOP)
&& (cnt_v < V_SYNC + V_BACK + V_TOP + V_VAILD)))
? 1'b1 : 1'b0;
assign pix_x = (pix_data_req == 1'b1) ? (cnt_h - (H_SYNC + H_BACK + H_LEFT - 1'b1)):10'h3ff;
assign pix_y = (pix_data_req == 1'b1) ? (cnt_v - (V_SYNC + V_BACK + V_TOP)):10'h3ff;
assign hsync = (cnt_h <= H_SYNC - 1'd1) ? 1'b1 : 1'b0;
assign vsync = (cnt_v <= V_SYNC - 1'd1) ? 1'b1 : 1'b0;
assign vga_rgb = (rgb_valid == 1'b1) ? pix_data : 16'h0000;
endmodule
Clk_gen:调用PLL ip核资源生成25M
效果展示: