VGA接口有15针,3排,每排5针。它是显卡上应用最广泛的接口类型,传输红/绿/蓝以及同步信号(水平以及垂直信号)。

如图所示,

FPGA VGA显示

 

VGA显示器一般从左上角开始扫描,从左向右逐点扫描,每扫描完一行后,向下移动一行,继续扫描。在这期间,CRT对电子束进行消隐,每行结束时,用行同步信号进行同步;当扫描完所有行,形成一帧图片时,用场同步信号进行同步,使扫描回到屏幕的左上角,同时进行消隐,开始下一帧。

完成一行扫描的时间为水平扫描时间,倒数为行频率;完成一帧的扫描时间为垂直扫描时间,倒数为场频率。基本上用场频率来表示显示屏的刷新频率。

当计算设计的FPGA的时钟频率时需要考虑到无效显示区。以[email protected](60Hz)为例,每场对应806个行周期,其中768为显示行。每显示行包括1344点时钟,其中1024点为有效显示区。由此可知:需要时钟频率:806*1344*60约65MHz。

FPGA VGA显示

行时序/场时序都需要同步脉冲(Sync a)、显示后沿(Back porch b)、显示时序段(Display interval c)和显示前沿(Front porch d)四部分。VGA工业标准显示模式要求:行同步,场同步都为负极性,即同步脉冲要求是负脉冲。

FPGA VGA显示

采用16位高彩色,R5G6B5。电路上用电阻网络实现RGB数字信号到模拟的转换。

FPGA VGA显示

网络关系如下:

VGA_R=8*(2^4 * VGA_R4 + 2^3 * VGA_R3 + 2^2 * VGA_R2 + 2^1 * VGA_R1 + 2^0 * VGA_R0 )

其余分量同理

 

软件设计部分,描述上述的vga时序图

always @ (posedge vga_clk)
       if(~rst_n)    x_cnt <= 1;
       else if(x_cnt == LinePeriod) x_cnt <= 1;
       else x_cnt <= x_cnt+ 1;
         
//----------------------------------------------------------------
////////// 水平扫描信号hsync,hsync_de产生
//----------------------------------------------------------------
always @ (posedge vga_clk)
   begin
       if(~rst_n) hsync_r <= 1'b1;
       else if(x_cnt == 1) hsync_r <= 1'b0;            //产生hsync信号
       else if(x_cnt == H_SyncPulse) hsync_r <= 1'b1;
         
                  
        if(~rst_n) hsync_de <= 1'b0;
       else if(x_cnt == Hde_start) hsync_de <= 1'b1;    //产生hsync_de信号
       else if(x_cnt == Hde_end) hsync_de <= 1'b0;    
    end

//----------------------------------------------------------------
////////// 垂直扫描计数
//----------------------------------------------------------------
always @ (posedge vga_clk)
       if(~rst_n) y_cnt <= 1;
       else if(y_cnt == FramePeriod) y_cnt <= 1;
       else if(x_cnt == LinePeriod) y_cnt <= y_cnt+1;

//----------------------------------------------------------------
////////// 垂直扫描信号vsync, vsync_de产生
//----------------------------------------------------------------
always @ (posedge vga_clk)
  begin
       if(~rst_n) vsync_r <= 1'b1;
       else if(y_cnt == 1) vsync_r <= 1'b0;    //产生vsync信号
       else if(y_cnt == V_SyncPulse) vsync_r <= 1'b1;
         
        if(~rst_n) vsync_de <= 1'b0;
       else if(y_cnt == Vde_start) vsync_de <= 1'b1;    //产生vsync_de信号
       else if(y_cnt == Vde_end) vsync_de <= 1'b0;     
  end

 

hsync_de /vsync_de 为有效像素的标志位,高电平有效

接下来输入需要显示图片的数据

always @(negedge vga_clk)  
    if(~rst_n) begin 
        vga_r_reg<=0; 
        vga_g_reg<=0;
        vga_b_reg<=0;         
    end
   else
        begin     
              vga_r_reg<=xxxxxx;    //需要的数据 
             vga_g_reg<=xxxxxxx;   //需要的数据
             vga_b_reg<=xxxxxx;    //需要的数据
         end    

vga_r_reg/ vga_g_reg/vga_b_reg  输入相应的像素,*****注意在下降沿触发*****。

 

 

 

 

 

 

 

相关文章: