'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 |
