Poll

Do you like the discussion forum ?

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.

Simulation 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.

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.

timescale 1ns/1ns

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.

Simulation 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.

Note that the base unit in waveform is in tens of nanoseconds with a precision of 1ns.

timescale 10ns/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.

Simulation 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.

timescale 1ns/1ps

Click to try this example in a simulator!   

You may also like:

You consent to our cookies if you continue to use our website. To know more about cookies, see our privacy policy. I accept cookies from this site.

Agree