毕业设计 基于FPGA的图形控制器的设计

设计一个VGA控制器,用VHDL硬件语言描述。功能要求:控制VGA出彩条和字符汉字。
邮箱[email protected]

已发至您邮箱,请注意查收。

---------------------------------------------------------------------------------------------

--实验题号    : lab5

--项目名称    : VGA实验

--文件名      : VGA_640480.vhd

--作者        : 

--班号.       :  

--创建日期    : 

--目标芯片    : EP1C6Q240C8

--电路模式    : 模式5

--演示说明    : 输入时钟为clock0,50Mhz

--    输出接VGA

--    请在通电后先reset

--    键1信号上升沿改变字符颜色

--    键2信号上升沿改变字符

--    键3开关控制字符y方向移动

--    键4开关控制字符x方向移动

--    键5开关控制字符闪烁

--    键6开关控制字符边框

--    键8 reset

---------------------------------------------------------------------------------------------

library ieee;

use  ieee.std_logic_1164.all;

use  ieee.std_logic_unsigned.all;

use  ieee.std_logic_arith.all;

entity vga640480 is

  port(

   address     : out STD_LOGIC_VECTOR(11 DOWNTO 0); --连接ROM地址

   reset             : in  STD_LOGIC;

   q         : in STD_LOGIC;  --ROM数据的返回

            clk            : buffer std_logic; --分频后的25M时钟

   clk_0          : in  STD_LOGIC; --50M时钟输入

   r,g,b          : out STD_LOGIC; --颜色信号

   hs,vs         : out STD_LOGIC; --行同步、场同步信号

   in_frame_switch   : in STD_LOGIC;  --加边框开关

   in_blink_switch   : in STD_LOGIC;  --闪烁开关

   in_enlarge_switch : in STD_LOGIC;  --大字符开关

   in_num_change   : in STD_LOGIC;  --改变显示的数值

   in_color_change   : in STD_LOGIC;  --改变显示的颜色

   in_v_x,in_v_y     : in STD_LOGIC;   --显示字符的是否向x,y方向位移

  vga_syn : out STD_LOGIC;

  vga_clk : out STD_LOGIC;

  vga_blank : out STD_LOGIC

 

 );

end vga640480;

architecture behavior of vga640480 is

 signal r1,g1,b1 : std_logic;     

 signal hs1,vs1  : std_logic;    

 signal vector_x : std_logic_vector(9 downto 0);  --扫描点X坐标

 signal vector_y : std_logic_vector(8 downto 0);  --扫描点Y坐标

 signal target_x : std_logic_vector(9 downto 0);  --字符左上角X坐标

 signal target_y : std_logic_vector(8 downto 0);  --字符左上角Y坐标

 signal blink : std_logic;      --闪烁控制信号

 Shared Variable scancount,blinkcount : integer;  --扫描点计数、扫屏数计数

 Shared Variable color : std_logic_vector(2 downto 0); --当前显示颜色rgb

 Shared Variable num : std_logic_vector(1 downto 0); --当前显示数字

 

