- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Update... Got it!
That "go" signal was external pin. That needs to be synchronized, otherwise the statemachine locks up. Duh!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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. :-)
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page