视频图像传输与显示(5)——视频图像阵列VGA及其时序的VHDL实现

视频图像阵列VGA及其时序的VHDL实现


1. VGA概念

VGA(Video Graphics Array,视频图形阵列)是IBM在1987年随PS/2一起推出的使用模拟信号的一种视频传输标准,在当时具有分辨率高、显示速率快、颜色丰富等优点,在彩色显示器领域得到了广泛的应用。VGA最早指的是显示器640x480这种显示模式,后经过VESA(Video ElectronicsStandards Association,频电子标准协会)的VSIS (Video signal standard,视频信号标准)规范扩充,以支持更高的分辨率。尽管对于现今的个人电脑已十分过时,VGA仍然是最多制造商共同支持的一个低标准。个人电脑在加载自己的独特驱动程式之前,都必须支持VGA标准。例如,微软Windows系列产品的开机画面仍然使用VGA显示模式。


2. VGA接口描述

VGA接口是一种D型接口,共有15pin ,分成3排,每排5个,非对称分布。



引脚1、2、3分别为红、绿、蓝三基色模拟电压,范围为0~0.714Vpp,0V代表无色,0.714V代表满色。一些非标准显示器使用的是 1Vpp的满色电平。三基色源端即终端匹配电阻都是75Ω。

水平同步和垂直同步为数字信号,TTL电平。

