Verilog simulation depends on how time is defined because the simulator needs to know what a #1 means in terms of time. The `timescale
compiler directive specifies the time unit and precision for the modules that follow it.
Syntax
`timescale <time_unit>/<time_precision>
// Example
`timescale 1ns/1ps
`timescale 10us/100ns
`timescale 10ns/1ns
The time_unit is the measurement of delays and simulation time while the time_precision specifies how delay values are rounded before being used in simulation.
Use the following timescale constructs to use different time units in the same design. Remember that delay specifications in the design are not synthesizable and cannot be converted to hardware logic.
`timescale
for base unit of measurement and precision of time- $printtimescale system task to display time unit and precision
$time
and$realtime
system functions return the current time and the default reporting format can be changed with another system task$timeformat
.
Character | Unit |
---|---|
s | seconds |
ms | milliseconds |
us | microseconds |
ns | nanoseconds |
ps | picoseconds |
fs | femtoseconds |
The integers in these specifications can be either 1, 10 or 100 and the character string that specifies the unit can take any value mentioned in the table above.
Example #1: 1ns/1ns
// Declare the timescale where time_unit is 1ns
// and time_precision is also 1ns
`timescale 1ns/1ns
module tb;
// To understand the effect of timescale, let us
// drive a signal with some values after some delay
reg val;
initial begin
// Initialize the signal to 0 at time 0 units
val <= 0;
// Advance by 1 time unit, display a message and toggle val
#1 $display ("T=%0t At time #1", $realtime);
val <= 1;
// Advance by 0.49 time unit and toggle val
#0.49 $display ("T=%0t At time #0.49", $realtime);
val <= 0;
// Advance by 0.50 time unit and toggle val
#0.50 $display ("T=%0t At time #0.50", $realtime);
val <= 1;
// Advance by 0.51 time unit and toggle val
#0.51 $display ("T=%0t At time #0.51", $realtime);
val <= 0;
// Let simulation run for another 5 time units and exit
#5 $display ("T=%0t End of simulation", $realtime);
end
endmodule
The first delay statement uses #1 which makes the simulator wait for exactly 1 time unit which is specified to be 1ns with `timescale
directive. The esecond delay statement uses 0.49 which is less than half a time unit. However the time precision is specified to be 1ns and hence the simulator cannot go smaller than 1 ns which makes it to round the given delay statement and yields 0ns. So the second delay fails to advance the simulation time.
The third delay statement uses exactly half the time unit [hl]#0.5[/lh] and again the simulator will round the value to get #1 which represents one whole time unit. So this gets printed at T=2ns.
The fourth delay statement uses a value more than half the time unit and gets rounded as well making the display statement to be printed at T=3ns.
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.
The simulation runs for 8ns as expected, but notice that the waveform does not have smaller divisions between each nanosecond. This is because the precision of time is the same as the time unit.

Example #2: 10ns/1ns
The only change made in this example compared to the previous one is that the timescale has been changed from 1ns/1ns to 10ns/1ns. So the time unit is 10ns and precision is at 1ns.
// Declare the timescale where time_unit is 10ns
// and time_precision is 1ns
`timescale 10ns/1ns
// NOTE: Testbench is the same as in previous example
module tb;
// To understand the effect of timescale, let us
// drive a signal with some values after some delay
reg val;
initial begin
// Initialize the signal to 0 at time 0 units
val <= 0;
// Advance by 1 time unit, display a message and toggle val
#1 $display ("T=%0t At time #1", $realtime);
val <= 1;
// Advance by 0.49 time unit and toggle val
#0.49 $display ("T=%0t At time #0.49", $realtime);
val <= 0;
// Advance by 0.50 time unit and toggle val
#0.50 $display ("T=%0t At time #0.50", $realtime);
val <= 1;
// Advance by 0.51 time unit and toggle val
#0.51 $display ("T=%0t At time #0.51", $realtime);
val <= 0;
// Let simulation run for another 5 time units and exit
#5 $display ("T=%0t End of simulation", $realtime);
end
endmodule
Actual simulation time is obtained by multiplying the delay specified using #
with the time unit and then it is rounded off based on precision. The first delay statement will then yield 10ns and the second one gives 14.9 which gets rounded to become 15ns.
The third statement similarly adds 5ns (0.5 * 10ns) and the total time becomes 20ns. The fourth one adds another 5ns (0.51 * 10) to advance total time to 25ns.
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.
Note that the base unit in waveform is in tens of nanoseconds with a precision of 1ns.

Example #3: 1ns/1ps
The only change made in this example compared to the previous one is that the timescale has been changed from 1ns/1ns to 1ns/1ps. So the time unit is 1ns and precision is at 1ps.
// Declare the timescale where time_unit is 1ns
// and time_precision is 1ps
`timescale 1ns/1ps
// NOTE: Testbench is the same as in previous example
module tb;
// To understand the effect of timescale, let us
// drive a signal with some values after some delay
reg val;
initial begin
// Initialize the signal to 0 at time 0 units
val <= 0;
// Advance by 1 time unit, display a message and toggle val
#1 $display ("T=%0t At time #1", $realtime);
val <= 1;
// Advance by 0.49 time unit and toggle val
#0.49 $display ("T=%0t At time #0.49", $realtime);
val <= 0;
// Advance by 0.50 time unit and toggle val
#0.50 $display ("T=%0t At time #0.50", $realtime);
val <= 1;
// Advance by 0.51 time unit and toggle val
#0.51 $display ("T=%0t At time #0.51", $realtime);
val <= 0;
// Let simulation run for another 5 time units and exit
#5 $display ("T=%0t End of simulation", $realtime);
end
endmodule
See that the time units scaled to match the new precision value of 1ps. Also note that time is represented in the smallest resolution which in this case is picoseconds.
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.
