3 min read

Getting VGA output using VHDL and a Spartan-3AN board

Hi there! Have been busy busy and busy! And you know what that means! New Code!

We were given a homework to write a game for the Spartan-3AN board. Our team decided to write a Simon Says game.(http://en.wikipedia.org/wiki/Simon_(game)) I was responsible for writing the VGA output of the program. I must say it was fun! ( I split the post as there a lot of images in this post )

So there are a few things you must know first about the Spartan-3AN board. The VGA output actually looks like as below;

VGA connections for Spartan-3AN board

The top 510 Ohms is where you want your connections. You must also follow the standard connection guidelines for your UCF file. Your VGA connections must be as below;

VGA connection information

The other thing you must know is that the output does not have to be a std_logic_vector type unless you want lots of colors. Since the Simon Says game uses only a few colors ( 4 main colors ) I decided to go easy on the board and instead of std_logic_vector for color outputs I simply used std_logic.

You must always keep in mind that the CRT screen acts like as below;

Cathod ray tube scan

Below you will find a sample code that simply paints the screen… red! Why red you may ask? Because it’s my girlfriend's favorite color!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity clockmodule is
  port(clk50_in  : in std_logic;
       red_out   : out std_logic;
       green_out : out std_logic;
       blue_out  : out std_logic;
       hs_out    : out std_logic;
       vs_out    : out std_logic);
end clockmodule;

architecture Behavioral of clockmodule is

signal clk25              : std_logic;
signal horizontal_counter : std_logic_vector (9 downto 0);
signal vertical_counter   : std_logic_vector (9 downto 0);

begin

-- generate a 25Mhz clock
process (clk50_in)
begin
  if clk50_in'event and clk50_in='1' then
    if (clk25 = '0') then
      clk25 <= '1';
    else
      clk25 <= '0';
    end if;
  end if;
end process;

process (clk25)
begin
  if clk25'event and clk25 = '1' then
    if (horizontal_counter >= "0010010000" ) -- 144
    and (horizontal_counter < "1100010000" ) -- 784
    and (vertical_counter >= "0000100111" ) -- 39
    and (vertical_counter < "1000000111" ) -- 519
    then

     --here you paint!!
      red_out <= '1';
      green_out <= '0';
      blue_out <= '0';

    else
      red_out <= '0';
      green_out <= '0';
      blue_out <= '0';
    end if;
    if (horizontal_counter > "0000000000" )
      and (horizontal_counter < "0001100001" ) -- 96+1
    then
      hs_out <= '0';
    else
      hs_out <= '1';
    end if;
    if (vertical_counter > "0000000000" )
      and (vertical_counter < "0000000011" ) -- 2+1
    then
      vs_out <= '0';
    else
      vs_out <= '1';
    end if;
    horizontal_counter <= horizontal_counter+"0000000001";
    if (horizontal_counter="1100100000") then
      vertical_counter <= vertical_counter+"0000000001";
      horizontal_counter <= "0000000000";
    end if;
    if (vertical_counter="1000001001") then
      vertical_counter <= "0000000000";
    end if;
  end if;
end process;

end Behavioral;

Everything else is straight forward after this actually. All you have to do is to follow which point you are on. If you are good enough you can draw a simple Simon Says interface like below;

Simon Says VGA VHDL Screen