Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

FSM misbehaves.

Altera_Forum
Honored Contributor II
1,202 Views

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;
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
431 Views

Update... Got it!  

 

That "go" signal was external pin. That needs to be synchronized, otherwise the statemachine locks up. Duh!
0 Kudos
Altera_Forum
Honored Contributor II
431 Views

Hi, 

 

 

I'm facing I think the same problem. Could you tell me what happens when using a not synchronized input to the statemachine. 

 

And most important how did you manage to detect it is in a not defined state. I need to prove it is in there and that is why the design is not correct. 

 

Thanx in advance.  

 

Bram
0 Kudos
Altera_Forum
Honored Contributor II
431 Views

Bram, My coleague had as debugging output a "one-hot" encoded signal that we exported to debugging leds. Those simply indicated a state that was valid, but we also exported the input signals and by hand verified that it was supposed to continue.  

 

I then took over the project, and I used binary encoding to indicate the state. (I just defined a set of extra outputs with values that simply correspond to a binary encoding of the state. In reality behind the scenes Quartus was still using a one-hot encoding for the states).  

 

This binary encoding is of course much less likely to indicate "bad state" than the one-hot encoding that my colleague used before. (but even then his one-hot output that should've been just led_out = NOT state_idle etc did not indicate an illegal state...) 

 

I did not inconclusively prove that the state-machine got into an impossible state. I just synchronized the external inputs and it started working.  

 

If you really need to prove it to be in an invalid state then I would suggest trying to use SignalTap to monitor the situation. There you can tap the internal signals: 'state_is_idle', 'state_is_start_write' etc etc.  

 

I had never used SignalTap when I solved this problem. Now I have. :-)
0 Kudos
Reply