Frage zu Synthesizable For loop und Generate

Ich verwende die Verilog-Sprache und Zedboard als Zielplatine.

Soweit ich weiß kann die for-Schleife synthetisiert werden, und das Synthesewerkzeug übersetzt die for-Schleife als eine Folge von doppelten Anweisungen wie das Abrollen der Schleife.

Zum Beispiel

for ( i = 0; i < 4; i=i+1) begin mem[i] = i; end will be translated to mem[0] = 0; mem[1] = 1; mem[2] = 2; mem[3] = 3; 

Soweit ich weiß, kann die for-Schleife daher verwendet werden, wenn die Ressource verfügbar ist, um auf die mehreren, aber gleichartigen Gates zu schließen.

Es scheint jedoch, dass die in Verilog generiert wird kann verwendet werden, um nicht nur die mehreren Instanzen zu implizieren, sondern auch die mehreren Anweisungen, die mit der for-Schleife identisch sind.

Ich verstehe, dass das Generieren nur die mehreren Instanzen des Moduls implizieren kann und die for-Schleife nicht verwendet werden kann zu diesem Zweck.

Was ist dann der Unterschied zwischen der Generate + for-Schleife und der Nur-for-Schleife? Ich denke, beide funktionieren wie das Abrollen der Schleife. Gibt es einen spürbaren Unterschied? Wenn es keinen Unterschied gibt, welcher Codierungsstil ist vorzuziehen, um das Abrollen der Schleife zu induzieren?

Kommentare

  • Nur aus Gründen der Klarheit ' s: Ich impliziere, Sie schließen daraus. z.B. Sie implizieren einen RAM in Verilog / VHDL. Die Synthesesoftware leitet diesen RAM von Ihrem Verilog / VHDL ab. Sehr häufiger Fehler, der es wert ist, gelernt zu werden.

Antwort

Verilog-for-Schleifen sind unter bestimmten Bedingungen perfekt synthetisierbar:

  • Sie können eine beliebige prozedurale Anweisung innerhalb einer Schleife verwenden (z. B. if-else).
  • Die Anzahl der Schleifen muss vorbestimmt sein .
    • Der einschränkende Ausdruck muss ein Vergleich zwischen der Schleifenvariablen und entweder einer Konstanten oder einem Parameter sein.
    • Die Schrittzuweisung muss den Schleifenwert um einen konstanten Betrag erhöhen.
  • Sie können derselben Variablen in jeder Schleife einen anderen Wert zuweisen (z. B. Berechnen eines Index aus der Schleifenvariablen).
  • Für Synthesezwecke wird die Schleife ausgewertet in null Zeit – dh wenn Sie versuchen, einen Zähler zu erstellen, wird immer nur der Endwert angezeigt.

Dieselben Regeln gelten unabhängig davon, ob Sie eine for-Schleife in einem prozeduralen Block verwenden oder in einem Erzeugungsblock.

Wenn Sie in einem prozeduralen Block initial und always ausführen, können Sie ein for verwenden Schleife, um Elemente in einem Array zu ändern (genau wie in Ihrem Beispiel), oder Sie können denselben Wert mehrmals ändern, zum Beispiel:

for (idx = 0; idx < 4; idx=idx+1) begin a = a + b[idx]; c = c + 2; //You can change more than one variable in a for loop end 

In diesem Beispiel Die resultierende Hardware ist eine Kette von Addierern, die die Werte aus vier Array-Indizes summieren.

Das Wichtigste ist, dass Sie in einer prozeduralen for-Schleife keine neuen Variablen oder Module erstellen können. Diese Regel gilt für Prozedurblöcke im Allgemeinen, nicht nur für Schleifen (dh Sie können eine Variable in einem Prozedurblock nicht deklarieren).

 

Generieren von Blöcken ermöglicht andererseits das Erstellen von Variablen und das Instanziieren von Modulen. Das bedeutet, dass Sie in einem generierten Block eine generate for-Schleife verwenden können, um Module abzuleiten. Das ist so ziemlich der einzige Unterschied.

Zum Generieren für Schleifen müssen Sie eine genvar als Schleifenvariable verwenden (dh den Wert, den Sie zum Zählen durch jede Schleife verwenden). Sie müssen der for-Schleife auch einen Namen geben:

for (loopVal = 0; loopVal < 4; loopVal = loopVal + 1) begin : loopName 

Dieser Name wird jeder Hardware vorangestellt, die Sie in der Schleife instanziieren. Wenn Sie also eine Instanz mit dem Namen bob erstellen, erstellt die obige Schleife Instanzen:

loopName[0]|bob loopName[1]|bob loopName[2]|bob loopName[3]|bob 

Dies führt zu mehreren Instanzen mit eindeutigen Namen.

 

Sowohl das Generieren als auch das Prozedurieren für Schleifen führen das Abrollen der Schleife durch, wie Sie sagen. Der Unterschied ist einfach, wie Sie sie verwenden können. Prozedural kann in Prozedurblöcken verwendet werden (z. B. zum Initialisieren eines Speichers). Generieren kann nur zum Generieren von Blöcken verwendet werden.

Sie sind sowohl nützlich als auch bevorzugt. Einer kann den anderen nicht ersetzen.

Kommentare

  • Eine andere Art, sich Generieren vorzustellen, ist eine Art Vorprozessor, Ihr Verilog-Compiler ' führt ' Dinge in Generierungsblöcken an dem Punkt aus, an dem ' den enthaltenden Block instanziiert die generiert – sie ' treten nicht zur Laufzeit auf (im Gegensatz zu prozeduralen Schleifen)
  • @Taniwha prozedurale Schleifen don ' Sie werden auch nicht zur Laufzeit ausgeführt. Sie werden vom Compiler abgewickelt. Am Ende läuft alles auf Hardware hinaus. ' Verwechseln Sie den Präprozessor nicht mit generierten Anweisungen, dies ist jedoch nicht der Fall Das gleiche Konzept – Verilog verfügt über einen Präprozessor mit Anweisungen vom Typ if-else.
  • @TomCarpenter Ich freue mich über eine gute Antwort. Ich konnte alle Ihre Punkte außer der Generate for-Schleife verstehen.Es scheint, dass begin: etwas direkt vor der for-Schleife hinzugefügt werden sollte, kann aber nicht verstehen, wie es beim Instanziieren von Modulen funktioniert. Ist der loopName eine Variable oder nur eine Zeichenfolge? Und wie sie von [1] bis [4] indiziert werden können.
  • @JaeHyukLee loopName ist nur Text, wie ein Instanzname oder ein Signalname. Es kann alles sein, was Sie wollen.
  • @TomCarpenter – es hängt vom Compiler ab – wenn Sie ' Gates kompilieren, werden sie abgewickelt, wenn Sie ' Code für die Simulation wird eher nicht kompiliert (Haftungsausschluss, ich ' habe einen Verilog-Compiler geschrieben)

Schreibe einen Kommentar

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