Forum: FPGA, VHDL & Co. Zustandsautomat mit Subautomaten


von Hans-Werner (Gast)


Lesenswert?

Kann man einen Zustansautomaten mit "Subautomaten" über mehrere Prozesse 
verteilen ?
Das "Standardmodell" mit einem, zwei oder drei Prozessen ist hier nicht 
gemeint.
Ein grösserer Zustandsautomat soll zwecks Übersichtlichkeit in mehrere 
kleine aufgeteilt werden die jeweils in einem eigenen Prozess ablaufen.
Das "Zusammenspiel" soll von einem Kontrollprozess geregelt werden.
Ist so etwas überhaupt realisierbar und wenn ja wie müsste die 
Grobstruktur aussehen ?

Danke

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Das ist ja nichts anderes, als wenn in einem Zustand deiner Statemachine 
(Haupt-Statemachine HSM) eine andere Statemachine (SM2) angeschubst 
wird, und dann auf das Abarbeiten dieser SM2 gewartet wird?

Falls ja, dann z.B. so
1
HauptSM:  process (clk) 
2
      if rising_edge(clk) then
3
        StartSM2<='0';
4
        case (StateHSM) is
5
6
          when IDLE =>
7
            if (Losgehts = '1') then
8
              StartSM2<='1';             -- Starten SM2
9
              StateHSM<=HS1;
10
            end if;
11
12
          when HS1 =>
13
            if (StateSM2 = SM2S4)  then  -- warten, bis SM2 fertig
14
              StateHSM<=HS2;             -- wenn fertig : weiter gehts in HSM
15
            end if;
16
17
          when HS2 =>
18
            :
19
            StateHSM<=HS3;
20
21
          when HS3 =>
22
            StateHSM<=IDLE;
23
24
         :
25
         :
26
         end case;
27
      end if;
28
   end process;
29
30
SM2:  process (clk) 
31
      if rising_edge(clk) then
32
        case (StateSM2) is
33
34
          when IDLE =>
35
            if StartSM2 = '1' then
36
              StateSM2<=SM2S1 ;
37
            end if;
38
39
          when SM2S1 =>
40
            :
41
            StartSM2<=SM2S2 ;
42
43
          when SM2S2 =>
44
            :
45
            StartSM2<=SM2S3 ;
46
47
          when SM2S3 =>
48
            :
49
            StartSM2<=SM2S4 ;
50
51
          when SM2S4 =>
52
            :
53
            if(StateHSM=HS2) then
54
               StartSM2<=IDLE ;
55
            end if;
56
57
         :
58
         :
59
         end case;
60
     end if;
61
   end process;

von Level up (Gast)


Lesenswert?

Etwas übersichtlicher wirds schon durch die verwendung von procedure 
aufrufen mit griffigen Namen.
dann steht dort when state23 => fetch_new_data;

oder so.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

@ Level up
>...procedure...
Ja, ich weiß und kann das.
Aber Hans-Werner hilft das nicht weiter, hier gehts um das Prinzip,
nicht um die schönste und kompakteste Schreibweise.

von Hans-Werner (Gast)


Lesenswert?

Hallo Lothar,

soweit verstanden benutzt du zwei Signale StartSM2 für die Zustände der 
Zustandsmaschine SM2 und StateHSM für die Zustände der Zustandsmaschine 
HauptSM. Der Start von SM2 erfolgt durch StartSM2 = '1'; die Beendigung 
durch StateHSM = HS2. Für mich etwas verwirrend. Warum erfolgt der Start 
bei einem bestimmten Wert von StartSM2 und die Beendigung durch Abfrage 
eines Zustandes ?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mann, da hats mich selber zerlegt:
StartSM2 = '1' ist ein Flag, das die SM2 anstösst/startet.
StateHSM sind die Zustände der Haupt-SM
StateSM2 sind die Zustände der Sub-SM
(Achtung: StateSM2 sieht fast aus wie StartSM2)
Das
>StartSM2<=IDLE ;
ist ein doofer Tippfehler
richtig ist
>StateSM2<=IDLE ;

StartSM2 = '1' startet die SM2.
In der HSM wird im Zustand HS1 gewartet, bis die SM2 fertig ist.
Wenn die SM2 durch ist, dann wartet die SM2,
bis die HSM auf den nächsten Zustand weitergeschaltet hat.

Dieses letzte Warten (ein Handshake) wäre eigentlich nicht nötig, aber 
es definiert eine klare Abhängigkeit der beiden SM. Die SM2 kann hier 
erst dann weitermachen, wenn die HSM erkannt hat, dass die SM2 fertig 
ist.

Ohne Synchronisation der beiden SM sparst du dir diese Abhängigkeit.
Dann wird SM2 nur gestartet und rennt einmal durch:
(restlicher Code s.o.)
1
:
2
:
3
        case (StateSM2) is
4
5
          when IDLE =>
6
            if StartSM2 = '1' then  -- SM2 wird gestartet
7
              StateSM2<=SM2S1 ;
8
            end if;
9
:
10
:
11
          when SM2S4 =>             -- SM2 ist fertig
12
            :
13
            StateSM2<=IDLE ;        -- hier war der Teppfihler StartSM2
14
         :
15
         :
16
         end case;
17
:
18
:

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.