VHDL-VGA

Problem
The beat bearing drum sequencer interface involves a VGA LCD monitor video. The problem is how to drive the monitor without a PC.

Conceive
The goal is to design a beat boarding board with out a PC, without software. The concept is to use FPGA technology to create a circuit that displays only what is necessary for the beat bearing project.

Design
This design started off with this hardware:
 * Papilo Spartan3E 250K FPGA
 * VGA connector on a logic start board
 * initial VGA VHDL Project that this was started from

Howard Community College Spring 2014 ENES-245 This file is part of the Chapter 19 lab Description: Date: 3/20/14 Current Status: Complete Original Author: unknown

Modification Description: Edited SwitchesLinkedToColor project to include all 256 colors (controlled by the 8 switches); displays a 					50x50 px box on a screen, move the box across the screen with the joystick Date: 3/27/14 Author: King Carmichael III

library ieee; use ieee.std_logic_1164.all;

entity vga_generator is       port(                ext_CLK, reset: in std_logic;                SWITCH: in std_logic_vector(7 downto 0);                VGA_HSYNC, VGA_VSYNC: out std_logic;					 JOY_RIGHT, JOY_LEFT, JOY_UP, JOY_DOWN: in STD_LOGIC;                rgb: out std_logic_vector(7 downto 0)        ); end vga_generator;

architecture arch of vga_generator is       -- vga clock component dcm_32_to_50p35 port(                       clkin_in : in std_logic;                                  clkfx_out : out std_logic;                        clkin_ibufg_out : out std_logic;                        clk0_out : out std_logic                ); end component; signal clk: std_logic;

signal rgb_reg: std_logic_vector(7 downto 0); signal video_on, antisquare: std_logic; begin inst_dcm_32_to_50p35: dcm_32_to_50p35 port map(                       clkin_in => ext_CLK,                        clkfx_out => clk,                        clkin_ibufg_out => open,                        clk0_out => open                );

vga_sync_unit: entity work.vga_sync port map(                       clk => clk,                        reset => reset,                        hsync => VGA_HSYNC,                        vsync => VGA_VSYNC,                        video_on => video_on,								antivid => antisquare,								right => JOY_RIGHT,								left => JOY_LEFT,								up => JOY_UP,								down => JOY_DOWN,                        p_tick => open,                        pixel_x => open,                        pixel_y => open                );

process(clk, reset) begin if reset = '1' then rgb_reg <= (others => '0'); elsif clk'event and clk = '1' then rgb_reg <= SWITCH(7 downto 0); end if; end process;

rgb <= rgb_reg when video_on = '1' and antisquare = '0' else NOT rgb_reg when video_on = '1' and antisquare = '1' else "00000000"; end arch;

Howard Community College Spring 2014 ENES-245 This file is part of the Chapter 19 lab Description: VGA sync - tells determines when the video will be on, syncs timing of pixel ticks (when to scan horizontally/vertically 					and when to restart), etc. Date: 3/20/14 Current Status: Complete Original Author: unknown

Modification Description: Move the box across the screen with the joystick. Second block element on (second video_on) when block is at the end of pixel range. Date: 3/27/14 Author: King Carmichael III Email:

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity vga_sync is       port(                clk, reset: in std_logic;                hsync, vsync: out std_logic;                video_on, antivid, p_tick: out std_logic;					 right, left, up, down: in std_logic;                pixel_x, pixel_y: out std_logic_vector(9 downto 0)        ); end vga_sync;

