Tengo 5 estados: inactivo, estado1, estado2, estado3, estado4. A veces necesito ir a inactivo de acuerdo con mi diseño, y cuando vuelvo de inactivo, no quiero comenzar desde el principio, quiero comenzar desde el último estado en el que estaba. Pensé en hacer esto en inactivo como
if (statereg = 2) then
my_state <= state2;
end if;
¿Es este un buen enfoque o no funcionará? ¿Hay mejores formas? ¿Cómo manejan los gurús de VHDL este tipo de situaciones? ¿Cómo llamamos a este método en VHDL? ¿Tiene un nombre?
¿Qué tan complicado es su estado "inactivo"?
Si es relativamente simple, tal vez sería mejor simplemente replicarlo; en otras palabras, tener estados idle1
, idle2
, etc. separados, uno para cada uno de los estados activos.
La pregunta no está clara, pero suponiendo que desea que todos los demás estados que no sean inactivos sean persistentes e inactivos para volver a cualquier estado persistente, el siguiente enfoque lo logrará sin agregar muchos estados adicionales ...
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;
saved_state
se state
retrasa 1 cc, por lo que si permanece en un estado por más de 1 cc, entonces el guardado y el actual son los mismos.Guardaría el estado anterior al mismo tiempo que guarda su estado actual. Por ejemplo, defina dos señales del mismo tipo de máquina de estado:
type states is (idle, state1, ... other states);
signal current_state : state;
signal previous_state : state;
En su máquina de estado, cada vez que current_state
cambia a un estado diferente, previous_state
establezca current_state
.
Esto hace que previous state
siempre esté un paso atrás current state
.
Luego, en su estado inicial, simplemente configure current_state
cuándo previous_state
desea volver a donde estaba.
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;
previous_state
a state1
durante el reinicio.
Avín
krambo