X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=dide_16.git;a=blobdiff_plain;f=bsp4%2FDesignflow%2Fsrc%2Fvga_driver_arc.vhd;fp=bsp4%2FDesignflow%2Fsrc%2Fvga_driver_arc.vhd;h=d875c0c3ad98b697c291373138cd91819a21df26;hp=0000000000000000000000000000000000000000;hb=8c5b21b5de3f142d7210146a850cf7689e05c543;hpb=9388b7667104acb1a8ca81816d94d5ae71cffcc0 diff --git a/bsp4/Designflow/src/vga_driver_arc.vhd b/bsp4/Designflow/src/vga_driver_arc.vhd new file mode 100644 index 0000000..d875c0c --- /dev/null +++ b/bsp4/Designflow/src/vga_driver_arc.vhd @@ -0,0 +1,404 @@ +------------------------------------------------------------------------------- +-- Title : vga_driver architecture +-- Project : LU Digital Design +------------------------------------------------------------------------------- +-- File : vga_driver.vhd +-- Author : Thomas Handl +-- Company : TU Wien +-- Created : 2004-12-15 +-- Last update: 2007-09-13 +------------------------------------------------------------------------------- +-- Description: generate hsync and vsync +------------------------------------------------------------------------------- +-- Copyright (c) 2004 TU Wien +------------------------------------------------------------------------------- +-- Revisions : +-- Date Version Author Description +-- 2004-12-15 1.0 handl Created +-- 2006-01-24 2.0 ST revised +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- LIBRARIES +------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_unsigned.all; +use IEEE.std_logic_arith.all; + +use work.vga_pak.all; + +------------------------------------------------------------------------------- +-- ARCHITECTURE +------------------------------------------------------------------------------- + +architecture behav of vga_driver is + + attribute syn_preserve : boolean; + attribute syn_preserve of behav : architecture is true; + + constant TIME_A : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "1100011111"; + constant TIME_B : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "0001011010"; + constant TIME_BC : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "0010000111"; + constant TIME_BCD : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "1100000111"; + + constant TIME_O : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "1000001000"; + constant TIME_P : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "0000000001"; + constant TIME_PQ : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "0000100001"; + constant TIME_PQR : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "1000000001"; + + signal h_sync : std_logic; + signal h_sync_next : std_logic; + + signal hsync_state : hsync_state_type; + signal hsync_state_next : hsync_state_type; + + signal h_enable_sig : std_logic; + signal h_enable_next : std_logic; + + signal set_hsync_counter : std_logic; + signal hsync_counter : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0); + signal hsync_counter_next : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0); + constant HSYN_CNT_MAX : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "1111111111"; + + signal column_counter_sig : std_logic_vector(COL_CNT_WIDTH-1 downto 0); + signal column_counter_next : std_logic_vector(COL_CNT_WIDTH-1 downto 0); + signal set_column_counter : std_logic; + + signal v_sync : std_logic; + signal v_sync_next : std_logic; + + signal vsync_state : vsync_state_type; + signal vsync_state_next : vsync_state_type; + + signal v_enable_sig : std_logic; + signal v_enable_next : std_logic; + + signal set_vsync_counter : std_logic; + signal vsync_counter : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0); + signal vsync_counter_next : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0); + constant VSYN_CNT_MAX : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "1111111111"; + + signal line_counter_sig : std_logic_vector(LINE_CNT_WIDTH-1 downto 0); + signal line_counter_next : std_logic_vector(LINE_CNT_WIDTH-1 downto 0); + signal set_line_counter : std_logic; + + + +begin + +---------------------------------------------------------------------------- +-- Column_Counter [0..639]: calculates column number for next pixel to be displayed +---------------------------------------------------------------------------- + + COLUMN_COUNT_syn: process(clk, reset, column_counter_next) + begin + if clk'event and clk = '1' then + if reset = RES_ACT then -- synchronous reset + column_counter_sig <= (others => '0'); + else + column_counter_sig <= column_counter_next; -- synchronous capture + end if; + end if; + end process; + + COLUMN_COUNT_next: process(set_column_counter, column_counter_sig) + begin + if set_column_counter = ENABLE then -- reset counter + column_counter_next <= (others => '0'); + else + if column_counter_sig < RIGHT_BORDER then + column_counter_next <= column_counter_sig + '1'; -- increment column + else + column_counter_next <= RIGHT_BORDER; -- ... but do not count beyond right border + end if; + end if; + end process; + +---------------------------------------------------------------------------- +-- Line_counter [0..479]: calculates line number for next pixel to be displayed +---------------------------------------------------------------------------- + + LINE_COUNT_syn: process(clk, reset, line_counter_next) + begin + if clk'event and clk = '1' then + if reset = RES_ACT then -- synchronous reset + line_counter_sig <= (others => '0'); + else + line_counter_sig <= line_counter_next; -- synchronous capture + end if; + end if; + end process; + + LINE_COUNT_next: process(set_line_counter, line_counter_sig, set_hsync_counter) + begin + if set_line_counter = ENABLE then -- reset counter + line_counter_next <= (others => '0'); + else + if line_counter_sig < BOTTOM_BORDER then + if set_hsync_counter = '1' then -- when enabled + line_counter_next <= line_counter_sig + '1'; -- ... increment line + else + line_counter_next <= line_counter_sig; + end if; + else + line_counter_next <= BOTTOM_BORDER; -- ... but do not count below bottom + end if; + end if; + end process; + + +---------------------------------------------------------------------------- +-- Hsync_Counter: generates time base for HSYNC State Machine +---------------------------------------------------------------------------- + + HSYNC_COUNT_syn: process(clk, reset, hsync_counter_next) + begin + if clk'event and clk = '1' then + if reset = RES_ACT then -- synchronous reset + hsync_counter <= (others => '0'); + else + hsync_counter <= hsync_counter_next; -- synchronous capture + end if; + end if; + end process; + + HSYNC_COUNT_next: process(set_hsync_counter, hsync_counter) + begin + if set_hsync_counter = ENABLE then -- reset counter + hsync_counter_next <= (others => '0'); + else + if hsync_counter < HSYN_CNT_MAX then + hsync_counter_next <= hsync_counter + '1'; -- increment time + else + hsync_counter_next <= HSYN_CNT_MAX; -- ... but do not count beyond max period + end if; + end if; + end process; + + +---------------------------------------------------------------------------- +-- HSYNC STATE MACHINE: generates hsync signal and controls hsync counter & column counter +---------------------------------------------------------------------------- + + HSYNC_FSM_syn: process (clk, reset) -- synchronous capture + begin + if clk'event and clk = '1' then + if reset = RES_ACT then + hsync_state <= RESET_STATE; + h_sync <= '1'; + v_enable_sig <= not(ENABLE); + else + hsync_state <= hsync_state_next; + h_sync <= h_sync_next; + v_enable_sig <= v_enable_next; + end if; + end if; + end process; + + HSYNC_FSM_next : process(hsync_state, hsync_counter, h_sync, v_enable_sig) -- next-state logic + begin -- default assignments + hsync_state_next <= hsync_state; -- ... hold current state + h_sync_next <= h_sync; -- ... and values + v_enable_next <= v_enable_sig; + + case hsync_state is + when RESET_STATE => + h_sync_next <= '0'; -- next signal values are defined here + v_enable_next <= not(ENABLE); + hsync_state_next <= B_STATE; -- ... as well as state transitions + when B_STATE => + h_sync_next <= '0'; + if hsync_counter = TIME_B then + hsync_state_next <= C_STATE; + end if; + -- C_STATE instead of D_STATE + when C_STATE => + h_sync_next <= '1'; + if hsync_counter = TIME_BC then + hsync_state_next <= pre_D_STATE; + end if; + when pre_D_STATE => + v_enable_next <= ENABLE; + hsync_state_next <= D_STATE; + -- D_STATE instead of C_STATE + when D_STATE => + v_enable_next <= ENABLE; + if hsync_counter = TIME_BCD then + hsync_state_next <= E_STATE; + end if; + when E_STATE => + v_enable_next <= not(ENABLE); + if hsync_counter = TIME_A then + hsync_state_next <= pre_B_STATE; + end if; + when pre_B_STATE => + h_sync_next <= '0'; + v_enable_next <= not(ENABLE); + hsync_state_next <= B_STATE; + when others => + null; + end case; + end process; + + HSYNC_FSM_out : process(hsync_state) -- output logic + begin + set_hsync_counter <= not(ENABLE); -- default assignments + set_column_counter <= not(ENABLE); + + case hsync_state is + when RESET_STATE => -- outputs for each state are defined here + set_hsync_counter <= ENABLE; + when pre_D_STATE => + set_column_counter <= ENABLE; + when pre_B_STATE => + set_hsync_counter <= ENABLE; + when others => + null; + end case; + end process; + + +---------------------------------------------------------------------------- +-- Vsync_Counter: generates time base for VSYNC State Machine +---------------------------------------------------------------------------- + + VSYNC_COUNT_syn: process(clk, reset, vsync_counter_next) + begin + if clk'event and clk = '1' then + if reset = RES_ACT then -- synchronous reset + vsync_counter <= (others => '0'); + else + vsync_counter <= vsync_counter_next; -- synchronous capture + end if; + end if; + end process; + + VSYNC_COUNT_next: process(set_vsync_counter, vsync_counter, set_hsync_counter) + begin + if set_vsync_counter = ENABLE then -- reset counter + vsync_counter_next <= (others => '0'); + else + if vsync_counter < VSYN_CNT_MAX then + if set_hsync_counter = '1' then -- if enabled + vsync_counter_next <= vsync_counter + '1'; -- ... increment time + else + vsync_counter_next <= vsync_counter; + end if; + else + vsync_counter_next <= VSYN_CNT_MAX; -- ... but do not count beyond max period + end if; + end if; + end process; + + +---------------------------------------------------------------------------- +-- VSYNC STATE MACHINE: generates vsync signal and controls vsync counter & line counter +---------------------------------------------------------------------------- + + VSYNC_FSM_syn : process (clk, reset) -- synchronous capture + begin + if clk'event and clk = '1' then + if reset = RES_ACT then + vsync_state <= RESET_STATE; + v_sync <= '1'; + h_enable_sig <= not(ENABLE); + else + vsync_state <= vsync_state_next; + v_sync <= v_sync_next; + h_enable_sig <= h_enable_next; + end if; + end if; + end process; + + VSYNC_FSM_next : process(vsync_state, vsync_counter, v_sync, h_enable_sig) + begin -- next state logic + vsync_state_next <= vsync_state; -- default assignments + v_sync_next <= v_sync; + h_enable_next <= h_enable_sig; + + case vsync_state is -- state transitions and next signals are defined here + when RESET_STATE => + v_sync_next <= '0'; + h_enable_next <= not(ENABLE); + vsync_state_next <= P_STATE; + when P_STATE => + v_sync_next <= '0'; + if vsync_counter = time_p then + vsync_state_next <= Q_STATE; + end if; + when Q_STATE => + v_sync_next <= '1'; + if vsync_counter = time_pq then + vsync_state_next <= pre_R_STATE; + end if; + when pre_R_STATE => + h_enable_next <= ENABLE; + vsync_state_next <= R_STATE; + when R_STATE => + h_enable_next <= ENABLE; + if vsync_counter = time_pqr then + vsync_state_next <= S_STATE; + end if; + when S_STATE => + h_enable_next <= not(ENABLE); + if vsync_counter = time_o then + vsync_state_next <= pre_P_STATE; + end if; + when pre_P_STATE => + v_sync_next <= '0'; + h_enable_next <= not(ENABLE); + vsync_state_next <= P_STATE; + when others => + null; + end case; + end process; + + VSYNC_FSM_out : process(vsync_state) + begin -- output logic + set_vsync_counter <= not(ENABLE); -- output values for each state defined here + set_line_counter <= not(ENABLE); + + case vsync_state is + when RESET_STATE => + set_vsync_counter <= ENABLE; + when pre_R_STATE => + set_line_counter <= ENABLE; + when pre_P_STATE => + set_vsync_counter <= ENABLE; + when others => + null; + end case; + end process; + + + +-- signal wiring for entity (introduced _sig to allow readback of output signals) + + column_counter <= column_counter_sig; + v_enable <= v_enable_sig; + line_counter <= line_counter_sig; + h_enable <= h_enable_sig; + + + hsync <= h_sync; + vsync <= v_sync; + + ----------------------------------------------------------------------------- + -- debug signals + ----------------------------------------------------------------------------- + d_hsync_state <= hsync_state; + d_vsync_state <= vsync_state; + d_hsync_counter <= hsync_counter; + d_vsync_counter <= vsync_counter; + d_set_hsync_counter <= set_hsync_counter; + d_set_vsync_counter <= set_vsync_counter; + d_set_column_counter <= set_column_counter; + d_set_line_counter <= set_line_counter; + +end behav; + +------------------------------------------------------------------------------- +-- END ARCHITECTURE +-------------------------------------------------------------------------------