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.
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 the simulation.
Use the following timescale constructs to use different time units in the same design. The delay specifications in the design are not synthesizable and cannot be converted to hardware logic.
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
The first delay statement uses #1, making the simulator wait for the exactly 1-time unit, specified to be 1ns with a `timescale directive. The second delay statement uses 0.49, which is less than half a time unit.
However, the time precision is specified to be 1ns, and 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. After the execution, it gives the following output:
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.
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 the total time to 25ns.
NOTE: The base unit in the 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.
See that the time units scaled to match the new precision value of 1ps. And time is represented in the smallest resolution, which in this case is picoseconds.
Although Verilog modules are expected to have a timescale defined before the module, simulators may insert a default timescale.
The actual timescale that gets applied at any scope in a Verilog elaborated hierarchy can be printed using the system task $printtimescale, which accepts the scope as an argument.
NOTE: A timescale directive was not placed before this module. The simulator ended up applying a 1ns/1ns timescale value.
Standard Timescale Scope
By default, a timescale directive placed in a file is applied to all modules that follow the directive until the definition of another timescale directive.
In the above example, tb and alu end up with a timescale of 1ns/1ns while des get a timescale of 1ns/10ps because of the directive placement before the module definition of des.
Other files can be included in the current file using an `include directive, which is a pre-processor directive and makes the compiler place contents of the included file before compilation.
This is equivalent to simply pasting the entire contents of the other file in this main file.
See that results are precisely the same as in the previous example. alu gets a timescale of 1ns/1ps because it was the last directive that stayed valid until the compiler found alu definition insisted of placing it in a different file.
The des gets a timescale of 1ns/10ps because the directive was replaced before its definition.
Swapping Files can Change Timescale.
The order of inclusion of files plays an important role in the redefinition of timescale directives, which is evident in the example below.
See that the module alu now gets a timescale of 1ns/10ps.
This is one reason for having a timescale directive at the top of files so that all modules in that file assume the correct timescale irrespective of file inclusion.
However, this approach may make it difficult to compile with a different timescale precision without altering each file.
Many compilers and simulators also provide an option to override default timescale values, which will be applied to all modules.