-- -- VHDL Architecture FACT_FAD_lib.led_controller.bahavior -- -- Created: -- by - dneise.UNKNOWN (E5B-LABOR6) -- at - 11:04:17 04.01.2011 -- -- using Mentor Graphics HDL Designer(TM) 2009.2 (Build 10) -- LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; use ieee.STD_LOGIC_UNSIGNED.all; library FACT_FAD_lib; use FACT_FAD_lib.fad_definitions.all; ENTITY led_controller IS GENERIC( HEARTBEAT_PWM_DIVIDER : integer := 500; WAITING_DIVIDER : integer := 500000000 ); PORT( CLK : IN std_logic; -- LED outs -- inverted logic green : OUT std_logic; amber : OUT std_logic; red : OUT std_logic; additional_flasher_out : OUT std_logic; -- status INs trigger : IN std_logic; -- when trigger is received green should toggle w5300_reset : in std_logic; trigger_veto : in std_logic; refclk_too_high : in std_logic; refclk_too_low : in std_logic; socks_waiting : IN std_logic; socks_connected: IN std_logic --heartbeat_en : IN std_logic ); END ENTITY led_controller; -- ARCHITECTURE bahavior OF led_controller IS type states is ( INIT, WAITING, CONNECTED); signal state,next_state : states := INIT; -- noninverted logic signal green_loc : std_logic := '1'; -- on in order to show power signal amber_loc : std_logic := '0'; --default off signal red_loc : std_logic := '0'; --default off signal flasher : std_logic; signal heartbeat_counter: integer range 0 to HEARTBEAT_PWM_DIVIDER - 1 := 0; constant ontime_update : integer := 100; signal ontime_update_counter : integer range 0 to ontime_update - 1 := 0; signal on_time: integer range 0 to HEARTBEAT_PWM_DIVIDER - 1 := 0; constant ontime_divider : integer range 0 to HEARTBEAT_PWM_DIVIDER - 1 := 1; signal delta_ontime : integer range 0 to HEARTBEAT_PWM_DIVIDER - 1 := 1; signal DIR : std_logic := '0'; BEGIN -- since leds have inverted logic, the outs are inverted at this point. green <= not green_loc; --amber <= not amber_loc; amber <= w5300_reset; --red <= not red_loc; red <= not trigger_veto; additional_flasher_out <= flasher; -- MAIN FSM: go to next state if rising edge FSM_Registers: process(CLK) begin if Rising_edge(CLK) then state <= next_state; end if; end process; -- MAIN FSM FSM_logic: process(state, socks_connected, socks_waiting) begin next_state <= state; case state is when INIT => green_loc <= '0'; if (socks_waiting = '1') then next_state <= WAITING; else next_state <= INIT; end if; when WAITING => green_loc <= flasher; if (socks_connected = '1') then next_state <= CONNECTED; else next_state <= WAITING; end if; when CONNECTED => green_loc <= '1'; if (socks_connected = '0') then next_state <= INIT; else next_state <= CONNECTED; end if; end case; end process FSM_logic; -- if trigger is received red_loc toggles trigger_proc : process (trigger) begin if Rising_edge(trigger) then red_loc <= not red_loc; end if; end process trigger_proc; -- heartbeat process: -- as long as nothing else is to be done for the red led -- it will show a ~2Hz heartbeat -- can be switched off with heartbeat_en high heartbeat : process (CLK) begin if rising_edge(CLK) then if (heartbeat_counter < HEARTBEAT_PWM_DIVIDER - 1) then heartbeat_counter <= heartbeat_counter + 1; else heartbeat_counter <= 0; end if; -- calculate the change in on_time -- if the change is too small... then change at least by 1. if ( on_time / (2*ontime_divider) = 0) then delta_ontime <= 1; else delta_ontime <= on_time / (2*ontime_divider); end if; if (heartbeat_counter = 0) then if (ontime_update_counter < ontime_update - 1) then ontime_update_counter <= ontime_update_counter + 1; else ontime_update_counter <= 0; -- set new on_time if (DIR = '0') then -- increase on_time if (on_time + delta_ontime < HEARTBEAT_PWM_DIVIDER - 1) then on_time <= on_time + delta_ontime; else on_time <= HEARTBEAT_PWM_DIVIDER - 1; DIR <= '1'; end if; else -- DIR is '1' -- count down if (on_time - delta_ontime > 0) then on_time <= on_time - delta_ontime; else on_time <= 0; DIR <= '0'; end if; end if; end if; end if; if (heartbeat_counter = 0) then amber_loc <= '1'; end if; if (heartbeat_counter = on_time) then amber_loc <= '0'; end if; end if; end process heartbeat; -- sock_waiting_flasher process: sock_waiting_flasher : process (CLK) variable Y: integer range 0 to WAITING_DIVIDER - 1; begin if rising_edge(CLK) then if (Y < WAITING_DIVIDER - 1) then Y := Y + 1; else Y := 0; end if; if (Y = 0) then flasher <= '1'; end if; if (Y = WAITING_DIVIDER / 2) then flasher <= '0'; end if; end if; end process sock_waiting_flasher; END ARCHITECTURE bahavior;