Hallo, ich habe eine Frage bezüglich State-Machines in VHDL. Ich habe diese bisher immer mittels If/Elsif realisiert, also ungefähr so: process(clk) begin ... if state = idle then -- Do something elsif state = calc then -- Do something elsif state = finish then -- Do something else -- Do something end if; ... end process; Nun habe ich im Internet fast kein anderes Beispiel gefunden, indem die State-Machine ebenfalls mit If/Elsif-Statements aufgebaut ist. In nahezu allen Beispielen werden stattdessen Case-Statements verwenden, also so: process(clk) begin ... case state is when idle => -- Do something when calc => -- Do something when finish => -- Do something when other => -- Do something end case; ... end process; Auch wenn ich es mir eigentlich nicht vorstellen kann, gibt es zwischen den beiden Realisierungen irgendwelche Unterschiede? Bietet die Realisierung mit dem Case-Statement evtl. irgendwelche Vorteile bei der Synthetisierung? Oder wird Case aufgrund der besseren Lesbarkeit einfach häufiger verwendet? Vielen Dank im Voraus, Marc
Streng genommen, deine if/elsif Kaskade wird zu einer Mux Kette synthetisiert. Die if/elsif Kette gibt auch eine Priorisierung vor. Die boolsche Optimierung ist allerdings meistens in der Lage die wahre Intention zu erkennen und flacht das ganze wieder aus, muss aber nicht sein. Wenn die Optimierung nicht klappt ist deine Logik langsamer. Deine Case Lösung wird zu einem einzigen N -> 1 Multiplexer synthestisiert (Natürlich eine kleinere Kaskade wenn N zu breit ist) wobei N die Anzahl der States ist. d.h. Die Logik hier ist schneller. Von der Simulation, die Case wird natürlich schneller Simulieren auch wenn du den Unterschied wahrscheinlich gar nicht merkst auf einem schnellen PC. Wenn du eine Analogie in C suchst, if/elsif muss ggfs bis zum letzten else durchlaufen werden. Case ist ein Table-Jump mit Index, wobei STATE der Index ist.
:
Bearbeitet durch User
Synthetisier beide Varianten mal und such nach den Unterschieden im RTL-Schaltbild, dann wird dir bestimmt klar, warum man das mit einem case macht.
Adrian Bergmann schrieb: > Synthetisier beide Varianten mal und such nach den Unterschieden im > RTL-Schaltbild, dann wird dir bestimmt klar, warum man das mit einem > case macht. Und was dann letztlich tatsächlich herauskommt sieht man erst am Ressourcenverbrauch und im Technologieschaltplan.
Ganz wichtig ist meist, dass für alle States eine Aktion erfolgt (hier durch else bzw. others). Ansonsten baust Du Dir unbeabsichtigt Latches ein, die dein Synchrones Design durcheinander bringen. Beim if ist die Gefahr eines Fehlers viel größer, da hier ganz schnell mal eine andere Variable reingefrickelt wird ("elseif state2 = finish" oder "AND X = ready") wodurch dann das gleiche Problem auftritt. Wenn ein case passt, dann sollte man es auch verwenden. Die Lesbarkeit wird enorm erhöht, da ich sofort weiss, dass in diesem Block nur state die maßgebliche Eingangsvariable ist.
Benutzt man das Case-Konstrukt, ist die Mux-Struktur vorgegeben, und man kann eigentlich nichts falsch machen. Benutzt man das If-Konstrukt, kann im Idealfall eine Mux-Struktur resultieren, muss aber nicht. Falls man es dann wirklich so hinkriegt, dass man viele Priorisierungen hat, erhöht das direkt die Anzahl Logic-Levels zwischen den Registern. Dies wiederum ist böse, wenn man Mühe hat das Timing zu zu kriegen...
Marc schrieb: > wird Case aufgrund der besseren Lesbarkeit einfach häufiger verwendet? Eher wegen der geringeren Fehlerträchtigkeit. Denn sowas geht mit einem if zufällig problemlos:
1 | if state = idle then |
2 | -- Do something
|
3 | elsif state = calc then |
4 | -- Do something
|
5 | elsif state = finish then |
6 | -- Do something
|
7 | elsif input = '1' then |
8 | -- Do something
|
9 | else
|
10 | -- Do something
|
11 | end if; |
Mit einem case kommst du da nicht weit...
Vielen Dank für die vielen und ausführlichen Antworten! Der Unterschied zwichen den zwei Methoden ist dann doch größer als ich vermutet hatte. In Zukunft werde ich, wann immer es geht, auch das Case-Statement für den Bau meiner FSMs verwenden.
Noch ein Punkt zum Thema Fehlerträchtigkeit, ein case muss immer alle möglichen Werte abdecken. Es ist im Gegensatz zum if/elsif/... nicht möglich, einen Zustand zu vergessen. Außer man ist faul und fasst alle Zustände, in denen nichts oder das selbe zu tun ist, in einem "when others" zusammen. Dann ist man aber auch selbst schuld.
Andreas B. schrieb: > Außer man ist faul und fasst alle Zustände, in denen nichts oder das > selbe zu tun ist, in einem "when others" zusammen. Oder man führt aus Gewohnheit einen "when others" Pfad ein, wo es gar keine "others" mehr gibt. Wenn ich solchen VHDL-Code vors Auge bekomme, dann ist das für mich dann immer ein Warnsignal mit Ausrufezeichen: http://www.lothar-miller.de/s9y/categories/25-when-others
:
Bearbeitet durch Moderator
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.