视频图像阵列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=1024、d=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
=Var_Front_Porch and v_counter