Forum: FPGA, VHDL & Co. VHDL State Machine - Case vs. If/Elsif


von Marc (Gast)


Lesenswert?

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

von Charles G. (Firma: Ingenieurbuero Gardiner) (cfgardiner)


Lesenswert?

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
von Adrian Bergmann (Gast)


Lesenswert?

Synthetisier beide Varianten mal und such nach den Unterschieden im 
RTL-Schaltbild, dann wird dir bestimmt klar, warum man das mit einem 
case macht.

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


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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.

von P. K. (pek)


Lesenswert?

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...

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


Lesenswert?

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...

von Marc (Gast)


Lesenswert?

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.

von Andreas B. (andreas_b77)


Lesenswert?

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.

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


Lesenswert?

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
Noch kein Account? Hier anmelden.