library ieee;
use ieee.std_logic_1164.all;

-- moore: value of output Z depends on value of CURRENT_STATE.
-- state machine design style 1
-- One unclocked process to hold combinational elements. 
-- One clocked process to hold state register. 

entity MOORE is
  port(RESET, X, CLK : in std_ulogic; Z: out std_ulogic);
end;

architecture BEHAVIORAL of MOORE is
  type state_type is (s0, s1, s2, s3);
  signal CURRENT_STATE, NEXT_STATE: state_type;
begin

  -- Unclocked process to hold combinational logic.
  -- The sensitivity list of this process should include  
  -- signals read, which are CURRENT_STATE AND X. 
  combin: process (CURRENT_STATE, X)
  begin
    case CURRENT_STATE is
      when s0 =>
	Z <= '0';
	if X = '0' then
	  NEXT_STATE <= s0;
	else
	  NEXT_STATE <= s2;
	end if;
      when s1 =>
	Z <= '1';
	if X = '0' then
	  NEXT_STATE <= s0;
	else
	  NEXT_STATE <= s2;
	end if;
      when s2 =>
	Z <= '1';
	if X = '0' then
	  NEXT_STATE <= s2;
	else
	  NEXT_STATE <= s3;
	end if;
      when s3 =>
	Z <= '0';
	if X = '0' then
	  NEXT_STATE <= s3;
	else
	  NEXT_STATE <= s1;
	end if;
    end case;
  end process combin;

  -- From clocked process sr, CURRENT_STATE is 
  -- synthesized as the state register with asynchronous reset.
  sr: process (RESET, CLK)
  begin
     if (RESET = '1') then 
        CURRENT_STATE <= s0;                               
     elsif rising_edge(CLK) then
        CURRENT_STATE <= NEXT_STATE;
     end if;
  end process sr;                          

end BEHAVIORAL;
