Rückkehr aus dem Ruhezustand

Ich habe 5 Zustände: Leerlauf, Zustand1, Zustand2, Zustand3, Zustand4. Manchmal muss ich gemäß meinem Design in den Leerlauf gehen, und wenn ich aus dem Leerlauf zurückkehre, möchte ich nicht von vorne beginnen, ich möchte mit dem letzten Zustand beginnen, in dem ich war. Ich habe darüber nachgedacht, dies im Leerlauf als zu tun

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

Ist das ein guter Ansatz oder funktioniert es nicht? Gibt es bessere Wege? Wie gehen VHDL-Gurus mit solchen Situationen um, wie nennen wir diese Methode in VHDL, hat sie einen Namen?

Bitte geben Sie weitere Informationen darüber an, was Sie mit dem Code und/oder dem vollständigen Zustandsmaschinencode, den Sie implementiert haben, erreichen möchten.
Die UML-Terminologie für das, was Sie beschreiben, lautet "Übergang in den Verlaufszustand". Hier ist ein Beispiel für den UML-Verlaufs-Pseudozustand .

Antworten (3)

Wie kompliziert ist Ihr "Leerlauf"-Zustand?

Wenn es relativ einfach ist, wäre es vielleicht besser, es einfach zu replizieren; mit anderen Worten, haben separate idle1, idle2, usw. Zustände, einen für jeden der aktiven Zustände.

Die Frage ist unklar, aber unter der Annahme, dass jeder andere Zustand als Leerlauf dauerhaft sein soll und dass Leerlauf zu einem solchen dauerhaften Zustand zurückkehren soll, wird der folgende Ansatz dies erreichen, ohne viele zusätzliche Zustände hinzuzufügen ...

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;
Ich gehe nacheinander die Zustände durch: 1,2,3,4, wenn ein Leerlauffall auftritt, möchte ich nicht von Anfang an mit dem Scannen beginnen, sondern dort, wo ich aufgehört habe.
Wenn ich Ihre Implementierung richtig verstehe, saved_statewird sie stateum 1cc verzögert. Wenn Sie also länger als 1cc in einem Zustand bleiben, sind die gespeicherte und die aktuelle identisch.
@Stacey - ja (außer natürlich für den Idle-Zustand), die Idee ist, dass Sie nach Idle immer in den Zustand zurückkehren, der ihn "aufgerufen" hat, und Idle als Unterprogramm behandeln. Das ist vielleicht nicht das, was der Poster eigentlich wollte, was mir noch unklar ist.
@Brian, also ist es deine Absicht, nur für 1cc im Leerlauf zu leben? Bist du auch viel im Chat? Ich würde gerne mit jemandem sprechen, der mehr HDL-Erfahrung hat als ich. Das ist einer der Nachteile der Freiberuflichkeit.
Was macht es, wenn "leave_idle" falsch ist? ... Ich habe noch nie versucht zu chatten, aber ich werde es versuchen ...

Ich würde den vorherigen Zustand zur gleichen Zeit speichern, zu der Sie Ihren aktuellen Zustand speichern. Definieren Sie beispielsweise zwei Signale desselben Zustandsmaschinentyps:

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

  signal current_state  : state;
  signal previous_state : state;

Setzen Sie in Ihrer Zustandsmaschine jedes Mal, wenn die current_stateÄnderungen in einen anderen Zustand wechseln, previous_stateauf current_state.

Diese machen previous stateimmer einen Schritt hinterher current state.

Stellen Sie dann in Ihrem Ausgangszustand einfach current_stateein , previous_statewann Sie dorthin zurückkehren möchten, wo Sie waren.

  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;
Wie kommt das nach dem Zurücksetzen aus dem Leerlauf?
Bissiger Kommentar beiseite, die Grundidee ist solide.
@BrianDrummond, huh, guter Punkt. Geändert previous_stateauf state1während des Zurücksetzens.