architecture arch of vga_sync is       -- VGA 640x480 -- horizontal timings, in pixels constant h_display_area: integer := 640; constant h_front_porch: integer := 16; constant h_sync: integer := 96; constant h_back_porch: integer := 48; -- vertical timings, in lines constant v_display_area: integer := 480; constant v_front_porch: integer := 10; constant v_sync: integer := 2; constant v_back_porch: integer := 33; -- derived horizontal constants constant hsync_start: integer := h_display_area + h_front_porch; constant hsync_end: integer := hsync_start + h_sync; constant end_of_line: integer := hsync_end + h_back_porch - 1; -- derived vertical constants constant vsync_start: integer := v_display_area + v_front_porch; constant vsync_end: integer := vsync_start + v_sync; constant end_of_frame: integer := vsync_start + v_back_porch - 1; -- mod-2 counter signal mod2_reg, mod2_next: std_logic; -- sync counters signal v_count_reg, v_count_next: unsigned(9 downto 0); signal h_count_reg, h_count_next: unsigned(9 downto 0); -- output buffer signal v_sync_reg, h_sync_reg: std_logic; signal v_sync_next, h_sync_next: std_logic; -- status signals signal h_end, v_end, pixel_tick: std_logic; --30 bit counter signal count: std_logic_vector(29 downto 0) := (others => '0'); --pixel region to display signal pixx, pixy: unsigned(10 downto 0);-- := (others => '0');		--Need at least 10 bits to have decimal number 799 signal neg: std_logic; --		 constant pixx_set: integer := 424;		--initial test to display rectangle --		 constant pixy_set: integer := 286;		--initial test to display rectangle begin -- registers process(clk, reset) begin if reset = '1' then mod2_reg <= '0'; v_count_reg <= (others => '0'); h_count_reg <= (others => '0'); v_sync_reg <= '0'; h_sync_reg <= '0'; elsif clk'event and clk = '1' then mod2_reg <= mod2_next; v_count_reg <= v_count_next; h_count_reg <= h_count_next; v_sync_reg <= v_sync_next; h_sync_reg <= h_sync_next; end if; end process; -- mod-2 circuit to generate 25.125MHz enable tick mod2_next <= not mod2_reg; -- 25.125MHz pixel tick pixel_tick <= '1' when mod2_reg = '1' else '0'; -- status h_end <= '1' when h_count_reg = end_of_line else '0';       v_end <= '1' when v_count_reg = end_of_frame else '0';       -- mod-800 horizontal sync counter process(h_count_reg, h_end, pixel_tick) begin if pixel_tick = '1' then if h_end = '1' then h_count_next <= (others => '0'); else h_count_next <= h_count_reg + 1; end if; else h_count_next <= h_count_reg; end if; end process; -- mod-525 vertical sync counter process(v_count_reg, h_end, v_end, pixel_tick) begin if pixel_tick = '1' and h_end = '1' then if v_end = '1' then v_count_next <= (others => '0'); else v_count_next <= v_count_reg + 1; end if; else v_count_next <= v_count_reg; end if; end process; -- hsync and vsync, buffered to avoid glitch h_sync_next <= '1' when hsync_start <= h_count_reg and h_count_reg < hsync_end else '0';       v_sync_next <= '1' when vsync_start <= v_count_reg and v_count_reg < vsync_end else '0';		 --Block controls process(clk)--pixel_tick)		 begin					 if rising_edge(clk) then								count <= count + 1;								if count = 200000 then		--change value to change how fast block moves									count <= (others => '0');									if right = '0' and pixx < 591 then										pixx <= pixx + 1;									elsif left = '0' and pixx > 0 then										pixx <= pixx - 1;									elsif up = '0' and pixy > 0 then										pixy <= pixy - 1;									elsif down = '0' and pixy < 431 then										pixy <= pixy + 1;									end if;								end if;                end if;        end process;		  -- video on/off        video_on <=                '1' when h_count_reg < 50 + pixx and h_count_reg > pixx		--pixx and pixy +51 because rectangle is 50x50 pixels							and v_count_reg < 50 + pixy and v_count_reg > pixy else                '0';					 --original code - displayed a rectangle the size of the screen --					 '1' when h_count_reg < h_display_area and v_count_reg < v_display_area else --               '0';		  neg <= '1' when pixx = 0 else '1' when pixx = 591 else '1' when pixy = 0 else '1' when pixy = 431 else '0';       -- output signals hsync <= h_sync_reg; vsync <= v_sync_reg; antivid <= neg; pixel_x <= std_logic_vector(h_count_reg); pixel_y <= std_logic_vector(v_count_reg); p_tick <= pixel_tick; end arch;

NET ext_CLK         LOC="P89"  | IOSTANDARD=LVTTL | PERIOD=31.25ns;               # CLK

NET VGA_VSYNC   LOC="P85"  | IOSTANDARD=LVTTL;                                # B0 NET VGA_HSYNC    LOC="P83"  | IOSTANDARD=LVTTL;                                # B1 NET "rgb<7>" LOC = "P78"  | IOSTANDARD=LVTTL; NET "rgb<6>" LOC = "P71" | IOSTANDARD=LVTTL; NET "rgb<5>" LOC = "P68" | IOSTANDARD=LVTTL; NET "rgb<4>" LOC = "P66" | IOSTANDARD=LVTTL; NET "rgb<3>" LOC = "P63" | IOSTANDARD=LVTTL; NET "rgb<2>" LOC = "P61" | IOSTANDARD=LVTTL; NET "rgb<1>" LOC = "P58" | IOSTANDARD=LVTTL; NET "rgb<0>" LOC = "P54" | IOSTANDARD=LVTTL;

NET SWITCH(0)   LOC="P91"  | IOSTANDARD=LVTTL;                                # C0 NET SWITCH(1)    LOC="P92"  | IOSTANDARD=LVTTL;                                # C1 NET SWITCH(2)    LOC="P94"  | IOSTANDARD=LVTTL;                                # C2 NET SWITCH(3)    LOC="P95"  | IOSTANDARD=LVTTL;                                # C3 NET SWITCH(4)    LOC="P98"  | IOSTANDARD=LVTTL;                                # C4 NET SWITCH(5)    LOC="P2"   | IOSTANDARD=LVTTL;                                # C5 NET SWITCH(6)    LOC="P3"   | IOSTANDARD=LVTTL;                                # C6 NET SWITCH(7)    LOC="P4"   | IOSTANDARD=LVTTL;                                # C7

Implement
The goal is to simulate this video with out using a PC running some program like processing or visual basic. So the switches on the logic start board are used to simulate one row of the beat bearing board.

The switches add a white explosion underneath the blue squares.

Squares are used instead of circles because implementing a circuit that does the math would not fit on such a small FPGA.

Operate

 * 1) Connect a papilo 250K FPGA with a logic start circuit board to a USB file to a computer that has the papilo boot loader installed.
 * 2) Connect a VGA cable from the logic start board to a monitor.
 * 3) Apply power to both.
 * 4) Download this bit file.
 * 5) Right mouse on the bit file and send it to the papilo.

Demo

 * video
 * presentation

Next Steps
(need 6 pins free on Papilio)
 * Turn squares off totally and have an two step explosion of color
 * Create test program to test and exercise each row
 * Use putty through usb cable to configure speed of bar, colors of squares
 * Connect to arduino serial out to change configuration
 * Physically connect to beat bearing board and read column of four switches