Unterschied zwischen blockierender und nicht blockierender Zuweisung Verilog

Ich habe diese Seite gelesen http://www.asic-world.com/verilog/verilog_one_day3.html als ich auf Folgendes stieß:

Normalerweise müssen wir Flip-Flops zurücksetzen, also jedes Mal, wenn die Uhr das macht Beim Übergang von 0 nach 1 (Posedge) prüfen wir, ob ein Reset aktiviert ist (synchrones Reset), und fahren dann mit der normalen Logik fort. Wenn wir genau hinschauen, sehen wir, dass wir im Fall der kombinatorischen Logik „=“ für die Zuweisung hatten und für den sequentiellen Block den Operator „< =“. Nun, „=“ blockiert die Zuweisung und „< =“ blockiert die Zuweisung nicht. „=“ führt Code nacheinander innerhalb eines Anfangs / Endes aus, während „< =“ parallel ausgeführt wird.

Ich war mir ziemlich sicher, dass nicht blockierende Zuweisungen sequentiell waren, während blockierende Zuweisungen parallel waren. Schließlich können Sie Blockierungszuweisungen mit Zuweisungsanweisungen außerhalb von Always-Blöcken vornehmen, und diese werden alle parallel ausgeführt. Ist das ein Fehler oder ist das Verhalten innerhalb eines Always-Blocks anders? Und wenn das Verhalten innerhalb eines Always-Blocks unterschiedlich ist, können nicht blockierende Zuweisungen außerhalb eines Always-Blocks vorgenommen werden?

Antwort

war ziemlich sicher, dass nicht blockierende Zuweisungen sequentiell waren, während blockierende Zuweisungen parallel waren.

Die Blockierungszuweisung wird „in Serie“ ausgeführt, da eine Blockierungszuweisung die Ausführung der nächsten Anweisung blockiert, bis sie abgeschlossen ist. Daher können die Ergebnisse der nächsten Anweisung davon abhängen, dass die erste abgeschlossen wird.

Die nicht blockierende Zuweisung wird parallel ausgeführt, da sie Zuweisungen beschreibt, die alle gleichzeitig ausgeführt werden. Das Ergebnis einer Anweisung in der 2. Zeile hängt nicht von den Ergebnissen der Anweisung in der 1. Zeile ab. Stattdessen wird die 2. Zeile so ausgeführt, als wäre die 1. Zeile noch nicht passiert.

Kommentare

  • Wie sieht es also mit Anweisungen zuweisen aus? Sind sie nur eine ganze Klasse für sich?
  • Ja, assign -Anweisungen treten außerhalb von Always-Blöcken auf und werden im Allgemeinen zur Beschreibung von kombinatorischen (nicht zwischengespeicherten) Anweisungen verwendet ) Logik (während immer Blöcke, mit einigen Ausnahmen, sequentielle Logik beschreiben). AFAIK, assign -Anweisungen führen “ immer parallel “ aus, wenn sich ihre LHS-Werte ändern .
  • Okay … Ich ‚ bekomme allmählich den Eindruck, dass Verilog nicht ‚ ist elegant gestaltete Sprache. Dies wird so sein, als würde man C lernen.
  • Verilog wurde entwickelt, um “ die bereits vorhandene “ Hardware zu beschreiben. Die Verwendung als Sprache zum Entwerfen (Synthetisieren) von Hardware ist ein Hack.
  • wenn Verilog “ wie das Lernen von C “ ist ein Problem, werfen Sie einen Blick auf VHDL. Einige Leute haben ziemlich starke Vorlieben für das eine oder andere. Für manche ist VHDL einfach zu ausführlich. Für mich ist es ‚ viel besser durchdacht. (Die Semantik der Signal- / Variablenzuweisung ist viel klarer als beispielsweise das Blockieren / Nicht-Blockieren). stackoverflow.com/questions/13954193/… und sigasi .com / content / vhdls-Kronenjuwel Vielleicht bevorzugen Sie es oder hassen es. Aber ‚ ist einen Blick wert.

Antwort

Assign-Anweisungen sind weder „blockierend“ noch „nicht blockierend“, sie sind „fortlaufend“. Die Ausgabe einer Zuweisungsanweisung entspricht immer der angegebenen Funktion der Eingaben. „Blockierende“ und „Nichtblockierende“ Zuweisungen sind nur in immer Blöcken vorhanden.

Eine blockierende Zuweisung wird sofort wirksam, wenn sie verarbeitet wird. Eine nicht blockierende Zuweisung findet am Ende der Verarbeitung des aktuellen „Zeitdeltas“ statt.

