Verilog Timescale beheersen: Units, Precision, en Accurate Simulatie-timing
Verilog-simulatie hangt af van hoe tijd gedefinieerd is omdat de simulator moet weten wat een #1 betekent in termen van tijd. De \`timescale compiler-directive specificeert de tijdseenheid en precisie voor de modules die erop volgen.
Syntax
\`timescale <tijdseenheid>/<tijdprecisie>
// Voorbeelden
\`timescale 1ns/1ps
\`timescale 10us/100ns
\`timescale 10ns/1ns
De tijdseenheid is de meting van vertragingen en simulatiettijd terwijl de tijdprecisie specificeert hoe delay-waarden afgerond worden voordat ze in simulatie gebruikt worden.
Gebruik de volgende timescale-constructies om verschillende tijdseenheden in hetzelfde ontwerp te gebruiken. Onthoud dat delay-specificaties in het ontwerp niet synthetiseerbaar zijn en niet omgezet kunnen worden naar hardwarelogica.
\`timescalevoor basiseenheid van meting en precisie van tijd$printtimescalesystem-taak om tijdseenheid en precisie weer te geven$timeen$realtimesystem-functies geven de huidige tijd terug en het standaard rapportageformaat kan gewijzigd worden met een andere system-taak$timeformat.
| Karakter | Eenheid |
|---|---|
| s | seconden |
| ms | milliseconden |
| us | microseconden |
| ns | nanoseconden |
| ps | picoseconden |
| fs | femtoseconden |
De integers in deze specificaties kunnen 1, 10 of 100 zijn en de karakaterstring die de eenheid specificeert kan elke waarde uit de bovenstaande tabel aannemen.
Voorbeeld #1: 1ns/1ns
// Declareren van de timescale waar tijdseenheid 1ns
// en tijdprecisie ook 1ns is
\`timescale 1ns/1ns
module tb;
// Om het effect van timescale te begrijpen, laten we
// een signaal sturen met sommige waarden na enige vertraging
reg val;
initial begin
// Initialiseer het signaal op 0 op tijd 0 eenheden
val <= 0;
// Ga vooruit met 1 tijdseenheid, toon bericht en toggle val
#1 $display ("T=%0t Op tijd #1", $realtime);
val <= 1;
// Ga vooruit met 0.49 tijdseenheid en toggle val
#0.49 $display ("T=%0t Op tijd #0.49", $realtime);
val <= 0;
// Ga vooruit met precies half de tijdseenheid en toggle val
#0.50 $display ("T=%0t Op tijd #0.50", $realtime);
val <= 1;
// Ga vooruit met meer dan half de tijdseenheid en toggle val
#0.51 $display ("T=%0t Op tijd #0.51", $realtime);
val <= 0;
// Laat simulatie nog 5 tijdseenheden lopen en stop
#5 $display ("T=%0t Einde van simulatie", $realtime);
end
endmodule
De eerste delay-statement gebruikt #1 wat de simulator laat wachten voor precies 1 tijdseenheid gespecificeerd als 1ns met de \`timescale-directive. De tweede delay-statement gebruikt 0.49 wat minder dan half een tijdseenheid is. Echter de tijdprecisie is gespecificeerd als 1ns en dus kan de simulator niet kleiner gaan dan 1ns wat ervoor zorgt dat de gegeven delay-statement afgerond wordt en 0ns oplevert. Dus de tweede delay slaagt er niet in de simulatiettijd vooruit te schuiven.
De derde delay-statement gebruikt precies half de tijdseenheid #0.5 en weer zal de simulator de waarde afronden om #1 te krijgen wat één hele tijdseenheid vertegenwoordigt. Dus dit wordt geprint op T=2ns.
De vierde delay-statement gebruikt een waarde meer dan half de tijdseenheid en wordt ook afgerond wat ervoor zorgt dat de display-statement geprint wordt op T=3ns.
Simulatie-log
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.
De simulatie loopt voor 8ns zoals verwacht, maar let op dat de golfvorm geen kleinere divisies heeft tussen elke nanoseconde. Dit is omdat de precisie van tijd hetzelfde is als de tijdseenheid.
Voorbeeld #2: 10ns/1ns
De enige wijziging in dit voorbeeld ten opzichte van het vorige is dat de timescale gewijzigd is van 1ns/1ns naar 10ns/1ns. Dus de tijdseenheid is 10ns en precisie is 1ns.
// Declareren van de timescale waar tijdseenheid 10ns
// en tijdprecisie 1ns is
\`timescale 10ns/1ns
// LET OP: Testbench is hetzelfde als in vorig voorbeeld
module tb;
reg val;
initial begin
val <= 0;
#1 $display ("T=%0t Op tijd #1", $realtime);
val <= 1;
#0.49 $display ("T=%0t Op tijd #0.49", $realtime);
val <= 0;
#0.50 $display ("T=%0t Op tijd #0.50", $realtime);
val <= 1;
#0.51 $display ("T=%0t Op tijd #0.51", $realtime);
val <= 0;
#5 $display ("T=%0t Einde van simulatie", $realtime);
end
endmodule
De actuele simulatiettijd wordt verkregen door de delay gespecificeerd met # te vermenigvuldigen met de tijdseenheid en dan af te ronden op basis van precisie. De eerste delay-statement levert dan 10ns op en de tweede geeft 14.9 wat afgerond wordt tot 15ns.
De derde statement voegt op dezelfde manier 5ns toe (0.5 * 10ns) en de totale tijd wordt 20ns. De vierde voegt nog 5ns toe (0.51 * 10) om de totale tijd naar 25ns te brengen.
Simulatie-log
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.
Let op dat de basiseenheid in de golfvorm in tientallen nanoseconden is met een precisie van 1ns.
Voorbeeld #3: 1ns/1ps
De enige wijziging in dit voorbeeld ten opzichte van het vorige is dat de timescale gewijzigd is van 1ns/1ns naar 1ns/1ps. Dus de tijdseenheid is 1ns en precisie is 1ps.
// Declareren van de timescale waar tijdseenheid 1ns
// en tijdprecisie 1ps is
\`timescale 1ns/1ps
// LET OP: Testbench is hetzelfde als in vorig voorbeeld
module tb;
reg val;
initial begin
val <= 0;
#1 $display ("T=%0t Op tijd #1", $realtime);
val <= 1;
#0.49 $display ("T=%0t Op tijd #0.49", $realtime);
val <= 0;
#0.50 $display ("T=%0t Op tijd #0.50", $realtime);
val <= 1;
#0.51 $display ("T=%0t Op tijd #0.51", $realtime);
val <= 0;
#5 $display ("T=%0t Einde van simulatie", $realtime);
end
endmodule
Zie dat de tijdseenheden geschaald zijn om de nieuwe precisiewaarde van 1ps te matchen. Let ook op dat tijd gerepresenteerd wordt in de kleinste resolutie wat in dit geval picoseconden is.
Simulatie-log
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 beheersen: Complete tutorial voor digitale schakelingontwerp
- Verilog concatenatie beheersen: Een praktische gids
- Verilog-toewijzingen begrijpen: types, syntax en best practices
- Verilog Blocking vs. Non-Blocking: belangrijkste verschillen uitgelegd
- Verilog-functies beheersen voor efficiënt RTL-ontwerp
- Verilog Tasks begrijpen: Functions vs Tasks, Syntax en Gebruik
- Verilog Scheduling Semantics begrijpen: Timing, Events, en Uitvoeringsvolgorde
- Verilog Clock Generator: Ontwerp & Implementatie Gids
- Verilog Math Functions beheersen voor efficiënt Hardware-ontwerp
- Verilog $timeformat beheersen: Precisie en Weergave-controle
- Verilog Timescales begrijpen en printen in elke Scope