----------------------------------------------------------------------------------
-- Company: 		vutbr.cz
-- Engineer: 		Tomas Novotny, 72999
-- 
-- Create Date:    13:03:32 11/13/09
-- Design Name:    FSM_example
-- Module Name:    FSM - Behavioral
-- Project Name:   FSM_example
-- Target Device:  spartan3
-- Tool versions:  webpack 11.2
-- Description:		Jde o jednoduchy stavovy automat, vytvoreny podle sablon v ISE WebPack
--
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
-- 
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity FSM is
    Port ( X, RST, CLK: in std_logic;
           Q : out std_logic_vector(3 downto 0));
end FSM;

architecture Behavioral of FSM is
   type state_type is (st1_s1, st2_s2, st3_s3, st4_s4); 
	type data is (zakazano, povoleno);
   signal state, next_state : state_type;
	signal CO, CO_next : data;
   signal temp_i : std_logic_vector(3 downto 0) := (OTHERS => '0');  -- example output signal

begin
   SYNC_PROC: process (CLK, RST)
   begin
      if rising_edge(CLK) then
         state <= next_state;
			CO <= CO_next;
         Q <= temp_i;
		
         -- assign other outputs to internal signals
      end if; 

		if RST = '0' 
			then 
			state <= st1_s1;
			Q <= "1111";
	   end if;

   end process;
             	
   --MOORE State-Machine - Outputs based on state only
   OUTPUT_DECODE: process (state)
   begin

      --insert statements to decode internal output signals
      --below is simple example

	   if state = st1_s1 then
         temp_i <= "1011";
      end if;

		if state = st2_s2 then
         temp_i <= "1010";
      end if;

      if state = st3_s3 then
         temp_i <= "0110";
      end if;
		
		if state = st4_s4 then
         temp_i <= "1001";
      end if;

   end process;
 
   NEXT_STATE_DECODE: process (state, x, CO)
   begin
      --declare default state for next_state to avoid latches
      next_state <= state;  --default is to stay in current state
		CO_next <= CO;
      --insert statements to decode next_state
      --below is a simple example

		if x = '0' then
			CO_next <= povoleno;
		else CO_next <= zakazano;
		end if;
		
		if CO = povoleno then
			case (state) is
				when st1_s1 =>
					if x = '1' then
						next_state <= st2_s2;
						CO_next <= zakazano;
					end if;
				when st2_s2 =>
					if x = '1' then
						next_state <= st3_s3;
						CO_next <= zakazano;
					end if;
				when st3_s3 => 
					if x = '1' then
						next_state <= st4_s4;
						CO_next <= zakazano;
					end if;
				when others =>
					next_state <= st4_s4;
					CO_next <= zakazano;
			end case; 
		end if;

   end process;


end Behavioral;