# Return from idle state

I have 5 states : idle, state1, state2, state3, state4. I sometimes need to go to idle according to my design, and when I return from idle, I don't want to start from beginning, I want to start from the last state I was in. I thought about doing this in idle as

if (statereg = 2) then
my_state <= state2;
end if;


Is this a good approach or won't work? Are there better ways? How do VHDL gurus handle this kind of situation, what do we call this method in VHDL, does it have a name?

• Please provide more information on what you are trying to achieve with the code and/or the full state machine code which you implemented.
– Avin
Jun 6, 2014 at 10:16
• The UML terminology for what you are describing is, "transitioning to the history state". Here is an example of the UML History pseudostate. Jun 6, 2014 at 14:12

How complicated is your "idle" state?

If it's relatively simple, perhaps it would be better to simply replicate it; in other words, have separate idle1, idle2, etc. states, one for each of the active states.

The question is unclear, but assuming you want every other state than idle to be persistent, and idle to return to any such persistent state, the following approach will accomplish it without adding a lot of additional states...

type state_type is (idle, state1, state2, state3, state4);
signal state, saved_state : state_type;
signal reset, leave_idle, suspend, proceed : boolean;
procedure start_calculation;

process(clock)
begin
if rising_edge(clock) then
if reset then
state       <= idle;
saved_state <= state1;
else
-- default assignments : save current state
saved_state <= state;

-- main state machine
case state is

when idle =>
-- override default assignment here; last assignment wins
saved_state <= saved_state;
if leave_idle then
state <= saved_state;
end if;

when state1 =>
if suspend then
state <= idle;
elsif proceed then
start_calculation;
state <= state2;
-- else remain here
end if;

-- when state2 =>
-- etcetera

when others =>
state <= idle;
end case;
end if;
end if;
end process;

• I go through states: 1,2,3,4 sequentially when idle case occurs I don't want to start from the beginning to scan but from where I left. Jun 6, 2014 at 12:18
• If I'm understanding your implementation correctly, saved_state is state delayed by 1cc, so if you remain in a state longer than 1cc then the saved one and the current one are the same. Jun 6, 2014 at 12:24
• @Stacey - yes (except of course for the Idle state), the idea is that you always return after Idle to the state which "called" it, treating Idle as a subroutine. That may not be what the poster actually wanted, which is still unclear to me. Jun 6, 2014 at 14:14
• @Brian so your intention is to only live in idle for 1cc? Also, are you in chat much? I would love to speak to someone who has more hdl experience then me. It's one of the downsides of freelancing. Jun 6, 2014 at 14:44
• what does it do if "leave_idle" is false? ... I've never tried chat but I'll give it a go... Jun 6, 2014 at 16:11

I would save the previous state at the same time that you save your current state. For example, define two signal of the same state machine type:

 type states is (idle, state1, ... other states);

signal current_state  : state;
signal previous_state : state;


In your state machine, each time the current_state changes to a different state, set previous_state to current_state.

This make previous state always one step behind current state.

Then, in your initial state, just set current_state to previous_state when you want to go back to where you were.

  example_state_machine : process (clk, rst)
begin
if rst = '1' then
current_state  <= idle;
previous_state <= state1; -- set this to the state you want to go to after first idle
elsif clk'event and clk = '1' then  -- rising clock edge
case current is
when idle =>
if (something = '1') then
current_state  <= previous_state;
previous_state <= current_state;
else
current_state <= idle;
end if;
when state1 =>
if (something = '1') then
current_state  <= state2;
previous_state <= current_state;
elsif something_else = '1' then
current_state  <= idle;
previous_state <= current_state;
else
current_state <= state1;
end if;
-- ... rest of states
when others => null;
end case;
end if;
end process;

• How does this get out of Idle after reset? Jun 6, 2014 at 11:30
• Snarky comment aside, the basic idea is sound. Jun 6, 2014 at 11:39
• @BrianDrummond, huh, good point. Changed previous_state to state1 during reset. Jun 6, 2014 at 12:20