显示器标识信号是可选信号,但是不用这些信号就无法获取当前显示器的信息,不能实现高级管理功能。这些信号线遵循VESA的DDC(Display Data Channel,显示数据通道相关标准。


3. VGA时序分析

以640x480@60Hz的标准VGA信号为例。扫描从屏幕的左上方开始,从左到右,每扫完一行,用行同步进行同步,电子束回到左边下一行的开始位置,期间对电子束进行消隐。扫描完所有行后,再用场同步信号进行同步,电子束回到屏幕左上方,期间对电子束进行消隐,预备下一场的扫描。

尽管分辨率为640x480,VGA在实际工作中并不是每行扫描640个点,每场扫描480行。实际上每行有800个像素点,每场有525行。每行包括行同步时间a(96点)、行消隐后肩b(48点)、有效像素点c(640点)和行消隐前肩d(16点)。每场包括同步时间h(2行)、场消隐后肩i(33行)、有效像素行j(480行)和场消隐前肩k(10行)。


所以,点像素的 时钟频率为800x525x60=25.2MHz。

VGA的行同步线和场同步线并不是必须的,根据同步信号不同,VGA接口可以分为:

3线同步:绿同步,即在绿色模拟信号中复合了场行同步信号;

4线同步:三基色信号+复合行场同步信号;

5线同步:三基色信号+行场同步信号。

3线同步模式波形示意图如下所示




4. DDC与EDID介绍

PC机可以通过VGA的I2C总线来获取显示器的相关信息,这对I2C总线即被称为显示数据通道DDC(Display Data Channel),DDC通信中传输的显示器设备数据被称为外部显示设备标识数据EDID(Extended Display Identification Data )。EDID是一种VESA标准数据格式,基本信息主要有监视器名称、分辨率、最大图像尺寸、颜色特征、出厂设置时间、频率范围限制等。

每个显示器不一定只有一个EDID。现在的显示器功能很强大,通常都提供多种视频接口,常见的有VGA、DVI、HDMI、Display Port等,由于每种接口的特性和带宽不同,使得不同接口的EDID也不同。使用哪个接口,PC读到的就是哪个接口的EDID。对于一台有DDC功能的显示器,Windows操作系统会在开机时将其产品属性信息读出,然后根据这些信息进行最优化配置。在Windows操作系统可以把厂商的基本信息显示出来,告知用户这是一台即插即用的显示器,用户可根据需要随意调整系统的显示模式。而对于没有DDC功能的显示器,则没有上述所有的方便功能,仅仅能作为无法识别的监视器使用而已。

基本EDID信息为128字节,另外还可以附加128个字节EDID扩展块(VDIF),EDID中有专门的标志位指示VDIF块的存在。


通过SoftMCCS软件可以读取EDID数据文件,Phoenix EDID Designer软件可以用来分析EDID数据。





5. VGA时序的VHDL实现

下面的VHDL程序实现输出白、红、橙、黄、绿、青、蓝、紫彩条的VGA时序。参数如下:

分辨率:1024*768 @ 60 Mhz

像素时钟:65 MHz

行时序:a=136、b=160、c=1024d=24

场时序:h=6、i=29、 j=768、 k=3

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity VGA_Gen_768p is
     generic(
		Hor_Sync_Polarity  :   std_logic  :='0';
		Var_Sync_Polarity  :   std_logic  :='0';
		Blk_Sync_Polarity  :   std_logic  :='0'
		);
	port(
		pix_clk     :   in    std_logic;  --65M
		rst_n       :   in    std_logic;
		
		red         :   out   std_logic_vector(7 downto 0);
		green       :   out   std_logic_vector(7 downto 0);
		blue        :   out   std_logic_vector(7 downto 0);
		h_sync      :   out   std_logic;
		v_sync      :   out   std_logic;
		blank       :   out   std_logic		
 	);
end VGA_Gen_768p;

architecture rtl of VGA_Gen_768p is

     signal h_counter     :   integer range 0 to 2047;	
     signal v_counter     :   integer range 0 to 2047;
	
	constant  Hor_Valid_Pixel :  integer:= 1024;
	constant  Hor_Front_Porch :  integer:= 24;
     constant  Hor_Sync_Time   :  integer:= 136;
	constant  Hor_Back_Porch  :  integer:= 160;
	constant  Hor_Total_Pixel :  integer:= 1344;
	
	constant  Var_Valid_Line :  integer:= 768;
	constant  Var_Front_Porch:  integer:= 3;
     constant  Var_Sync_Time  :  integer:= 6;
	constant  Var_Back_Porch :  integer:= 29;
	constant  Var_Tolal_Line :  integer:= 806;
	
	constant Colour_Bar_Width:  integer :=128;  --Hor_Valid_Pixel/8
begin

  
  --h_counter,v_counter
	Pixel_CNT:process(rst_n,pix_clk)
	begin
		if(rst_n='0') then
			h_counter  <=  0;
			v_counter  <=  0;
		elsif(rising_edge(pix_clk)) then
			if(h_counter < Hor_Total_Pixel-1) then
				h_counter <= h_counter+1; 
			else
				h_counter <= 0;
				if(v_counter < Var_Tolal_Line-1) then
					v_counter <= v_counter+1;
				else
					v_counter <= 0;
				end if;
			end if;
		end if;
	end process;
	
	
	--h_sycn gen
	H_SYNC_GEN:process(rst_n,pix_clk) 
	begin
		if(rst_n='0') then
			h_sync  <=  not Hor_Sync_Polarity; 
		elsif(rising_edge(pix_clk)) then
			if(h_counter>=Hor_Front_Porch and h_counter<Hor_Front_Porch+Hor_Sync_Time) then
				h_sync  <=  Hor_Sync_Polarity;
			else
				h_sync  <=  not Hor_Sync_Polarity;
			end if;
		end if;
	end process;
	
	--y_sycn gen
	Y_SYNC_GEN:process(rst_n,pix_clk) 
	begin
		if(rst_n='0') then
			v_sync  <=  not Var_Sync_Polarity; 
		elsif(rising_edge(pix_clk)) then
			if(v_counter>=Var_Front_Porch and v_counter<Var_Front_Porch+Var_Sync_Time) then
				v_sync  <=  Var_Sync_Polarity;
			else
				v_sync  <=  not Var_Sync_Polarity;
			end if;
		end if;
	end process;
	
	--RGB Gen
	process(rst_n,pix_clk) 
	begin
		if(rst_n='0') then
			red     <=    x"00";
			green   <=    x"00";
			blue    <=    x"00";
			blank   <=    not Blk_Sync_Polarity;
		elsif(rising_edge(pix_clk)) then
			if(h_counter<Hor_Front_Porch+Hor_Sync_Time+Hor_Back_Porch or v_counter<Var_Front_Porch+Var_Sync_Time+Var_Back_Porch) then
				red     <=    x"00";
				green   <=    x"00";
				blue    <=    x"00";
				blank   <=    Blk_Sync_Polarity;
				
			elsif(h_counter<Hor_Front_Porch+Hor_Sync_Time+Hor_Back_Porch+Colour_Bar_Width) then
				red     <=    x"FF";  --白 
				green   <=    x"FF";
				blue    <=    x"FF";
				blank   <=    not Blk_Sync_Polarity;
			
			elsif(h_counter< Hor_Front_Porch+Hor_Sync_Time+Hor_Back_Porch+Colour_Bar_Width+Colour_Bar_Width) then
				red     <=    x"FF";  --红  
				green   <=    x"00";
				blue    <=    x"00";
				blank   <=    not Blk_Sync_Polarity;
				
			elsif(h_counter< Hor_Front_Porch+Hor_Sync_Time+Hor_Back_Porch+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width) then
				red     <=    x"FF";  --橙  
				green   <=    x"7F";
				blue    <=    x"00";
				blank   <=    not Blk_Sync_Polarity;
				
			elsif(h_counter< Hor_Front_Porch+Hor_Sync_Time+Hor_Back_Porch+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width) then
				red     <=    x"FF";  --黄  
				green   <=    x"FF";
				blue    <=    x"00";
				blank   <=    not Blk_Sync_Polarity;
				
			elsif(h_counter< Hor_Front_Porch+Hor_Sync_Time+Hor_Back_Porch+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width) then
				red     <=    x"00";  --绿
				green   <=    x"FF";
				blue    <=    x"00";
				blank   <=    not Blk_Sync_Polarity;
			
			elsif(h_counter<Hor_Front_Porch+Hor_Sync_Time+Hor_Back_Porch+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width) then
				red     <=    x"00"; --青
				green   <=    x"FF";
				blue    <=    x"FF";
				blank   <=    not Blk_Sync_Polarity;
				
			elsif(h_counter<Hor_Front_Porch+Hor_Sync_Time+Hor_Back_Porch+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width+Colour_Bar_Width) then
				red     <=    x"00"; --蓝 
				green   <=    x"00";
				blue    <=    x"FF";
				blank   <=    not Blk_Sync_Polarity;
				
			else
				red     <=    x"8B";  --紫色
				green   <=    x"00";
				blue    <=    x"FF";
				blank   <=    not Blk_Sync_Polarity;
			end if;
		end if;
	end process;
end rtl;






 
 

  • 5
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值