--- /dev/null
+-------------------------------------------------------------------------------
+-- Title : vga_driver architecture
+-- Project : LU Digital Design
+-------------------------------------------------------------------------------
+-- File : vga_driver.vhd
+-- Author : Thomas Handl
+-- Company : TU Wien
+-- Created : 2004-12-15
+-- Last update: 2006-01-24
+-------------------------------------------------------------------------------
+-- 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;
+ 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;
+ 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
+-------------------------------------------------------------------------------