--- Source http://esd.cs.ucr.edu/labs/tutorial/fsm.vhd
-----------------------------------------------------
-- VHDL FSM (Finite State Machine) modeling
-- (ESD book Figure 2.7)
-- by Weijun Zhang, 04/2001
--
-- FSM model consists of two concurrent processes
-- state_reg and comb_logic
-- we use case statement to describe the state 
-- transistion. All the inputs and signals are
-- put into the process sensitive list.  
-----------------------------------------------------

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

-----------------------------------------------------

ENTITY seq_design IS
	PORT (
		a : IN STD_LOGIC;
		clock : IN STD_LOGIC;
		reset : IN STD_LOGIC;
		x : OUT STD_LOGIC
	);
END seq_design;

-----------------------------------------------------

ARCHITECTURE FSM OF seq_design IS

	-- define the states of FSM model

	TYPE state_type IS (S0, S1, S2, S3);
	SIGNAL next_state, current_state : state_type;

BEGIN

	-- cocurrent process#1: state registers
	state_reg : PROCESS (clock, reset)
	BEGIN

		IF (reset = '1') THEN
			current_state <= S0;
		ELSIF (clock'event AND clock = '1') THEN
			current_state <= next_state;
		END IF;

	END PROCESS;

	-- cocurrent process#2: combinational logic
	comb_logic : PROCESS (current_state, a
		)
	BEGIN

		-- use case statement to show the 
		-- state transistion

		CASE current_state IS

			WHEN S0 => x <= '0';
				IF a
					= '0' THEN
					next_state <= S0;
				ELSIF a
					= '1' THEN
					next_state <= S1;
				END IF;

			WHEN S1 => x <= '0';
				IF a
					= '0' THEN
					next_state <= S1;
				ELSIF a
					= '1' THEN
					next_state <= S2;
				END IF;

			WHEN S2 => x <= '0';
				IF a
					= '0' THEN
					next_state <= S2;
				ELSIF a
					= '1' THEN
					next_state <= S3;
				END IF;

			WHEN S3 => x <= '1';
				IF a
					= '0' THEN
					next_state <= S3;
				ELSIF a
					= '1' THEN
					next_state <= S0;
				END IF;

			WHEN OTHERS =>
				x <= '0';
				next_state <= S0;

		END CASE;

	END PROCESS;

END FSM;
