-- -- swfsm.vhd -- Version: v1.1 -- library IEEE; use IEEE.STD_LOGIC_1164.all; entity SWFSM is port ( CLK : in STD_LOGIC; MR : in STD_LOGIC; L, S : in STD_LOGIC;-- L-"light", S-"start/stop" of my wristwatch EN, RUN, RST: out STD_LOGIC-- outputs to monitor "latch enable", "run stop", and "reset" conditions ); end SWFSM; architecture SWFSM_BEH of SWFSM is type STATE_TYPE is (RESET, -- main reset state START_T, START, -- timer running and display enabled STOP_T, STOP, -- timer stopped and display enabled LAP_T, LAP, -- entering lap mode. display latched and timer running L_STOP_T, L_STOP, -- lap mode. display latched and timer stopped L_START_T, L_START, -- lap mode. display latched and timer running R_STOP_T, -- return to regular mode. timer stopped and display enabled R_START_T, -- return to regular mode. timer running and display enabled RESET_T -- transitional reset state ); -- states with _T are transitional states, -- meaning these occur when buttons are pressed down (before they are released) attribute enum_encoding : string; attribute enum_encoding of STATE_TYPE: type is --using grey code "0000 " & -- RESET "0001 " & -- START_T "0011 " & -- START "0010 " & -- STOP_T "0110 " & -- STOP "0111 " & -- LAP_T "0101 " & -- LAP "0100 " & -- L_STOP_T "1100 " & -- L_STOP "1101 " & -- L_START_T "1111 " & -- L_START "1110 " & -- R_STOP_T "1010 " & -- R_START_T "1011"; -- RESET_T signal NS: STATE_TYPE; -- signals for current and next states signal QOUT: STD_LOGIC_VECTOR (18 downto 0); -- 100 Hz clock begin with NS select EN<= '0' when LAP_T | LAP | L_STOP_T | L_STOP | L_START_T | L_START, --LAP mode '1' when others; --this means the (display) latch is transparent with NS select RUN<= '0' when RESET | STOP_T | STOP | L_STOP_T | L_STOP | R_STOP_T | RESET_T, '1' when others; -- the counter is running with NS select RST<= '1' when RESET, -- the counter is reset '0' when others; COMB_PROC: process (CLK, MR) -- This is the combinational part begin if (MR = '0') then NS <= RESET; elsif (CLK'event and CLK = '1') then case NS is -- case # appears in () to aid in coding when RESET => -- (1) if S = '0' then NS <= START_T; -- go to this state when the S button is pressed; else NS <= RESET; -- otherwise stay in this same state. end if; when START_T => -- (2)transitional states have the outputs of the corresponding stable state. if S = '1' then NS <= START; else NS <= START_T; end if; when START => -- (3)stable state if S = '0' then NS <= STOP_T; -- stopping the timer has higher priority than.. elsif L = '0' then NS <= LAP_T; -- going to lap mode else NS <= START; end if; when STOP_T => -- (4)transitional state if S = '1' then NS <= STOP; else NS <= STOP_T; end if; when STOP => -- (5)stable state if S = '0' then NS <= START_T; -- starting the timer (again) has higher priority than.. elsif L = '0' then NS <= RESET_T; -- resetting it. else NS <= STOP; end if; -- We are entering Lap mode when LAP_T => -- (6)transitional state if L = '1' then NS <= LAP; else NS <= LAP_T; end if; when LAP => -- (7)stable state if S = '0' then NS <= L_STOP_T; -- stop the timer, but stay in lap mode elsif L = '0' then NS <= R_START_T; -- return to regular start state, but keep timer running else NS <= LAP; end if; when L_STOP_T => -- (8)transitional state if S = '1' then NS <= L_STOP; else NS <= L_STOP_T; end if; when L_STOP => -- (9)stable state if S = '0' then NS <= L_START_T; -- startup the timer again inside lap mode.. elsif L = '0' then NS <= R_STOP_T; -- or return to regular mode and display the timer's contents instead. else NS <= L_STOP; end if; when L_START_T => -- (10)transitional state if S = '1' then NS <= L_START; else NS <= L_START_T; end if; when L_START => -- (11)stable state if S = '0' then NS <= L_STOP_T; -- keep cycling between start and stop in lap mode, elsif L = '0' then -- utill L is pressed; then NS <= R_START_T; -- return to regular mode else NS <= L_START; end if; -- we are leaving lap mode when R_STOP_T => -- (12) if L = '1' then NS <= STOP; else NS <= R_STOP_T; end if; when R_START_T => -- (13)transitional state if L = '1' then NS <= START; else NS <= R_START_T; end if; when RESET_T => -- (14)transitional states have the outputs of the corresponding stable state. if L = '1' then NS <= RESET; -- go to this state when the L button is pressed; else NS <= RESET_T; -- otherwise stay in this same state. end if; end case; end if; end process; end SWFSM_BEH;