library IEEE; use IEEE.std_logic_1164.all; entity tail_lights is port ( reset : in std_logic; clk : in std_logic; left_in : in std_logic; right_in : in std_logic; haz : in std_logic; l_a : out std_logic; l_b : out std_logic; l_c : out std_logic; r_a : out std_logic; r_b : out std_logic; r_c : out std_logic ); end tail_lights; architecture beh of tail_lights is type fsm_state_type is (idle, left1, left2, left3, right1, right2, right3, all_on); signal fsm_state, fsm_next_state : fsm_state_type; constant MAX_CNT : natural := 4; signal clock_counter : natural range 0 to MAX_CNT-1; begin cnt_clk: process (reset, clk) is begin if (reset = '1') then clock_counter <= 0; elsif (rising_edge(clk)) then if (clock_counter < MAX_CNT-1) then clock_counter <= clock_counter + 1; else clock_counter <= 0; end if; end if; end process; fsm_state_reg: process (reset, clk) is begin if (reset = '1') then fsm_state <= idle; elsif (rising_edge(clk)) then fsm_state <= fsm_next_state; end if; end process; fsm_next_state_logic: process (left_in, right_in, haz, fsm_state, clock_counter) is begin case fsm_state is when idle => if (left_in='1' and right_in='0' and haz='0') then fsm_next_state <= left1; elsif (left_in='0' and right_in='1' and haz='0') then fsm_next_state <= right1; elsif ((left_in='1' and right_in='1') or haz='1') then fsm_next_state <= all_on; else fsm_next_state <= idle; end if; when left1 => if (clock_counter = MAX_CNT-1) then if (haz = '0') then fsm_next_state <= left2; else fsm_next_state <= all_on; end if; else fsm_next_state <= left1; end if; when left2 => if (clock_counter = MAX_CNT-1) then if (haz = '0') then fsm_next_state <= left3; else fsm_next_state <= all_on; end if; else fsm_next_state <= left2; end if; when left3 => if (clock_counter = MAX_CNT-1) then fsm_next_state <= idle; else fsm_next_state <= left3; end if; when right1 => if (clock_counter = MAX_CNT-1) then if (haz = '0') then fsm_next_state <= right2; else fsm_next_state <= all_on; end if; else fsm_next_state <= right1; end if; when right2 => if (clock_counter = MAX_CNT-1) then if (haz = '0') then fsm_next_state <= right3; else fsm_next_state <= all_on; end if; else fsm_next_state <= right2; end if; when right3 => if (clock_counter = MAX_CNT-1) then fsm_next_state <= idle; else fsm_next_state <= right3; end if; when all_on => if (clock_counter = MAX_CNT-1) then fsm_next_state <= idle; else fsm_next_state <= all_on; end if; when others => fsm_next_state <= idle; end case; end process; l_a <= '1' when (fsm_state = left1 or fsm_state = left2 or fsm_state= left3 or fsm_state = all_on) else '0'; l_b <= '1' when (fsm_state = left2 or fsm_state= left3 or fsm_state = all_on) else '0'; l_c <= '1' when (fsm_state= left3 or fsm_state = all_on) else '0'; r_a <= '1' when (fsm_state = right1 or fsm_state = right2 or fsm_state= right3 or fsm_state = all_on) else '0'; r_b <= '1' when (fsm_state = right2 or fsm_state= right3 or fsm_state = all_on) else '0'; r_c <= '1' when (fsm_state= right3 or fsm_state = all_on) else '0'; end beh;