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
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; |
Etwas übersichtlicher wirds schon durch die verwendung von procedure aufrufen mit griffigen Namen. dann steht dort when state23 => fetch_new_data; oder so.
@ 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.
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 ?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.