学习VGA首先要了解VGA是什么:
(1)VGA接口协议:VGA端子_维基百科 、VGA视频传输标准_百度
最主要的几根线:
驱动VGA显示的接口主要是下面三种信号:行同步信号(HSYNC),场同步信号(VSYNC)和三条色彩电压传输信号(R、G、B分别对应)色彩电压为0--0.7V其中同步是靠前面两个信号协助的。HSYNC和VSYNC传输关系相对是固定的,双方虽然没有约定时钟信号同步,但是通常会约定发送方有一个基本的时钟,VSYNC、HSYNC、和色彩信号都会按照这个时钟的节拍确定状态。
VGA扫描方式
显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT 对电子束进行消隐,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。隔行扫描是指电子束扫描时每隔一行扫一线,扫完一屏后再返回来扫描剩下的线,隔行扫描的显示器闪烁快速,可能会使使用者眼睛疲劳
通常我们说的像素是指的显示像素并非总像素因为有前后沿脉冲
VGA 工业标准显示模式要求:行同步、列同步都为负极性,即同步脉冲要求是负脉冲。
行、列同步时序
列同步时序
这里可能有的人会有疑问怎么计算VGA的时序?
这里我在别处看到了一个不错的文章大家可以参考理解:·vga时序计算
实例:VGA显示colorbar:
vga的top:
module top(ext_clk_25m,ext_rst_n,vga_r,vga_b,vga_g,vga_hsy,vga_vsy ); input ext_clk_25m; input ext_rst_n; output vga_r; output vga_g; output vga_b; output vga_hsy; output vga_vsy; wire clk_50m; pll_countroller uut_pll_countroller (// Clock in ports .CLK_IN1(ext_clk_25m), // IN // Clock out ports .CLK_OUT1(clk_50m), // OUT // Status and control signals .RESET(~ext_rst_n),// IN .LOCKED(sys_rst_n) ); // OUT vga_countroller uut_vga_countroller( .clk(clk_50m), .rst_n(ext_rst_n), .vga_r(vga_r), .vga_g(vga_g), .vga_b(vga_b), .vga_hsy(vga_hsy), .vga_vsy(vga_vsy) ); endmodule
pll分频模块利用ip核进行实例化
vga控制模块:
module vga_countroller(clk,rst_n,vga_r,vga_g,vga_b,vga_hsy,vga_vsy ); input clk; input rst_n; output vga_r; output vga_g; output vga_b; output reg vga_hsy; output reg vga_vsy; //VGA_Timing 800*600 &50MHZ &72Hz; parameter VGA_HTT=12'd1040-12'd1;//Hor Total Time(行帧长) parameter VGA_HST=12'd120; //Hor Sync Time(同步脉冲) parameter VGA_HBP=12'd64; //Hor Back Porch(后沿脉冲) parameter VGA_HVT=12'd800; //Hor Valid Time(显示脉冲) parameter VGA_HFP=12'd56; //Hor Front Porch(前沿脉冲) parameter VGA_VTT=12'd666-12'd1; //Hor Total Time(列帧长) parameter VGA_VST=12'd6; //Hor Sync Time(同步脉冲) parameter VGA_VBP=12'd23; //Hor Back Porch(后沿脉冲) parameter VGA_VVT=12'd600; //Hor Valid Time(显示脉冲) parameter VGA_VFP=12'd37; //Hor Front Porch(前沿脉冲) parameter VGA_CORBER=12'd100; //8等分做colorbar显示 //X和Y坐标计数器 reg [11:0] xcnt; reg [11:0] ycnt; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin xcnt<=12'd0; end else if(xcnt>=VGA_HTT)begin xcnt<=12'd0; end else begin xcnt<=xcnt+1'b1; end end always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin ycnt<=12'd0; end else if(xcnt==VGA_HTT)begin if(ycnt>=VGA_VTT)begin ycnt<=12'd0; end else begin ycnt<=ycnt+1'b1; end end else begin ycnt<=ycnt; end end //行信号生成 always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin vga_hsy<=1'b0; end else if(xcnt<VGA_HST)begin vga_hsy<=1'b1; end else begin vga_hsy<=1'b0; end end //场信号生成 always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin vga_vsy<=1'b0; end else if(ycnt<VGA_VST)begin vga_vsy<=1'b1; end else begin vga_vsy<=1'b0; end end //显示有效区域标志信号生成 reg vga_vaild;//显示区域内,该信号为高电平 always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin vga_vaild<=1'b0; end else if(xcnt>=(VGA_HST+VGA_HBP)&&xcnt<(VGA_HST+VGA_HBP+VGA_HVT)&& ycnt>=(VGA_VST+VGA_VBP)&&ycnt<(VGA_VST+VGA_VBP+VGA_VVT))begin vga_vaild<=1'b1; end else begin vga_vaild<=1'b0; end end //产生颜色逻辑 reg vga_rdb; reg vga_gdb; reg vga_bdb; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin vga_rdb=1'b0; vga_gdb=1'b0; vga_bdb=1'b0; end else if(xcnt==(VGA_HST+VGA_HBP))begin//绿色边框 vga_rdb=1'b0; vga_gdb=1'b1; vga_bdb=1'b0; end else if(xcnt==(VGA_HST+VGA_HBP+VGA_HVT-1'b1))begin//绿色边框 vga_rdb=1'b0; vga_gdb=1'b1; vga_bdb=1'b0; end else if(ycnt==(VGA_VST+VGA_VBP))begin//绿色边框 vga_rdb=1'b0; vga_gdb=1'b1; vga_bdb=1'b0; end else if(ycnt==(VGA_VST+VGA_HBP+VGA_VVT-4'd1))begin//绿色边框 vga_rdb=1'b0; vga_gdb=1'b1; vga_bdb=1'b0; end else if(xcnt<=VGA_HST+VGA_HBP+VGA_CORBER)begin//1个 vga_rdb=1'b0; vga_gdb=1'b0; vga_bdb=1'b0; end else if(xcnt<=VGA_HST+VGA_HBP+VGA_CORBER*4'd2)begin//2个 vga_rdb=1'b0; vga_gdb=1'b0; vga_bdb=1'b1; end else if(xcnt<=VGA_HST+VGA_HBP+VGA_CORBER*4'd3)begin//3个 vga_rdb=1'b0; vga_gdb=1'b1; vga_bdb=1'b0; end else if(xcnt<=VGA_HST+VGA_HBP+VGA_CORBER*4'd4)begin//4个 vga_rdb=1'b0; vga_gdb=1'b1; vga_bdb=1'b1; end else if(xcnt<=VGA_HST+VGA_HBP+VGA_CORBER*4'd5)begin//5个 vga_rdb=1'b1; vga_gdb=1'b0; vga_bdb=1'b0; end else if(xcnt<=VGA_HST+VGA_HBP+VGA_CORBER*4'd6)begin//6个 vga_rdb=1'b1; vga_gdb=1'b0; vga_bdb=1'b1; end else if(xcnt<=VGA_HST+VGA_HBP+VGA_CORBER*4'd7)begin//7个 vga_rdb=1'b1; vga_gdb=1'b1; vga_bdb=1'b0; end else if(xcnt<=VGA_HST+VGA_HBP+VGA_CORBER*4'd8)begin//8个 vga_rdb=1'b1; vga_gdb=1'b1; vga_bdb=1'b1; end else begin vga_rdb=1'b0; vga_gdb=1'b0; vga_bdb=1'b0; end end assign vga_r = vga_vaild ? vga_rdb :1'b0; assign vga_g = vga_vaild ? vga_gdb :1'b0; assign vga_b = vga_vaild ? vga_bdb :1'b0; endmodule