library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity test_function is Port ( clk : in std_logic; SWITCH : in std_logic_vector(3 downto 0); BTN_NORTH : in std_logic; BTN_SOUTH : in std_logic; BTN_WEST : in std_logic; BTN_EAST : in std_logic; LED : inout std_logic_vector(7 downto 0)); end test_function; architecture behavioral of test_function is -- eigene Typen: type state_ty is (all_in, run, pattern1, pattern2, hold, count, reverse, reset, btnError); -- interne Signale: signal state, next_state : state_ty := count; signal tempCounter1 : std_logic_vector(7 downto 0) := B"0000_0001"; signal tempCounter2 : std_logic_vector(7 downto 0) := B"0000_0001"; signal intCLK : std_logic; signal clk_delay : std_logic_vector(23 downto 0):= X"000000"; --################################################################# --# FUNCTION shift a bit-vector # --################################################################# function shift (direction : in string; inputVct : in std_logic_vector) return std_logic_vector is -- verschiebt die Bits des Eingangsvektors um ein Bit in die gewünschte Richtung variable shifted_vct : std_logic_vector(inputVct'range); begin if direction = "right" then for i in inputVct'range loop if i<=6 then shifted_vct(i) := inputVct(i+1); else shifted_vct(inputVct'high) := inputVct(inputVct'low); end if; end loop; elsif direction = "left" then shifted_vct(inputVct'high downto inputVct'low+1) := inputVct(inputVct'high-1 downto inputVct'low); -- shifted_bv(bv2shift'length-1 downto 1) := bv2shift(bv2shift'length-2 downto 0); shifted_vct(inputVct'low) := inputVct(inputVct'length-1); end if; return shifted_vct; end function shift; --################################################################# --# PROCEDURE time delay # --################################################################# procedure delay (dlyTime : in integer)is variable ABM : bit; begin if intCLK ='1' then -- intCLK ~ 1/3sec for i in 1 to 3*dlyTime loop null; end loop; end if; end procedure; --################################################################# --# PROCEDURE flash leds # --################################################################# procedure flash (frequency : in string; repeat : in integer; signal flashedLED : out std_logic_vector)is begin for i in 1 to 3 loop if frequency = "fl" then -- flashing (<2sec), hier entstehen später noch andere Frequenzen flashedLED <= B"1111_1111"; delay(50); flashedLED <= B"0000_0000"; --(others=>'0') delay(50); end if; end loop; end procedure; --################################################################# --# PROCESS internal clock generator # --################################################################# begin --architecture clk_pr : process (clk, clk_delay) begin if clk'event and clk = '1' then clk_delay <= clk_delay + 1; end if; intCLK <= clk_delay(23); end process clk_pr; input_pr : process (SWITCH, BTN_NORTH, BTN_SOUTH, BTN_WEST, BTN_EAST) variable btns : std_logic_vector(7 downto 0) := BTN_NORTH & BTN_SOUTH & BTN_WEST & BTN_EAST & SWITCH; begin btns := BTN_NORTH & BTN_SOUTH & BTN_WEST & BTN_EAST & SWITCH; -- muss hier wiederholt bzw. zugewiesen werden, weil beim ersten Durchlauf Null und wird es daraufhin wegrationalisiert wird. case btns is -- Prozess liest die Schalter-Aktivität aus weist entsprechende Variablen (Signale) zu. when "10000000" | "00000000" => next_state <= reset; when "01000000" => next_state <= all_in; when "00100000" => next_state <= pattern1; when "00010000" => next_state <= pattern2; when "00001000" => next_state <= run; when "00000100" => next_state <= reverse; when "00000010" => next_state <= count; when "-------1" => next_state <= hold; when others => next_state <= btnError; end case; end process input_pr; sync_pr : process (intclk) is -- bei jeder steigenden Flanke wird die Variablen-Typ "state" aktualisiert. begin -- könnte man auch nach case btns beschrteiben, aber im FPGA wird effizienterweise nur mit getakteten Prozessen gearbeitet: if rising_edge(intclk) then -- -> "state" ändert sich immer nur getaktet = synchron state <= next_state; end if; end process sync_pr; out_pr : process (state, tempCounter1, tempCounter2) is -- Prozess codiert die LED-Aktivität. begin -- Anweisung werden je nach Inhalt der Variable "state" ausgeführt. case state is when reset => LED <= (others=>'0'); when all_in => LED <= (others=>'1'); when pattern1 => LED <= "11010101"; when pattern2 => LED <= "10011001"; when run | reverse => LED <= tempCounter1; when count => LED <= tempCounter2; when hold => LED <= LED; when btnError => flash("fl", 3, LED); when others => end case; end process out_pr; --################################################################# --# PROCESS count action # --################################################################# count_pr : process (intCLK) -- realisiert "run", "count" und "reverse". begin if rising_edge(intclk) then case state is when run => tempCounter1 <= shift("right", tempCounter1); when reverse => tempCounter1 <= shift("left", tempCounter1); when count => tempcounter2 <= tempcounter2 + 1; -- binär hochzählen when others => end case; end if; end process count_pr; end behavioral;