Unterschied zwischen If-else- und Case-Anweisung in VHDL

Ich möchte verstehen, wie verschiedene Konstrukte im VHDL-Code in RTL synthetisiert werden.

  • Kann mir jemand den Unterschied zwischen If-Else- Konstrukt und Case-Anweisungskonstrukten eines Prozesses in VHDL in Bezug darauf sagen, wie der Code vom Synthesetool in die RTL-Schaltung rückgeschlossen wird?
  • Berücksichtigen Sie den Fall mehrerer verschachtelter if-else -Anweisungen und das Mischen von Case-Anweisungen mit if-else- Konstrukten innerhalb eines Prozesses.
  • Auch wann welches Konstrukt zu verwenden?

PS: Ich habe eine verwandte Frage "Mehrere if-Anweisungen in Bearbeitung in vhdl" gesehen, aber das beantwortet meine Frage sowieso nicht.

Ich kann nicht sagen, wie die physischen Gates konfiguriert werden, aber in den meisten Compilern, die x86-Assembly ausgeben, existiert ein if-else normalerweise als einzelne Prüfung mit einem bedingten Sprung (z. B. jg, jl, jz, jnz usw.). während switch die Fälle in numerischer Reihenfolge organisiert und iterative dec/ jzAnweisungen ausführt, was viel effizienter ist. Vielleicht wird hier eine ähnliche Optimierung angewendet.
@Polynomial Das Verhalten von If-else und case unterscheidet sich in Hardwaresprachen erheblich von Ihrer typischen linearen Programmierung. Op-Code-Optimierungen sind nicht sehr relevant, da die HDL-Anweisung "sofort" ausgeführt wird.

Antworten (2)

Kann mir jemand den Unterschied zwischen If-Else-Konstrukt und Case-Anweisungskonstrukten eines Prozesses in VHDL in Bezug darauf sagen, wie der Code vom Synthesetool in die RTL-Schaltung rückgeschlossen wird?

Das if-elsif-elseKonstrukt leitet ein Prioritäts-Routing-Netzwerk ab:

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Dies entspricht

if bool_expr_1 then
    sig <= val_expr_1;
elsif bool_expr_2 then
    sig <= val_expr_2;
elsif bool_expr_3 then
    sig <= val_expr_3;
else
    sig <= val_expr_4;
end if;

Das caseKonstrukt hingegen leitet einen großen alten Mux ab:

Geben Sie hier die Bildbeschreibung ein

Dies entspricht

case case_expr is
  when c0 =>
    sig <= val_expr_0;
  when c1 =>
    sig <= val_expr_1;
  when c2 =>
    sig <= val_expr_2;
      ...
  when others =>
    sig <= val_expr_N;
end case;

Offensichtlich sind dies sehr vereinfachte Entwürfe mit nur einem Wertausdruck, was zu einer Ausgabe führt.

Berücksichtigen Sie den Fall mehrerer verschachtelter if-else-Anweisungen und das Mischen von Case-Anweisungen mit if-else-Konstrukten innerhalb eines Prozesses.

Gemäß dem oben Gesagten können Sie sehen, wie sie sich verschachteln/mischen würden.

Auch wann welches Konstrukt zu verwenden?

Da if-elsePriorität abgeleitet wird, sollte es verwendet werden, wenn mehr als eine Eingabebedingung auftreten könnte. Die Verwendung casevon hingegen ist angemessen, wenn sich die Eingaben gegenseitig ausschließen.

Ich verstehe, dass die Case-Anweisung nur für eine einzelne Eingabebedingung funktioniert und if-else für mehrere Eingabebedingungen funktionieren kann. Aber beide Konstrukte erzeugen im Wesentlichen Muxes (in Abwesenheit von clk). Ist es nicht möglich, dass die Logiksynthese Single-Input-If-Else zu einem einzigen großen Mux anstelle einer Kette von Muxen optimiert? Was ist ein Prioritäts-Routing-Netzwerk ... ist das nicht einfach eine Kette von Muxen anstelle von 1 großen Mux?
Wenn wir einen taktempfindlichen Prozess haben, kann if-else außerdem sequentielle Elemente wie Register, Latches usw. generieren. Kann eine case-Anweisung auch sequentielle Logik generieren?
Ja, ein Prioritäts-Routing-Netzwerk ist genau das – eine Kette von Muxes. Die Natur des if-elseKonstrukts liegt jedoch darin, wo diese Kette entsteht. Die erste Bedingung muss fehlschlagen, damit die zweite Bedingung getestet werden kann. Dies ist nicht der Fall für, äh, das caseKonstrukt, und deshalb könnte eine if-elseAnweisung nicht als ein einziger großer Mux synthetisiert werden.
Und ja, eine caseAnweisung kann auch sequentielle Logik erzeugen. Ich habe "Real World VHDL" gefunden , eine Reihe von Vorlesungsfolien der University of Glasgow, die für Sie hilfreich sein können.
Dies ist eine gute Referenz.
Angelo Stavrow: Bedeutet das, dass das Case-Beispiel weniger Verzögerung vom Eingang zum Ausgang hat als der if/else-Fall?

In diesem alten Blogbeitrag hat der Autor zwei funktional gleichwertige Versionen von VHDL-Code geschrieben und synthetisiert. Einer verwendet if-else, der andere case. Das Ergebnis:

Ich habe diesen Code synthetisiert und die genauen Ergebnisse erhalten. Sogar das RTL-Schema war für beide Programme genau gleich.

Und sein Fazit:

Dies zeigt, dass 'case'- und 'if...elsif...else'-Anweisungen beide gleich effizient sind. Wenn Sie jedoch einen klaren Code schreiben möchten, verwenden Sie besser 'case'. 'case' ist sehr nützlich, wenn die Die Ausgabe hängt von einer großen Anzahl von Bedingungen ab. Wenn die Anzahl der Bedingungen jedoch sehr klein ist (2 oder 3), können Sie 'if..elseif..else' verwenden.

Auch zu diesem Thema gibt es auf Stack Overflow dutzende Beiträge für jede erdenkliche Sprache. Die Schlussfolgerung ist im Allgemeinen die gleiche, dass es keinen Unterschied in Bezug auf die Leistung gibt. Gelegentlich, wenn es eine große Anzahl von Fällen gibt, kann ein Compiler schlau genug sein, eine Nachschlagetabelle zu erstellen, die eine etwas bessere Leistung erbringen würde.

Ein VHDL-Synthesizer kann möglicherweise etwas Ähnliches tun. Aber Sie würden immer noch eine große Anzahl von Fällen benötigen, in denen Sie (Wortspiel beabsichtigt) wahrscheinlich sowieso eine Fallanweisung verwenden möchten, da dies bei einer großen Anzahl von Optionen eine bessere Lesbarkeit bietet.