'I am trying to implement a traffic light controller using a FSM that stays in its initial state until it receives an input "carew"

HERE IS MY FSM1 VHDL that implements the traffic light controller logic. My issue is within the case statement of the FSM in the state "000", with the if statement:

library IEEE;
use IEEE.std_logic_1164.all;
--INPUTS: carew(car waiting at East/West direction)
--OUTPUTS: North/South lights(GNS-YNS-RNS), East/West lights(GEW-YEW-REW)
Entity FSM1 is
    port(clk, r, carew :in std_logic;
    GNS, YNS, RNS, GEW, YEW, REW : out std_logic);
end;

Architecture behave of FSM1 is
--Declaring three bit signals for current and next state to represent all six states
signal cs: std_logic_vector(2 downto 0);
signal ns: std_logic_vector(2 downto 0);
begin
process(clk)
    begin
--Asynchronous reset to first state
    if (r = '1') then
        cs <= "000";
    elsif (clk'event and clk='1') then
        cs <= ns;
    end if;
end process;

--Moore finite state machine
process(cs,carew)
begin
    case cs is
--Ns direction is green and EW is red
        when "000" =>
            GNS <= '1';
            YNS <= '0';
            RNS <= '0';
            GEW <= '0';
            YEW <= '0';
            REW <= '1';
--Only moves to next state when carew detects car waiting in EW direction
            if (carew = '1') then
                ns <= "001";
            end if;
--NS direction is yellow and EW direction is red
        when "001" =>
            GNS <= '0';
            YNS <= '1';
            RNS <= '0';
            GEW <= '0';
            YEW <= '0';
            REW <= '1';
            ns <= "010";
--NS and EW directions are red
        when "010" =>
            GNS <= '0';
            YNS <= '0';
            RNS <= '1';
            GEW <= '0';
            YEW <= '0';
            REW <= '1';
            ns <= "011";
--NS direction is red and EW direction is green
        when "011" =>
            GNS <= '0';
            YNS <= '0';
            RNS <= '1';
            GEW <= '1';
            YEW <= '0';
            REW <= '0';
            ns <= "100";
--NS direction is red and EW direction is yellow
        when "100" =>
            GNS <= '0';
            YNS <= '0';
            RNS <= '1';
            GEW <= '0';
            YEW <= '1';
            REW <= '0';
            ns <= "101"; 
--NS and EW directions are red
        when "101" =>
            GNS <= '0';
            YNS <= '0';
            RNS <= '1';
            GEW <= '0';
            YEW <= '0';
            REW <= '1';
            ns <= "000";                 
--Don't care out other possible state left with bits
        when others => ns <= "000";
    end case;
end process;
end behave;

HERES MY CODE FOR TESTBENCH VHDL: The issue is that despite having inputting carew = 1, my state does not recognize it and stays in the same state. It will iterate through the state if I did not have the condition to stay in the state until carew is 1.

library IEEE;
use IEEE.std_logic_1164.all;

Entity HW9_tb is
end;

Architecture beh of HW9_tb is
signal myClk, myR, myCAREW, myGNS, myYNS, myRNS, myGEW, myYEW, myREW: std_logic;

component FSM1
    port(clk, r, carew : in std_logic;
    GNS, YNS, RNS, GEW, YEW, REW : out std_logic);
end component;

begin

HW : FSM1 
port map (myClk, myR, myCAREW, myGNS, myYNS, myRNS, myGEW, myYEW, myREW);

process
begin
    myClk <= '1';
    myR <= '0';
    myCAREW <= '0';
    wait for 10 ns;
    
    report "input = " & std_logic'image(myClk) & std_logic'image(myR) & std_logic'image(myCAREW) & std_logic'image(myGNS) & std_logic'image(myYNS) & std_logic'image(myRNS) & std_logic'image(myGEW) & std_logic'image(myYEW) & std_logic'image(myREW);
    
    myClk <= '0';
    myR <= '0';
    myCAREW <= '0';
    wait for 10 ns;
    
    report "input = " & std_logic'image(myClk) & std_logic'image(myR) & std_logic'image(myCAREW) & std_logic'image(myGNS) & std_logic'image(myYNS) & std_logic'image(myRNS) & std_logic'image(myGEW) & std_logic'image(myYEW) & std_logic'image(myREW);
    
    myClk <= '1';
    myR <= '0';
    myCAREW <= '1';
    wait for 10 ns;
    
    report "input = " & std_logic'image(myClk) & std_logic'image(myR) & std_logic'image(myCAREW) & std_logic'image(myGNS) & std_logic'image(myYNS) & std_logic'image(myRNS) & std_logic'image(myGEW) & std_logic'image(myYEW) & std_logic'image(myREW);
    
    myClk <= '0';
    myR <= '0';
    myCAREW <= '0';
    wait for 10 ns;
    
    report "input = " & std_logic'image(myClk) & std_logic'image(myR) & std_logic'image(myCAREW) & std_logic'image(myGNS) & std_logic'image(myYNS) & std_logic'image(myRNS) & std_logic'image(myGEW) & std_logic'image(myYEW) & std_logic'image(myREW);
    
    myClk <= '1';
    myR <= '0';
    myCAREW <= '0';
    wait for 10 ns;
    
    report "input = " & std_logic'image(myClk) & std_logic'image(myR) & std_logic'image(myCAREW) & std_logic'image(myGNS) & std_logic'image(myYNS) & std_logic'image(myRNS) & std_logic'image(myGEW) & std_logic'image(myYEW) & std_logic'image(myREW);
    
    wait;
end process;
end beh;


Solution 1:[1]

Part of the problem is you have nothing declaring what ns should do when cs = 000 and carew = 0. In that case, I assume you want ns to stay as 000. The method I prefer for state machines is to always declare a default assignment statement before the case statement that says, unless something else overrides this, stay in the current state.

ns <= cs;

case ...

The other option is to add an else to your statement:

--Only moves to next state when carew detects car waiting in EW direction
            if (carew = '1') then
                ns <= "001";
            else
                ns <= "000";
            end if;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Reddersen