after slot5
[dide_16.git] / bsp4 / Designflow / src / vga_driver_arc.vhd
diff --git a/bsp4/Designflow/src/vga_driver_arc.vhd b/bsp4/Designflow/src/vga_driver_arc.vhd
new file mode 100644 (file)
index 0000000..d875c0c
--- /dev/null
@@ -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
+-------------------------------------------------------------------------------