Mein Compiler beschwert sich über abgeleitete Latches in meinen kombinatorischen Schleifen ( always @(*)
, in Verilog). Mir wurde auch gesagt, dass abgeleitete Latches vorzugsweise vermieden werden sollten.
Was genau ist falsch an abgeleiteten Latches? Sie erleichtern sicherlich das Schreiben von kombinatorischen Schleifen.
Ein "Latch" unterscheidet sich von einem "Flip-Flop" dadurch, dass ein FF seinen Ausgang nur als Reaktion auf eine Taktflanke ändert. Ein Latch kann seinen Ausgang als Reaktion auf etwas anderes als einen Takt ändern. Beispielsweise hat ein SR-Latch einen Set- und einen Reset-Eingang, und wenn einer von beiden aktiv ist, kann sich der Ausgang ändern. Wobei ein SR-FF nur auf ein Setzen oder Zurücksetzen reagiert, wenn auch eine Taktflanke vorhanden ist.
In einem FPGA möchten Sie, dass Ihre Logik vollständig synchron ist. Das bedeutet, dass alle Speicherelemente (wie FFs) alle von einer einzigen Taktquelle getaktet werden. Alles, was zu dieser Uhr asynchron ist, muss sehr sorgfältig behandelt werden, da sonst Zeitfehler auftreten.
Ein Latch ist im Grunde ein asynchrones Speicherelement. Es hat keinen Takteingang und kann daher mit keiner Uhr synchronisiert werden. Ich sollte beachten, dass es FFs mit asynchronen Reset- und Reset-Eingängen gibt, und diese sollten mit der gleichen Sorgfalt behandelt werden wie normale Latches.
Auf alle Timing-Probleme einzugehen, die Latches verursachen können, geht weit über das hinaus, was hier behandelt werden kann, aber lassen Sie mich Ihnen ein Beispiel geben:
Angenommen, Sie haben einen SR-Latch und möchten, dass er jedes Mal gesetzt wird, wenn ein 8-Bit-Zähler einen bestimmten Wert erreicht. Ich bin mir nicht sicher, wie der Verilog-Code lauten würde, aber in VHDL lautet der Code: set <= '1' when count="11010010" else '0'; Dieses Set-Signal geht zum Set-Eingang unseres SR-Latch.
Die erzeugte Logik ist rein kombinatorisch; eine Mischung aus Und-Gattern, Oder-Gattern und Invertern (oder LUTs). Aber die Signalpfade durch diese kombinatorische Logik sind nicht immer perfekt und das "gesetzte" Signal könnte Störungen aufweisen. Der Signalpfad durch eine bestimmte Gruppe von Gattern könnte länger dauern als durch eine andere Gruppe, wodurch der eingestellte Ausgang für einen kurzen Moment aktiv wird, bevor sich der Ausgang in den endgültigen Zustand einpendelt.
Dieser Ausgangsfehler könnte dazu führen, dass unser SR-Latch gesetzt wird, obwohl dies nicht vorgesehen war. Wenn wir von einem SR-Latch zu einem SR-FF umschalten, das mit demselben Takt getaktet ist wie der Zähler, dann wartet das SR-FF einen ganzen Taktzyklus, bevor es den Zustand ändert. Im Wesentlichen wartet es darauf, dass sich das eingestellte Signal beruhigt, bevor es betrachtet wird.
Wenn die Pfade durch die kombinatorische Logik für das eingestellte Signal nur anders geroutet werden (was zu unterschiedlichen Verzögerungen führt), ändert sich auch das Glitch-Verhalten. Die Logik könnte gut funktionieren, aber dann, weil Sie etwas völlig Unabhängiges geändert haben, wird diese Logik anders weitergeleitet, und so taucht der Fehler auf. Temperatur und Spannung ändern auch das Signaltiming und können somit das Glitch-Verhalten verändern.
Diese Unsicherheit im Timing ist der Grund, warum Sie Latches in Ihrer Logik vermeiden sollten. FFs sind viel sicherer in der Anwendung. Aus diesem Grund warnt Sie Ihr Compiler vor Latches, da es leicht ist, versehentlich einen Latch zu erstellen, und Sie ihn wahrscheinlich sowieso nicht dort haben möchten.
Natürlich sind manchmal Verriegelungen erforderlich. Sie müssen sie nur sehr selten verwenden, nur wenn es unbedingt erforderlich ist, und dann müssen Sie die Logik richtig entwerfen, damit keine Störungen möglich sind.
Was macht ein abgeleitetes Latch aus?
Für die kombinatorische Logik ist der Ausgang der Schaltung nur eine Funktion des Eingangs und sollte keinen Speicher oder internen Zustand (Latch) enthalten.
In Verilog behält eine Variable ihren vorherigen Wert, wenn ihr in einem Always - Block kein Wert zugewiesen wird. Es muss ein Latch erstellt werden, um diesen aktuellen Wert zu speichern.
Eine unvollständige if-else- Anweisung generiert Latches. Eine if-else- Anweisung gilt als „unvollständig“, wenn der Ausgangszustand nicht für alle möglichen Eingangsbedingungen definiert ist. Dasselbe gilt für eine unvollständige case - Anweisung oder eine case - Anweisung, die kein default: -Element hat.
Warum sind abgeleitete Latches schlecht?
Abgeleitete Latches können als „Warnzeichen“ dafür dienen, dass das Logikdesign möglicherweise nicht wie beabsichtigt implementiert wird. Möglicherweise fehlt eine wichtige if-else- oder case - Anweisung im Design.
Sperren können zu Zeitproblemen und Rennbedingungen führen. Sie können zu kombinatorischem Feedback führen – Routing des Ausgangs zurück zum Eingang – was unvorhersehbar sein kann.
So vermeiden Sie das Erstellen abgeleiteter Latches:
Einige Teile aus „FPGA Prototyping by Verilog Examples“ von P. Chu
Latches sind in FPGAs oder CPLDs sehr schwierig zu verwenden, daher vermeiden viele Leute sie einfach vollständig. Einer der Gründe ist, dass viele FPGAs keinen eingebauten Latch haben, also aus Logikgattern bestehen – dies kann zu unangenehmen Timing-Problemen führen.
Außerdem haben Sie keine Kontrolle über Timing-Verzögerungen und Rennbedingungen, wenn Sie einen Latch verwenden (es sei denn, es gibt ein natives Element).
Ich würde von der Verwendung von Latches abraten, es sei denn, Sie können absolut nicht darauf verzichten (z. B. Zeitausleihe, um eine erforderliche maximale Taktfrequenz zu erreichen) und Codierungstechniken verwenden, um versehentliche Schlussfolgerungen von Latches weniger wahrscheinlich zu machen.
Sequentielle Logikentwürfe, die unter Verwendung von kombinatorischer Logik und Rückkopplung konstruiert wurden, gehen im Allgemeinen von einer Annahme aus, die bei der Verwendung physikalischer Gatter vernünftig erscheint: dass sich der Ausgang eines Gatters nicht als Reaktion auf eine Änderung des Eingangs ändert, bis sich der Eingang irgendwann tatsächlich geändert hat. Es gibt einige Fälle, in denen diese Annahme bei der Verwendung echter Gatter möglicherweise nicht zutrifft (z. B. wenn ein schnelles NOR-Gatter und ein schneller Inverter beide von einem Signal angesteuert werden, das langsam von VSS auf VDD ansteigt, und wenn der Inverter bei 1,2 Volt schaltet, während das NOR Das Gatter schaltet erst bei 1,7 Volt, das NOR-Gatter sieht möglicherweise, dass der Ausgang des Inverters niedrig wird, bevor es erkennt, dass das langsam ansteigende Signal hoch gegangen ist), aber solche Probleme können im Allgemeinen durch Hinzufügen eines Puffers gelöst werden, wenn es sich langsam ändert Signal wird an mehr als ein Ziel geleitet. Leider,
Das Problem besteht darin, dass ein FPGA-Compiler, sofern nicht ausdrücklich anders angewiesen, eine kombinatorische Schaltung willkürlich durch eine völlig andere Schaltung ersetzen kann, die das gleiche stationäre Verhalten, aber möglicherweise ein völlig anderes Timing hat. Angenommen, eine komplexe kombinatorische Funktion F benötigt sechs Eingänge U bis Z. F wird direkt der Schaltung P zugeführt, und (F NAND Z) wird der Schaltung Q zugeführt. Der Compiler könnte erkennen, dass der Wert, der Q zugeführt wird, nur davon abhängt F, wenn Z hoch ist, und kann eine Funktion F' berechnen, die wie F ist, außer dass Z als hoch angenommen wird; Q kann dann mit (F' NAND Z) anstelle von (F NAND Z) gespeist werden. Es wäre durchaus möglich, dass die effizienteste Realisierung von P fünf Gatterverzögerungen hätte, aber die effizienteste Realisierung von Q hätte nur zwei. Daher,
Wenn eine Schaltung kombinatorische Rückkopplungsschleifen hat, muss ein FPGA-Compiler physikalische Signalknoten hinzufügen, die physikalisch eine positive Verzögerung haben (eine verzögerungsfreie Rückkopplungsschleife kann in der realen Welt nicht existieren), aber dafür gibt es keine Garantie solche Knoten würden an den Stellen hinzugefügt, die notwendig sind, damit sich die Schaltung wie gewünscht verhält. Es gibt auch keine Garantie dafür, dass eine geringfügige Änderung des Designs nicht dazu führt, dass der Compiler von einer willkürlichen Platzierung, die zufällig in der realen Welt funktioniert, zu einer anderen willkürlichen Platzierung wechselt, die zufällig fehlschlägt.
Details darüber, wie man einen Riegel im Design fängt, werden in diesem Link kurz erklärt.
shuckc
EML
Peter Grün