Altera_Forum
Honored Contributor
15 years agoFSM misbehaves.
I have designed a finite state machine with "qfsm". It's pretty simple. Wait for a "go" signal, when active (low) go through 4 states before returning back to "idle". One of the two outputs is high during the first two of those states, the other output is high during the third of those four states. Simple!
Now I'm seeing the state machine sort of "latch up" in a more or less random state. It is currently in state idle with the "go" signal active (low). It's just sitting there.... I have the input and the output signals on leds for debugging. Similarly I have the state encoded into a debug_state output variable, so that I can see in what state it is. Any suggestions? Here is the VHDL code.
-- This file was generated by
-- Qfsm Version 0.52
-- (C) Stefan Duffner, Rainer Strobel
-- Inputs: ft_ntxe
-- State/Output ct_inc ft_wr
-- st_idle 0 0
-- st_wr 0 1
-- st_inc 1 0
-- wr2 0 1
-- st_wait 0 0
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
ENTITY ftdi_writer IS
PORT (clk: IN std_ulogic;
rst_p: IN std_ulogic;
ft_ntxe: IN std_ulogic;
ct_inc: OUT std_ulogic; -- 1++2
ft_wr: OUT std_ulogic ; debug_state: OUT std_ulogic_vector (2 DOWNTO 0));
END ftdi_writer;
ARCHITECTURE behave OF ftdi_writer IS
TYPE state_type IS (st_idle, st_wr, st_inc, wr2, st_wait);
SIGNAL next_state, current_state : state_type;
BEGIN
state_register: PROCESS (rst_p, clk)
BEGIN
IF rst_p='1' THEN
current_state <= st_idle;
ELSIF rising_edge(clk) THEN
current_state <= next_state;
END IF;
END PROCESS;
next_state_and_output_logic: PROCESS (current_state, ft_ntxe)
VARIABLE temp_input : std_ulogic_vector(0 DOWNTO 0);
VARIABLE temp_output : std_ulogic_vector(4 DOWNTO 0);
BEGIN
temp_input(0) := ft_ntxe;
CASE current_state IS
WHEN st_idle => temp_output := "00000";
IF temp_input="0" THEN
next_state <= st_wr;
ELSE
next_state <= current_state;
END IF;
WHEN st_wr => temp_output := "00101";
next_state <= wr2;
WHEN st_inc => temp_output := "01010";
next_state <= st_wait;
WHEN wr2 => temp_output := "01101";
next_state <= st_inc;
WHEN st_wait => temp_output := "10000";
next_state <= st_idle;
WHEN OTHERS => temp_output := (OTHERS =>'X');
next_state <= st_idle;
END CASE;
ct_inc <= temp_output(1);
ft_wr <= temp_output(0);
debug_state <= temp_output (4 DOWNTO 2);
END PROCESS;
END behave;