VGA Display VHDL Code

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

library lpm;
use lpm.lpm_components.all;

entity vgadisp is

    port (
        clock : in std_logic;
        data : in std_logic_vector(7 downto 0);
        address : out std_logic_vector(7 downto 0);
        dtreq : out std_logic;
        hsync, vsync : out std_logic;
        rgb : out std_logic_vector(2 downto 0)
    );

end vgadisp;
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
-- car_router behavioural architecture definition
--------------------------------------------------------------------------------
architecture behaviour of vgadisp is

subtype counter is integer range 0 to 1023;
subtype nibble is integer range 0 to 15;

-- constants for the timing of one scan line (# of dot clock cycles)
constant hsync_start : counter := 0;
constant hsync_end : counter := 94;
constant hscan_start : counter := 139;
constant hscan_end : counter := 780;
constant hline_end : counter := 800;

-- constants for the timing of one field (# of scan lines)
constant vsync_start : counter := 0;
constant vsync_end : counter := 1;
constant vscan_start : counter := 34;
constant vscan_end : counter := 514;
constant field_end : counter := 524;

-- constants for timing and size of "low-res pixel" block
constant bl_read : nibble := 3;
constant bl_latch : nibble := 5;
constant bl_width : nibble := 9;

constant dread_start : counter := hscan_start - bl_read - 1;
constant dread_end : counter := hscan_end - bl_read - 1;

-- global signals
signal dot_count, row_count : counter;
signal block_col : nibble;
signal shaft, floor : std_logic_vector(2 downto 0);
signal areg, dreg : std_logic_vector(7 downto 0);

begin

    -- port maps
    -- (none)

    with dot_count select
        hsync <= '0' when hsync_start to hsync_end,
        '1' when others;

    with row_count select
        vsync <= '0' when vsync_start to vsync_end,
        '1' when others;

    with row_count select
        shaft <= "000" when 234 to 243,
        "001" when 254 to 263,
        "010" when 274 to 283,
        "011" when 294 to 303,
        "100" when 244 to 253,
        "101" when 264 to 273,
        "110" when 284 to 293,
        "111" when others;

    vgascan : process

    begin
        wait until rising_edge(clock);

        -- compute waveform counter state
        if dot_count < hline_end then
            dot_count <= dot_count + 1;
        else
            dot_count <= 0;
            if row_count < field_end then
                row_count <= row_count + 1;
            else
                row_count <= 0;
            end if;
        end if;

        -- retrieve data
        if dot_count > dread_start and dot_count < dread_end then
            if block_col < bl_read then
                address <= areg;
                dtreq <= '1';
                block_col <= block_col + 1;
            elsif block_col = bl_read then
                dtreq <= '0';
                dreg <= data;
                floor <= areg(2 downto 0);
                block_col <= block_col + 1;
            elsif block_col < bl_width then
                block_col <= block_col + 1;
            else
                areg <= areg + 1;
                block_col <= 0;
            end if;
        else
            block_col <= 0;
            areg <= shaft (1 downto 0) & "000000";
        end if;

        -- compute rgb outputs
        if dot_count > hscan_start and dot_count < hscan_end then
            if shaft < "100"
            or ( floor = "000" and shaft /= "111" ) then
                rgb <= dreg(6 downto 4);
            else
                rgb <= "111";
            end if;
        else
            rgb <= "000";
        end if;

    end process vgascan;

end behaviour;