Verilog Timescale meistern: Einheiten, Präzision und genaue Simulationszeit
Die Verilog-Simulation hängt davon ab, wie Zeit definiert ist, weil der Simulator wissen muss, was ein #1 in Bezug auf Zeit bedeutet. Die `timescale-Compiler-Direktive spezifiziert die Zeiteinheit und Präzision für die Module, die ihr folgen.
Syntax
`timescale <time_unit>/<time_precision>
// Beispiel
`timescale 1ns/1ps
`timescale 10us/100ns
`timescale 10ns/1ns
Die time_unit ist das Maß für Delays und Simulationszeit, während die time_precision spezifiziert, wie Delay-Werte gerundet werden, bevor sie in der Simulation verwendet werden.
Verwenden Sie die folgenden Timescale-Konstrukte, um verschiedene Zeiteinheiten im selben Design zu verwenden. Denken Sie daran, dass Delay-Spezifikationen im Design nicht synthetisierbar sind und nicht in Hardware-Logik umgewandelt werden können.
`timescalefür Basiseinheit der Messung und Präzision der Zeit$printtimescaleSystem-Task zum Anzeigen von Zeiteinheit und Präzision$timeund$realtimeSystemfunktionen geben die aktuelle Zeit zurück, und das Standardberichtsformat kann mit einem anderen System-Task$timeformatgeändert werden.
| Zeichen | Einheit |
|---|---|
| s | Sekunden |
| ms | Millisekunden |
| us | Mikrosekunden |
| ns | Nanosekunden |
| ps | Pikosekunden |
| fs | Femtosekunden |
Die Ganzzahlen in diesen Spezifikationen können entweder 1, 10 oder 100 sein, und die Zeichenkette, die die Einheit spezifiziert, kann jeden der in der Tabelle oben genannten Werte annehmen.
Beispiel #1: 1ns/1ns
// Timescale deklarieren, wo time_unit 1ns
// und time_precision ebenfalls 1ns ist
`timescale 1ns/1ns
module tb;
// Um den Effekt von timescale zu verstehen, treiben wir
// ein Signal mit einigen Werten nach einiger Verzögerung an
reg val;
initial begin
// Signal zur Zeit 0 Einheiten auf 0 initialisieren
val <= 0;
// Um 1 Zeiteinheit vorrücken, Nachricht anzeigen und val toggeln
#1 $display ("T=%0t At time #1", $realtime);
val <= 1;
// Um 0.49 Zeiteinheiten vorrücken und val toggeln
#0.49 $display ("T=%0t At time #0.49", $realtime);
val <= 0;
// Um 0.50 Zeiteinheiten vorrücken und val toggeln
#0.50 $display ("T=%0t At time #0.50", $realtime);
val <= 1;
// Um 0.51 Zeiteinheiten vorrücken und val toggeln
#0.51 $display ("T=%0t At time #0.51", $realtime);
val <= 0;
// Simulation für weitere 5 Zeiteinheiten laufen lassen und beenden
#5 $display ("T=%0t End of simulation", $realtime);
end
endmodule
Die erste Delay-Anweisung verwendet #1, was den Simulator veranlasst, genau 1 Zeiteinheit zu warten, was als 1ns mit der `timescale-Direktive spezifiziert ist. Die zweite Delay-Anweisung verwendet 0.49, was weniger als eine halbe Zeiteinheit ist. Da die Zeitpräzision jedoch auf 1ns spezifiziert ist, kann der Simulator nicht kleiner als 1ns werden, was dazu führt, dass der gegebene Delay gerundet wird und 0ns ergibt. Also scheitert der zweite Delay daran, die Simulationszeit voranzutreiben.
Die dritte Delay-Anweisung verwendet genau eine halbe Zeiteinheit #0.5 und wieder wird der Simulator den Wert runden, um #1 zu erhalten, was eine ganze Zeiteinheit darstellt. Also wird dies bei T=2ns ausgegeben.
Die vierte Delay-Anweisung verwendet einen Wert, der mehr als eine halbe Zeiteinheit beträgt, und wird ebenfalls gerundet, wodurch die Display-Anweisung bei T=3ns ausgegeben wird.
Simulationslog:
ncsim> run T=1 At time #1 T=1 At time #0.49 T=2 At time #0.50 T=3 At time #0.51 T=8 End of simulation ncsim: *W,RNQUIE: Simulation is complete.
Die Simulation läuft für 8ns wie erwartet, aber beachten Sie, dass das Waveform keine kleineren Divisionen zwischen jedem Nanosekunden hat. Dies liegt daran, dass die Zeitpräzision dieselbe ist wie die Zeiteinheit.
Beispiel #2: 10ns/1ns
Die einzige Änderung in diesem Beispiel im Vergleich zum vorherigen ist, dass der Timescale von 1ns/1ns auf 10ns/1ns geändert wurde. Also ist die Zeiteinheit 10ns und die Präzision bei 1ns.
// Timescale deklarieren, wo time_unit 10ns
// und time_precision 1ns ist
`timescale 10ns/1ns
// HINWEIS: Testbench ist dieselbe wie im vorherigen Beispiel
module tb;
reg val;
initial begin
val <= 0;
#1 $display ("T=%0t At time #1", $realtime);
val <= 1;
#0.49 $display ("T=%0t At time #0.49", $realtime);
val <= 0;
#0.50 $display ("T=%0t At time #0.50", $realtime);
val <= 1;
#0.51 $display ("T=%0t At time #0.51", $realtime);
val <= 0;
#5 $display ("T=%0t End of simulation", $realtime);
end
endmodule
Die tatsächliche Simulationszeit wird durch Multiplikation des mit # spezifizierten Delays mit der Zeiteinheit erhalten und dann basierend auf der Präzision gerundet. Die erste Delay-Anweisung ergibt dann 10ns und die zweite gibt 14.9, was gerundet zu 15ns wird.
Die dritte Anweisung fügt ähnlich 5ns (0.5 * 10ns) hinzu und die Gesamtzeit wird 20ns. Die vierte fügt weitere 5ns (0.51 * 10) hinzu, um die Gesamtzeit auf 25ns voranzutreiben.
Simulationslog:
ncsim> run T=10 At time #1 T=15 At time #0.49 T=20 At time #0.50 T=25 At time #0.51 T=75 End of simulation ncsim: *W,RNQUIE: Simulation is complete.
Beachten Sie, dass die Basiseinheit im Waveform in Zehnern von Nanosekunden mit einer Präzision von 1ns ist.
Beispiel #3: 1ns/1ps
Die einzige Änderung in diesem Beispiel im Vergleich zum vorherigen ist, dass der Timescale von 1ns/1ns auf 1ns/1ps geändert wurde. Also ist die Zeiteinheit 1ns und die Präzision bei 1ps.
// Timescale deklarieren, wo time_unit 1ns
// und time_precision 1ps ist
`timescale 1ns/1ps
// HINWEIS: Testbench ist dieselbe wie im vorherigen Beispiel
module tb;
reg val;
initial begin
val <= 0;
#1 $display ("T=%0t At time #1", $realtime);
val <= 1;
#0.49 $display ("T=%0t At time #0.49", $realtime);
val <= 0;
#0.50 $display ("T=%0t At time #0.50", $realtime);
val <= 1;
#0.51 $display ("T=%0t At time #0.51", $realtime);
val <= 0;
#5 $display ("T=%0t End of simulation", $realtime);
end
endmodule
Man sieht, dass die Zeiteinheiten skaliert wurden, um dem neuen Präzisionswert von 1ps zu entsprechen. Beachten Sie auch, dass die Zeit in der kleinsten Auflösung dargestellt wird, was in diesem Fall Pikosekunden sind.
Simulationslog:
ncsim> run T=1000 At time #1 T=1490 At time #0.49 T=1990 At time #0.50 T=2500 At time #0.51 T=7500 End of simulation ncsim: *W,RNQUIE: Simulation is complete.
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 Scheduling Semantics verstehen: Timing, Events und Ausführungsreihenfolge
- Verilog Clock Generator: Design & Implementierungsleitfaden
- Verilog Math Functions meistern für effizientes Hardware-Design
- Verilog $timeformat meistern: Präzision und Anzeigesteuerung