Verilog-Simulationstechniken für zuverlässige RTL-Verifikation
Verilog ist eine Hardware-Beschreibungssprache, und es gibt keine Anforderung für Designer, ihre RTL-Designs zu simulieren, um sie in Logikgatter umwandeln zu können. Also, was ist der Bedarf an Simulation?
Simulation ist eine Technik, bei der verschiedene Eingangsreize (Stimuli) zu verschiedenen Zeiten auf das Design angewendet werden, um zu prüfen, ob der RTL-Code sich wie beabsichtigt verhält. Im Wesentlichen ist Simulation eine bewährte Technik, um die Robustheit des Designs zu verifizieren. Sie ist auch ähnlich wie ein gefertigter Chip in der realen Welt verwendet wird und wie er auf verschiedene Eingänge reagiert.
Zum Beispiel stellt das obige Design einen positiven Flankendetektor mit den Eingängen Clock und Signal dar, die in regelmäßigen Abständen ausgewertet werden, um den Ausgang pe zu finden, wie gezeigt. Die Simulation ermöglicht es uns, das Timing-Diagramm verwandter Signale anzuzeigen, um zu verstehen, wie sich die Designbeschreibung in Verilog tatsächlich verhält.
Es gibt mehrere EDA-Unternehmen, die Simulatoren entwickeln, die in der Lage sind, die Ausgänge für verschiedene Eingänge des Designs zu ermitteln. Verilog ist in Bezug auf ein diskretes Ereignis-Ausführungsmodell definiert, und verschiedene Simulatoren sind frei, verschiedene Algorithmen zu verwenden, um dem Benutzer einen konsistenten Satz von Ergebnissen zu liefern. Der Verilog-Code wird in mehrere Prozesse und Threads unterteilt und kann zu verschiedenen Zeiten im Verlauf einer Simulation ausgewertet werden, worauf später eingegangen wird.
Beispiel
Der Testbench namens tb ist ein Container, der ein Design-Modul hält. In diesem Beispiel haben wir jedoch keine Design-Instanzen verwendet. Es gibt zwei Variablen oder Signale, die zu bestimmten Zeiten bestimmte Werte zugewiesen bekommen können. clk repräsentiert einen Takt, der innerhalb des Testbenchs generiert wird. Dies wird durch die always-Anweisung getan, indem der Taktwert nach jedem 5ns abwechselnd wird. Der initial-Block enthält eine Reihe von Anweisungen, die zu verschiedenen Zeiten unterschiedliche Werte beiden Signalen zuweisen.
module tb;
reg clk;
reg sig;
// Clock-Generierung
// Prozess startet bei Zeit 0ns und schleift nach jedem 5ns
always #5 clk = ~clk;
// Initial-Block: Prozess startet bei Zeit 0ns
initial begin
// Dieser System-Task gibt die Signalwerte jedes Mal aus, wenn sie sich ändern
$monitor("Time = %0t clk = %0d sig = %0d", $time, clk, sig);
// Auch Stimulus genannt, wir weisen einfach den Variablen
// nach einiger Simulations-"Verzögerung" unterschiedliche Werte zu
sig = 0;
#5 clk = 0; // Weist clk 0 zur Zeit 5ns zu
#15 sig = 1; // Weist sig 1 zur Zeit 20ns zu (#5 + #15)
#20 sig = 0; // Weist sig 0 zur Zeit 40ns zu (#5 + #15 + #20)
#15 sig = 1; // Weist sig 1 zur Zeit 55ns zu
#10 sig = 0; // Weist sig 0 zur Zeit 65ns zu
#20 $finish; // Beendet Simulation zur Zeit 85ns
end
endmodule
Der Simulator liefert die folgende Ausgabe nach Ausführung des obigen Testbenchs.
Simulationslog:
ncsim> run Time = 0 clk = x sig = 0 Time = 5 clk = 0 sig = 0 Time = 10 clk = 1 sig = 0 Time = 15 clk = 0 sig = 0 Time = 20 clk = 1 sig = 1 Time = 25 clk = 0 sig = 1 Time = 30 clk = 1 sig = 1 Time = 35 clk = 0 sig = 1 Time = 40 clk = 1 sig = 0 Time = 45 clk = 0 sig = 0 Time = 50 clk = 1 sig = 0 Time = 55 clk = 0 sig = 1 Time = 60 clk = 1 sig = 1 Time = 65 clk = 0 sig = 0 Time = 70 clk = 1 sig = 0 Time = 75 clk = 0 sig = 0 Time = 80 clk = 1 sig = 0 Simulation complete via $finish(1) at time 85 NS + 0
Was ist ein Simulations-Waveform?
Simulationen erlauben es uns, Design- und Testbench-Signale in ein Waveform zu dumpen, das grafisch dargestellt werden kann, um die Funktionalität des RTL-Designs zu analysieren und zu debuggen. Das unten gezeigte Waveform wurde von einem EDA-Tool erhalten und zeigt den Fortschritt jedes Signals in Bezug auf die Zeit und ist dasselbe wie das zuvor gezeigte Timing-Diagramm.
Jede Wertänderung einer Variable oder eines Nets wird als Update-Event bezeichnet. Und Prozesse sind empfindlich auf Update-Events, sodass diese Prozesse ausgewertet werden, wann immer das Update-Event eintritt, und dies wird als Evaluation-Event bezeichnet. Aufgrund der Möglichkeit, mehrere Prozesse willkürlich auszuwerten, muss die Reihenfolge der Änderungen in einer sogenannten Event-Queue verfolgt werden.
Natürlich sind sie nach Simulationszeit geordnet. Die Platzierung eines neuen Events in der Queue wird Scheduling genannt. Simulationszeit bezieht sich auf den Zeitwert, der vom Simulator verwaltet wird, um die tatsächliche Zeit zu modellieren, die der simulierten Schaltung benötigen würde. Die Zeitwerte für das obige Beispiel sind in Nanosekunden ns im Timing-Diagramm dargestellt.
module des;
wire abc;
wire a, b, c;
assign abc = a & b | c;
// abc wird über die assign-Anweisung (Prozess) aktualisiert, wann immer a, b oder c sich ändern -> Update-Event
endmodule
Verilog auffrischen und ein Beispiel sehen!
Regionen in der Event-Queue
Die Verilog-Event-Queue ist logisch in fünf Regionen unterteilt, und Events können zu beliebigen von ihnen hinzugefügt werden. Sie können jedoch nur aus der aktiven Region entfernt werden.
| Events | Beschreibung |
|---|---|
| Active | Treten zur aktuellen Simulationszeit auf und können in beliebiger Reihenfolge verarbeitet werden |
| Inactive | Treten zur aktuellen Simulationszeit auf, werden aber nach allen aktiven Events verarbeitet |
| Nonblocking | Wurden zu einem früheren Zeitpunkt ausgewertet, aber die Zuweisung erfolgt in der aktuellen Simulationszeit nach aktiven und inaktiven Events |
| Monitor | Werden nach allen aktiven, inaktiven und Non-Blocking-Events verarbeitet |
| Future | Treten zu einem zukünftigen Simulationszeitpunkt auf |
Ein Simulationszyklus ist der, in dem alle aktiven Events verarbeitet werden. Der Standard garantiert eine bestimmte Scheduling-Reihenfolge, abgesehen von wenigen Fällen. Zum Beispiel werden Anweisungen innerhalb eines begin-end-Blocks nur in der Reihenfolge ausgeführt, in der sie erscheinen.
module tb;
reg [3:0] a;
reg [3:0] b;
initial begin
// Anweisungen werden nacheinander zu den entsprechenden Simulationszeiten ausgeführt
a = 5; // Zur Zeit 0ns wird a mit 5 zugewiesen
b = 2; // Im selben Simulationsschritt (Zeit 0ns) wird b mit 2 zugewiesen
#10 a = 7; // Wenn die Simulation auf 10ns fortschreitet, wird a mit 7 zugewiesen
end
endmodule
Die Event-Queue definiert, dass die Zuweisung an b nach der Zuweisung an a erfolgen sollte.
Verilog
- Verilog meistern: Komplettes Tutorial für digitales Schaltungsdesign
- Verilog Concatenation meistern: Praktischer Leitfaden
- Verilog Assignments verstehen: Typen, Syntax und Best Practices
- Verilog Blocking vs. Non-Blocking: Wichtige Unterschiede erklärt
- Verilog Functions meistern für effizientes RTL-Design
- Verilog Tasks verstehen: Functions vs. Tasks, Syntax und Verwendung
- Verilog `ifdef: Bedingte Kompilierung erklärt
- Verilog Scheduling Semantics verstehen: Timing, Events und Ausführungsreihenfolge
- Verilog Clock Generator: Design & Implementierungsleitfaden
- Verilog Display Tasks meistern: Effizientes Debugging & Logging