I have a FSM consisting of 3 states: STATIC
, UP
and DOWN
.
The FSM starts in the STATIC
state and if I press the up arrow key, it will move to the UP
state, thereafter returning to the STATIC
state. Same thing for DOWN
.
At first the FSM works well but suddenly after a random amount of key presses it will enter an unspecified state. The FSM consists of two processes:
type ALL_STATES is (STATIC, UP, DOWN);
signal STATE, NEXT_STATE: ALL_STATES;
signal posBarraYTOP, posBarraYBOT: std_logic_vector(11 downto 0);
signal movTeclado: std_logic_vector(1 downto 0);
-- ...
Keybd: keyboard port map (input, movTeclado); -- keyboard output
-- ...
bar_FSM_sincrono: process(CLK, RST) -- CLK is the FPGA's clock
begin
if RST='1' then
STATE <= STATIC;
elsif (CLK'event and CLK = '1') then
STATE <= NEXT_STATE; -- in each CLK cycle we move to the next state.
end if;
end process bar_FSM_sincrono;
bar_FSM_cambioest: process(STATE)
begin
case STATE is
when STATIC=>
seg <= "1001001";
if (movTeclado = "01" and posBarraYTOP > 20) then
NEXT_STATE <= UP;
elsif (movTeclado = "10" and posBarraYBOT < 980) then
NEXT_STATE <= DOWN;
else
NEXT_STATE <= STATIC;
end if;
when UP | DOWN =>
NEXT_STATE <= STATIC;
seg <= "1111110";
when others =>
NEXT_STATE <= STATIC;
seg <= "0110111";
end case;
end process bar_FSM_cambioest;
movTeclado
is a 2-bit signal that shows when the user presses the up 01
or down 10
key. It's 00
if no key is pressed. movTeclado doesn't give me any problems.
posBarraYTOP
and posBarraYBOT
are two signals to describe a boundary, and these conditions are always met.
I use seg
as a signal for the 7-segment display to debug and find out in what state the FSM is at. At first it always displays the STATIC seg
, as it should since UP seg
and DOWN seg
are only displayed for one cycle. But then when the error happens it's when it starts displaying the others seg
, as well as the STATIC seg
. It's a back-and-forth between STATIC
and others
, which I don't understand since when STATE = STATIC
, it should only transition to UP
or DOWN
.
Thank you for reading this far, does anyone know what's going on?
As other comments have suggested, you should never drive a signal from more than one process
block. Personally I don't like writing state machines like this, with 2 process blocks, because I find it confusing.
But regardless, your 2nd process block (the combinational one) should only be assigning NEXT_STATE
, it should never make an assignment to STATE
since that's taken care of by the first process block.