begin

 -----------------------------------------------------------------------

  process(clk_0) --对50M输入信号二分频

    begin

        if(clk_0'event and clk_0='1') then 

             clk <= not clk;

        end if;

  end process;

 -----------------------------------------------------------------------

  process(clk,reset) --行区间像素数(含消隐区)

  begin

    if reset='0' then

      vector_x <= (others=>'0');

    elsif clk'event and clk='1' then

      if vector_x=799 then

       vector_x <= (others=>'0');

      else

       vector_x <= vector_x + 1;

      end if;

    end if;

  end process;

  -----------------------------------------------------------------------

  process(clk,reset) --场区间行数(含消隐区)

  begin

    if reset='0' then

      vector_y <= (others=>'0');

    elsif clk'event and clk='1' then

      if vector_x=799 then

       if vector_y=524 then

         vector_y <= (others=>'0');

       else

         vector_y <= vector_y + 1;

       end if;

      end if;

    end if;

  end process;

 

  -----------------------------------------------------------------------

  process(clk,reset) --行同步信号产生(同步宽度96,前沿16)

  begin

    if reset='0' then

     hs1 <= '1';

    elsif clk'event and clk='1' then

      if vector_x>=656 and vector_x<752 then

       hs1 <= '0';

      else

       hs1 <= '1';

      end if;

    end if;

  end process;

 

 -----------------------------------------------------------------------

  process(clk,reset) --场同步信号产生(同步宽度2,前沿10)

  begin

    if reset='0' then

      vs1 <= '1';

    elsif clk'event and clk='1' then

      if vector_y>=490 and vector_y<492 then

       vs1 <= '0';

      else

       vs1 <= '1';

      end if;

    end if;

  end process;

 -----------------------------------------------------------------------

  process(clk,reset) --行同步信号输出

  begin

    if reset='0' then

      hs <= '0';

    elsif clk'event and clk='1' then

      hs <=  hs1;

    end if;

  end process;

 -----------------------------------------------------------------------

  process(clk,reset) --场同步信号输出

  begin

    if reset='0' then

      vs <= '0';

    elsif clk'event and clk='1' then

      vs <=  vs1;

    end if;

  end process;

 

 -----------------------------------------------------------------------

  process(clk,reset) --扫描点计数、扫屏数计数,以及闪烁控制、字符显示位置控制

  begin

    if reset='0' then

   target_x <= "0101000000";

   target_y <= "011100000";

   blink <= '0';

   scancount := 0;

   blinkcount := 0;

    elsif clk'event and clk='1' then

   scancount := scancount + 1;

   if scancount >= 525*800 then

    blinkcount := blinkcount + 1;

    if (blinkcount = 20) then

     blink <= NOT blink;

     blinkcount := 0;

    end if;

    target_x <= target_x + in_v_x;

    target_y <= target_y + in_v_y;

    if target_x>=640-32 then 

     target_x <= "0000000000";

    end if;

    if target_y>=480-32 then 

     target_y <= "000000000";

    end if;

    scancount := 0;

   end if;

    end if;

  end process;

 -----------------------------------------------------------------------

 process(in_num_change,reset) --改变数字

 begin

  if reset='0' then

   num := "00";  

  elsif in_num_change'event and in_num_change='1' then

   num := num + "01";

    end if;

 end process;

 

 ----------------------------------------------------------------------- 

 process(in_color_change,reset) --改变颜色

 begin

  if reset='0' then

   color := "001";  

  elsif in_color_change'event and in_color_change='1' then

   if color="111" then

    color := "001";

   else

    color := color + "001";

   end if;

    end if;

 end process;

 

 ---------------------------------------------------- 

 process(reset,clk,vector_x,vector_y) -- XY坐标定位控制

  Variable temp_x : std_logic_vector(9 downto 0);

  Variable temp_y : std_logic_vector(8 downto 0);

  Variable size : integer;

 begin  

  if reset='0' then

           r1  <= '0';

     g1 <= '0';

     b1 <= '0'; 

  elsif(clk'event and clk='1')then

   if in_enlarge_switch='0' then --控制字符边长

    size := 32;

   else

    size := 64;

   end if;

   --字符边框

   if ((vector_x = target_x - 1 or vector_x = target_x + size + 3) and vector_y >= target_y - 1 and vector_y <= target_y + size + 3)

    or ((vector_y = target_y - 1 or vector_y = target_y + size + 3) and vector_x >= target_x - 1 and vector_x <= target_x + size + 3) then

     r1 <= color(2) AND (blink or NOT in_blink_switch) AND in_frame_switch;

     g1 <= color(1) AND (blink or NOT in_blink_switch) AND in_frame_switch;

     b1 <= color(0) AND (blink or NOT in_blink_switch) AND in_frame_switch;

    else

     r1 <= '0';

     g1 <= '0';

     b1 <= '0';

   end if;

   --显示字符

   if vector_x >= target_x and vector_x < target_x + size and vector_y >= target_y and vector_y < target_y + size then

    temp_y := vector_y-target_y;

    temp_x := vector_x-target_x;

    if in_enlarge_switch='0' then

     address <= num & temp_y(4 downto 0) & temp_x(4 downto 0);

    else

     address <= num & temp_y(5 downto 1) & temp_x(5 downto 1);

    end if;

    if q = '0' then

     r1 <= color(2) and (blink or NOT in_blink_switch);

     g1 <= color(1) and (blink or NOT in_blink_switch);

     b1 <= color(0) and (blink or NOT in_blink_switch);

    else

     r1  <= '0';

     g1 <= '0';

     b1 <= '0'; 

    end if;

   end if;

  end if;  

 end process; 

 -----------------------------------------------------------------------

 --色彩输出

 r <= r1 and hs1 and vs1;

 g <= g1 and hs1 and vs1;

    b <= b1 and hs1 and vs1;

 vga_blank <= hs1 and vs1;

 vga_clk <= clk;

 vga_syn <= '0';

 

end behavior;

温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-04-18
现代电子设计技术的核心是EDA技术。EDA技术依赖功能强大的计算机,在EDA软件工具平台上,以硬件描述语言VHDL为系统逻辑描述的主要手段完成系统设计。
利用可编程器件CPLD/FPGA实现VGA彩色显示控制器在工业现场中有许多实际应用。以硬件描述语言VHDL对可编程器件进行功能模块设计、仿真综合,可实现VGA显示控制器显示各种图形、图像、文字,并实现了动画效果。

VGA 接口及设计参数
VGA接口是与显示器进行通信的唯一接口。通过CPLD/FPGA器件对RGB信号、行同步信号、场同步信号等信号的控制,并参照有关标准,可以实现对VGA显示器的控制。由此可见,了解接口标准,控制时序和设定恰当的参数是系统设计的关键。
参照VGA主要参数的工业标准,像素输出频率为25.175MHz;行频(线频率)为31.469KHz;场频(刷新率)为59.94Hz。参数设计原理以及行同步信号(Ts)与显示信号(Tdis)的关系如图1所示。

VGA 图像控制器的设计方案
VGA图像控制器是一个较大的数字系统。采用模块化设计原则,借鉴自顶而下的程序设计思想,进行功能分离并按层次设计。将VHDL硬件描述语言设计与原理图设计相结合,逐一对每个功能模块进行仿真,使顶层VGA图像控制器的模块实体仿真综合得以顺利通过。VGA控制器主要由以下模块组成:消隐模块,显示模块,分频模块,网格生成模块,汉字显示模块,图像控制模块,动画生成模块,LPM-ROM调用模块,EEPROM调用模块等。功能模块的VHDL设计如下。
消隐模块
消隐模块是整个显示控制器的关键部分,显示模块、汉字模块、彩条模块、网格模块、动画控制模块、LPM-ROM调用模块等都由消隐模块控制,并且行同步信号(HS)和场同步信号(VS)都由该模块产生。
图2是消隐模块的仿真结果。由于CLK频率相当高,像素速率也很高,为了观察HS、VS信号,适当缩小了波形比例。其中, C[9..0]为像素坐标值,L[8..0]为扫描线信号,也就是像素的横坐标。
显示模块
显示模块是整个显示控制器的重要组成部分。各个模块的输出数据都要经过该模块处理后送到显示器。显示模块在VGA显示控制器中起着至关重要的作用。
显示模块的VHDL设计如下:
ARCHITECTURE BEHAVE OF DISPLAY IS
SIGNAL GRB: STD_LOGIC_VECTOR(3 DOWNTO 1);
BEGIN
GRB(2)<=GRBP(2) AND HS AND VS;
GRB(3)<=GRBP(3) AND HS AND VS;
GRB(1)<=GRBP(1) AND HS AND VS;
R<=GRB(2);
G<=GRB(3);
B<=GRB(1);
END BEHAVE;
显示模块仿真波形如图3所示。
GRBP为三原色数据信号,由模式控制模块产生;行同步信号HS由消隐模块产生;场同步信号VS由消隐模块产生。输出的R、G、B信号分别为红色、绿色、蓝色信号。
显示模块的输出信号直接连到VGA接口,它是控制器与显示器进行通信的桥梁。该模块以VHDL语言实现,该模块中的结构体描述一共只用了6条语句。而要实现同样的功能,一般操作系统的视频卡驱动程序需要冗长的代码去描述。由此可见,VHDL语言具有很大的优越性。
汉字生成模块
汉字生成模块可实现在显示器上显示汉字、字符等。字模信息可以利用字模提取软件来获得,得到了汉字的字模信息后,可以通过屏幕上的横坐标和纵坐标按照字模信息定义像素的颜色,这样就可以显示任何字体、任何点阵的汉字,并根据需要决定汉字在屏幕上的位置。至于英文以及其他任何符号的显示原理与汉字显示的原理一样。
网格生成模块
网格生成模块用来编辑各种图形。网格生成模块的实现原理与汉字生成模块、彩条发生器类似,在像素的横坐标和纵坐标控制下,实现各种网格图形的生成。网格生成模块所产生的九种图形送显示器依次显示,所以可以看到网格由小到大逐渐变化,虽然不是动画效果,但每秒一帧画面的速度依然使图像连续变化呈现出动感。网格以及背景的颜色也可以随意设置。每帧图像的速率可由时钟来控制。
网格生成模块的主要功能是编辑各种图形,因此本模块可以按照设计方案生成各种各样的图形。网格的选择是一种比较简单的图像编辑,该部分虽然名为网格生成模块,但实际上可以编辑出多种彩色图像。
LPM-ROM调用模块
LPM是参数可设置模块库。本设计中调用了三个LPM-ROM,其中两个用来存放汉字信息,另一个用来存放动态彩条信息。调用LPM-ROM模块,一个重要的问题就是*.mif文件的生成。这里文件生成借助字模提取软件和WORD编辑功能。设置好参数后,生成元件作为自定义元件库中的元件以供调用。
LPM-ROM调用模块为不使用外挂ROM而建立字库提供了条件,直接调用LPM模块,可以大大提高效率。通过LPM-ROM可以在显示器上显示汉字、字符等。
EEPROM调用模块
EEPROM调用模块是设计的难点之一。该模块实现了对系统外挂的两个EEPROM(W27E040和W27C020)的访问,通过该模块可以使显示器显示各种各样的彩色图像。
图像模式控制模块
图像模式控制模块也是该数字系统的关键部分,它的主体部分是一个功能齐全的数据选择器(32选1)。
该模块由一个32选1数据选择器和一个32进制可逆计数器组成。可逆计数器控制端为EC、DIR、CLR,MD为计数时钟信号。计数结果(即对应一种模式)是数据选择器进行选择的依据,通过对可逆计数器的控制,可以实现对模式选择的控制。
图像控制模块共产生了32种模式,由计数器实现了对模式的有效控制。其实图像控制模块功能还可以进一步扩展。计数器输出为8比特,实际共有255种模式,在输入的32个信号中,可以将它们其中的任意几个进行再处理,如叠加、异或(棋盘格生成就是横彩条与竖彩条的异或而实现的)、相与等等,这样就可以产生成千上万种图形的输出。
VGA控制器中的十余个模块都采用VHDL语言实现,每个模块在功能仿真无误后生成元件,放入元件库中,由顶层原理图调用各个模块(元件)。VGA图像控制器整体设计经过调试,通过了MAX+PLUSⅡ的功能仿真、时序仿真以及硬件仿真综合,在VGA显示器上实现了所设计的各种功能。