Always-Blöcke können verwendet werden, um entweder kombinatorische oder sequentielle Logik zu modellieren (Systemverilog hat always_comb und always_ff, um dies explizit zu machen) kombinatorische Logik ist normalerweise effizienter zu verwenden = aber es spielt normalerweise keine Rolle.

Bei der Modellierung sequentieller Logik (z. B. immer @ (posedge clk)) verwenden Sie normalerweise nicht blockierende Assingments. Dies ermöglicht Ihnen dies Bestimmen Sie den „Zustand nach der Taktflanke“ in Bezug auf „den Zustand vor der Taktflanke“.

Manchmal ist es nützlich, Blockierungszuweisungen in sequentiellen Blöcken immer als „Variablen“ zu verwenden. Wenn Sie dies dann tun Es sind zwei wichtige Regeln zu beachten.

  1. Greifen Sie nicht auf a zu reg, das mit blockierenden Zuweisungen innerhalb eines sequentiellen Always-Blocks von außerhalb des Always-Blocks festgelegt ist, in dem es zugewiesen ist.
  2. Mischen Sie blockierende und nicht blockierende Zuweisungen nicht mit demselben reg.

Ein Verstoß gegen diese Regeln führt wahrscheinlich zu Synthesefehlern und / oder Verhaltensunterschieden zwischen Simulation und Synthese.

Kommentare

  • “ “ Greifen Sie nicht auf eine Registrierung zu, die mit Sperrzuweisungen innerhalb eines sequentiellen Always-Blocks von außerhalb des Always-Blocks festgelegt ist wird zugewiesen in. “ “ Können Sie es bitte erklären?
  • Verschiedene sequentielle immer Blöcke haben keine definierte bestellen. Das Lesen eines “ reg “ -Satzes mit einer blockierenden Zuordnung in einem Always-Block von einem anderen Always-Block führt zu unvorhersehbarem Verhalten.
  • Und selbst wenn es in der Simulation zu funktionieren scheint, sollte sich ein Synthesewerkzeug das ansehen und “ nein “ sagen. Ich verwende lokale Regs für diese Zwischenvariablen und stelle sicher, dass sie immer bei jeder Uhr zugewiesen werden, bevor sie gelesen werden, damit kein ‚ Speicher ‚ ist impliziert.
  • IIRC zumindest in Quartus wird es nur als Warnung und nicht als Fehler betrachtet.
  • Sie sollten keine nicht blockierende Zuweisung in der kombinatorischen Logik verwenden, sie kann blockieren die Simulation. Weitere Informationen finden Sie in dieser Antwort: electronic.stackexchange.com/a/506047/238188

Antwort

Der Begriff Blockierungszuweisung verwirrt die Menschen, da das Wort Blockierung eine zeitlich sequentielle Logik nahe legt. In der synthetisierten Logik bedeutet dies jedoch nicht , da alles funktioniert parallel .

Ein weniger verwirrender Begriff wäre möglicherweise die sofortige Zuweisung , die die Zwischenergebnisse der kombinatorischen Logik immer noch von der unterscheidet Eingaben in nicht transparente Speicherelemente (z. B. getaktete Register), die eine verzögerte Zuweisung haben können.

Aus legalistischer Sicht funktioniert alles sehr gut. Sie können die = sogar innerhalb von always_comb div als blockierende (zeitsequenzielle) Operation betrachten > Sequenzen. Die Unterscheidung zwischen zeitlich sequentiell und parallel macht in diesem Fall jedoch absolut keinen Unterschied. , da die always_comb -Block wird so definiert, dass er wiederholt wird, bis die Befehlssequenz in einem stabilen Zustand konvergiert – genau das tut die Hardware-Schaltung (wenn sie die Timing-Anforderungen erfüllt).

Die synthetisierbare Teilmenge von Verilog (und insbesondere SystemVerilog) ist extrem einfach und einfach zu verwenden – sobald Sie die erforderlichen Redewendungen kennen. Sie müssen nur die geschickte Verwendung der Terminologie überwinden, die mit den sogenannten Verhaltenselementen in der Sprache verbunden ist.

Kommentare

  • In Verhaltenskodierungsstilen ( im Vergleich zu RTL ) kann die Unterscheidung zwischen Blockieren und Nichtblockieren relevant sein. In einigen Fällen kann das Synthesewerkzeug möglicherweise funktional äquivalente RTL aus Verhaltenskomponentenentwürfen ableiten.
  • Natürlich das prozedurale Der Modus von SystemVerilog, der insbesondere für initial -Anweisungen in program -Blöcken gilt, verwendet die (zeitsequenzielle) Blockierungszuweisung ausschließlich. Dies ist nützlich für das Testbench -Design, im Allgemeinen jedoch nicht für die RTL-Spezifikation.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.