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 motor_sm is
port (
  clk : in std_logic;  -- input to determine speed of rotation
  rst : in std_logic;  -- resets and initializes the circuit
  en  : in std_logic;  -- determines whether motor rotating or holding  (0 holding, 1 rotating)
  dir : in std_logic;  -- motor direction control           (0 forward, 1 backward)
  position_feedback : in std_logic_vector (3 downto 0); -- motor phase feedback vector (ph1,ph2,ph3,ph4)
  ph1 : out std_logic; -- output to motor phase 1
  ph2 : out std_logic; -- output to motor phase 2
  ph3 : out std_logic; -- output to motor phase 3
  ph4 : out std_logic  -- output to motor phase 4
  );
end motor_sm;

architecture Behavioral of motor_sm is
begin
process (clk)
  begin
      if (rst = '1') then
         ph1 <= '1';
   ph2 <= '0';
         ph3 <= '0';
         ph4 <= '0'; 
  elsif (clk'event and clk = '1') then
   if en = '1' then  
    case position_feedback is

--description of phase1 behaviour     
     when "1000" =>
          --In phase1 -> forward step
      if dir = '0' then
       ph1 <= '0';
       ph2 <= '1';
       ph3 <= '0';
       ph4 <= '0';
      --In phase1 -> backward step 
      elsif dir = '1' then
         ph1 <= '0';
       ph2 <= '0';
       ph3 <= '0';   
       ph4 <= '1';
          --In phase1 -> stay in phase1
      else
       ph1 <= '1';
       ph2 <= '0';
       ph3 <= '0';   
       ph4 <= '0';
      end if;
--description of phase2 behaviour     
     when "0100" =>
      --In phase2 -> forward step
      if dir = '0' then
       ph1 <= '0';
       ph2 <= '0';
       ph3 <= '1';   
       ph4 <= '0';
      --In phase2 -> backward step   
      elsif dir = '1' then
       ph1 <= '1';
       ph2 <= '0';
       ph3 <= '0';   
       ph4 <= '0';
      --In phase2 -> stay in phase2 
      else
       ph1 <= '0';
       ph2 <= '1';
       ph3 <= '0';   
       ph4 <= '0';
      end if;

--description of phase3 behaviour     
     when "0010" =>
      --In phase3 -> forward step
      if dir = '0' then
       ph1 <= '0';
       ph2 <= '0';
       ph3 <= '0';   
       ph4 <= '1';   
      --In phase3 -> backward step
      elsif dir ='1' then
       ph1 <= '0';
       ph2 <= '1';
       ph3 <= '0';   
       ph4 <= '0';
      --In phase3 -> stay in phase3
      else
       ph1 <= '0';
       ph2 <= '0';
       ph3 <= '1';   
       ph4 <= '0';
      end if;

--description of phase4 behaviour     
     when "0001" =>
      --In phase4 -> forward step
      if dir = '0' then
       ph1 <= '1';
       ph2 <= '0';
       ph3 <= '0';   
       ph4 <= '0';   
      --In phase4 -> backward step
      elsif dir = '1' then
       ph1 <= '0';
       ph2 <= '0';
       ph3 <= '1';   
       ph4 <= '0';
      --In phase4 -> stay in phase4
      else
       ph1 <= '0';
       ph2 <= '0';
       ph3 <= '0';   
       ph4 <= '1';
      end if;
     when others => null;     
    end case;   
   end if;
  end if;
end process;
end Behavioral;