Search code examples
vhdlfsm

Designing a FSM in VHDL using 2 processes


I tried to design a FSM using 2 processes though i have too many syntax errors. I can't understand what is wrong . The most of the errors are like this "syntax error near if/else" etc.

entity myFSM is
    Port ( CLK : in  STD_LOGIC;
           RST : in  STD_LOGIC;
           IN0 : in  STD_LOGIC;
           IN1 : in  STD_LOGIC;
           IN2 : in  STD_LOGIC;
           LED : out  STD_LOGIC_VECTOR (7 downto 0));
end myFSM;

architecture Behavioral of myFSM is
        type state is (A, B, C);
        signal currentS, nextS: state;
myFSM_comb: process (currentS, IN0, IN1, IN2)
begin
    case currentS is
        when A =>   LED <= "11111111";
                        if IN0 = '1' then nextS<=B;
                        else if IN1 = '1' then nextS<=C;
                        else            nextS<=A;
                        end if;
        when B =>   LED <= "11000011";
                        if IN0 = '1' then nextS<=C;
                        else if IN1 = '1' then nextS<=A;
                        else nextS<=B;
                        end if;
        when C =>   LED <= "00111100";
                        if IN0 = '1' then nextS<=A;
                        else if IN1 = '1' then nextS<=B;
                        else nextS<=C;
                        end if;
    end case;
end process;

myFSM_synch: process(CLK,RST)
begin 
    if (RST='1')        then    currentS<=A;
    elsif (rising_edge(CLK)) then; currentS<= nextS;
    end if;
end process ;

end Behavioral;

Solution

  • I can see the following faults:

    • The keyword for else if is elsif.
    • There is a missing begin before the first process.
    • The FSM has no initial state

      signal currentS : state := A;
      

    This is a fixed and improved version of your code. It uses a default assignment for nextS.

    myFSM_comb: process (currentS, IN0, IN1, IN2) -- IN2 is unused
    begin
       nextS <= currentS;
       LED   <= "11111111";
    
      case currentS is
        when A =>
          LED <= "11111111";
          if IN0 = '1' then
            nextS<=B;
          elsif IN1 = '1' then
            nextS<=C;
          end if;
        when B =>
          LED <= "11000011";
          if IN0 = '1' then
            nextS<=C;
          elsif IN1 = '1' then
            nextS<=A;
          end if;
        when C =>
          LED <= "00111100";
          if IN0 = '1' then
            nextS<=A;
          elsif IN1 = '1' then
            nextS<=B;
          end if;
      end case;
    end process;