FPGA NES: VGA (Part 2)

Previously a basic VGA controller was designed that had the capability to display a solid color across an entire computer monitor. This post builds on that design in an attempt to verify that the controller is able to correctly display more advanced patterns. In this example the code for the clock sub-circuit remained unchanged. However the color generator code was hacked up to create a moving 100 pixel horizontal and vertical bar. Color selection still works as before with the upper two bits now being used to enable or disable either bar. The animation of the bars works fairly well, however both bars are expected to be a solid color which is not the case as shown in the image below.



I’ve found the bug.  It turns out I was not shutting off pixel color when the active pixel left the boundaries of the screen.  The code has been modified with the changes from line 73-77. I believe the problem is related to the monitor expecting an absence of data during H-Blank.  It looks as though the monitor may be setting the black level by averaging the voltages measured during H-Blank.  A fade to black would occur with a persistent input signal if this were the case.  This also explains why the vertical bar is unaffected.

The updated color generator code is provided below. The code added for the animation timing is pretty sketchy, but this was just thrown together as a proof of concept so it’ll do. The only glaring problem with this test is the is the fact that the horizontal bar fades to black instead of displaying a solid color. I’ve also noticed that both bars will occasionally flicker when bouncing, but I’m going to ignore this problem for the time being and focus on the fading color. As before the code described here is available for download at the bottom of this post. I will append updates as any problem(s) are found and fixed.

[cc lang="vhdl"]
Library IEEE;
USE IEEE.STD_LOGIC_Unsigned.all;

        Clock,Reset : in STD_LOGIC;
        pixel : in STD_LOGIC_VECTOR(7 downto 0);
        pixelActive : in STD_LOGIC;
        row,column : in STD_LOGIC_VECTOR(0 to 9);
        animate : in STD_LOGIC;
        VSync, HSync : in STD_LOGIC;
        Red, Green, Blue : out STD_LOGIC_VECTOR(7 downto 0)
end VGAColor;

Architecture structure of VGAColor is
    signal Red_sig,Green_sig,Blue_sig : STD_LOGIC_VECTOR(7 downto 0);
    signal animateCounter : STD_LOGIC_VECTOR (0 to 5);
    signal horizontalStart : STD_LOGIC_VECTOR (0 to 9);
    signal verticalStart : STD_LOGIC_VECTOR (0 to 9);
    signal horzAdd : integer := 1;
    signal vertAdd : integer := 1;
    constant pixelCount  : integer := 640;
    constant rowCount : integer := 480;

begin process(Clock, Reset)
        if (Reset = '1') then
            Blue_sig <= "00000000";
            Red_sig <= "00000000";
            Green_sig <= "00000000";
        elsif (Clock'event and Clock = '1' ) then
            if(animate = '1' and VSync = '0' and HSync = '0') then
                if animateCounter = "111111" then
                    if  horizontalStart = 0 then
                        horzAdd  horizontalStart and column < (horizontalStart+100) and pixel(7) = '1') or (row > verticalStart and row < verticalStart+100 and pixel(6)='1') then
                if pixelActive = '1' then
                    if ((pixel(0) = '1') and (pixel(1) = '1')) then
                        Blue_sig <= "11111111";
                    elsif pixel(0) = '1' then
                        Blue_sig <= "01010101";
                    elsif pixel(1) = '1' then
                        Blue_sig <= "10101010";
                        Blue_sig <= "00000000";
                    end if;

                    if ((pixel(2) = '1') and (pixel(3) = '1')) then
                        Green_sig <= "11111111";
                    elsif pixel(2) = '1' then
                        Green_sig <= "01010101";
                    elsif pixel(3) = '1' then
                        Green_sig <= "10101010";
                        Green_sig <= "00000000";
                    end if;

                    if ((pixel(4) = '1') and (pixel(5) = '1')) then
                        Red_sig <= "11111111";
                    elsif pixel(4) = '1' then
                        Red_sig <= "01010101";
                    elsif pixel(5) = '1' then
                        Red_sig <= "10101010";
                        Red_sig <= "00000000";
                    end if;
                    Blue_sig <= "00000000";
                    Red_sig <= "00000000";
                    Green_sig <= "00000000";
                end if;
                Blue_sig <= "00000000";
                Red_sig <= "00000000";
                Green_sig <= "00000000";
            end if;
        end if;
    end process;

    Red <= Red_sig;
    Green <= Green_sig;
    Blue <= Blue_sig;
end structure;

Related Posts:
FPGA NES: VGA (Part 1)
[download id="5"]

Leave a Reply

Your email address will not be published. Required fields are marked *