Skip to content

Verilog · Chapter 7.3 · Compiler Directives

`timescale in Verilog — Simulator Time Unit and Precision

The timescale directive declares the unit and precision of simulation time for every module that follows it. It is the contract that turns a numeric delay of five into a real duration, which might mean five nanoseconds in one project and five microseconds in another. Without a timescale the simulator behaves in a way defined by the tool and quietly varies between vendors. With one, every delay, every time print, and every setup and hold check has a well-defined meaning. The directive looks trivial, since a full line is only half a line of code, but it carries several subtleties that every working engineer hits. This lesson covers the legal unit set, the rounding rule, what happens when modules declare different timescales, how precision sets the global simulator step, and how to choose the right values for different kinds of design.

Foundation16 min readVerilogtimescaleSimulationPreprocessor

Chapter 7 · Section 7.3 · Compiler Directives

1. The Engineering Problem

Two engineers on the same project write testbenches for the same DUT. Engineer A writes:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module tb_a;
    reg clk;
    initial begin
        clk = 0;
        forever #5 clk = ~clk;
    end
endmodule

Engineer B writes essentially the same thing in a different file. Both run in the same simulation. Engineer A's clock toggles at 100 MHz (every 5 ns); Engineer B's clock toggles at 100 kHz (every 5 µs). The simulation reports $time values that don't agree between the two modules. Setup/hold checks flag spurious violations. Coverage closure drifts.

The root cause: neither file specified a timescale. Without `timescale, the simulator falls back to a tool default — and the two files happened to import headers that set the default differently. The bug is not in the design; it is in the measurement contract.

The fix is one line per file:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale 1ns / 1ps
 
module tb_a;
    reg clk;
    initial begin
        clk = 0;
        forever #5 clk = ~clk;  // 5 × 1ns = 5ns → 100 MHz
    end
endmodule

After the directive, every #N in this file means N × 1 ns and every time check resolves to 1 ps. The simulator's interpretation is no longer ambient state — it is part of the source code. This page is the deep drill on that contract: what the directive declares, what units are legal, how precision rounds, what happens when files disagree, and how to pick the right timescale for ASIC RTL, high-speed interfaces, slow peripherals, and mixed-signal verification.

2. Anatomy of `timescale

The full syntax is one line.

2.1 Syntax — unit and precision

timescale-syntax.v — unit / precision
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale <time_unit> / <time_precision>
 
// Examples
`timescale 1ns / 1ps
`timescale 10ps / 1ps
`timescale 1us / 1ns
`timescale 1ps / 100fs

The directive takes two arguments separated by /.

  • time_unit — the base unit that every numeric delay is multiplied by. #5 under `timescale 1ns / 1ps becomes 5 × 1ns = 5ns. Under `timescale 1us / 1ns the same #5 becomes 5us — a thousand times longer.
  • time_precision — the smallest resolvable time step. Any delay finer than precision is rounded to the nearest precision boundary. Under `timescale 1ns / 1ns, a #5.5 becomes #6; under `timescale 1ns / 1ps, the same #5.5 is preserved exactly.

The directive applies to every module that follows it in the source file, until either end-of-file or another `timescale overrides it.

2.2 Valid units

The legal set is fixed by IEEE 1364-2005. Each unit is one of the magnitudes 1 / 10 / 100 paired with one of seven SI scales.

legal-timescale-units.txt
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
1s   10s   100s        ← seconds
1ms  10ms  100ms       ← milliseconds  (10⁻³ s)
1us  10us  100us       ← microseconds  (10⁻⁶ s)
1ns  10ns  100ns       ← nanoseconds   (10⁻⁹ s)
1ps  10ps  100ps       ← picoseconds   (10⁻¹² s)
1fs  10fs  100fs       ← femtoseconds  (10⁻¹⁵ s)

Anything outside this set (e.g., 2ns, 500ps, 1as) is a syntax error. The precision must be ≤ the unit`timescale 1ns / 1us is illegal because precision (1µs) is coarser than the unit (1ns).

3. Mental Model

4. The Scaling Rule — Numeric Delays Become Wall-Clock Time

Every #N in the source is multiplied by the active time_unit.

timescale-scaling.v — same code, different timescales
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Same source statement: #10 $display(...);
// Three different interpretations depending on timescale.
 
`timescale 1ns / 1ps      // case 1
module fast;
    initial #10 $display("Time = %0t", $time);
    // Prints at simulated time = 10 × 1ns = 10ns
endmodule
 
`timescale 1us / 1ns      // case 2
module medium;
    initial #10 $display("Time = %0t", $time);
    // Prints at simulated time = 10 × 1us = 10us
endmodule
 
`timescale 1ms / 1us      // case 3
module slow;
    initial #10 $display("Time = %0t", $time);
    // Prints at simulated time = 10 × 1ms = 10ms
endmodule

Same #10, three different wall-clock durations — 10 ns, 10 µs, 10 ms. The number is unitless until the timescale supplies the conversion. This is the single most common source of cross-file confusion: a #10 looks identical in every file, but means something different in each.

The same scaling applies to all delay forms — #5, #(PERIOD/2), edge-aligned @(posedge clk) waits (relative to the clock period), $setup / $hold checks, repeat (N) @(posedge clk). Every numeric duration in the source rides on the active timescale.

5. The Precision Rule — Rounding to the Time Step

time_precision is the smallest unit the simulator can represent. Delays finer than precision are rounded to the nearest precision boundary.

timescale-precision.v — rounding behaviour
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale 1ns / 1ns       // precision = 1ns
module coarse;
    initial begin
        #5.5 $display("t = %0t", $time);  // Rounds to #6 → t = 6
        #3.2 $display("t = %0t", $time);  // Rounds to #3 → t = 9
    end
endmodule
 
`timescale 1ns / 1ps       // precision = 1ps
module fine;
    initial begin
        #5.5 $display("t = %0t", $time);  // 5.5ns = 5500ps exact → t = 5500
        #3.2 $display("t = %0t", $time);  // 3.2ns = 3200ps exact → t = 8700
    end
endmodule

Two consequences:

  • Sub-precision delays disappear. `timescale 1ns / 1ns with #0.001 rounds to zero — the delay is silently dropped.
  • Cumulative drift. If every step rounds slightly, hundreds of consecutive delays can accumulate microseconds of error in a long simulation. Critical for timing-sensitive verification (jitter measurements, SerDes equalisation simulations).

The rule of thumb: choose precision fine enough to represent every meaningful delay in the design. For a 100 MHz design with 50 ps jitter tolerance, precision should be at least 10 ps — preferably 1 ps to give margin.

6. Multi-Module Propagation — The Global Precision Rule

When a simulation contains multiple modules with different `timescale directives, two rules apply.

6.1 Each module uses its own unit and precision

timescale-multi-module.v — per-module timescales
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale 1us / 1ns
module slow_logger;
    initial #10 $display("slow_logger fires at %0t", $time);
    // Uses 1us — fires at 10us = 10_000 ns of global time
endmodule
 
`timescale 1ns / 1ps
module fast_top;
    slow_logger u_log();
    initial #10 $display("fast_top fires at %0t", $time);
    // Uses 1ns — fires at 10ns
endmodule

fast_top and slow_logger interpret their own #10 against their own timescales. They co-exist in one simulation but speak different units locally.

6.2 The simulator uses the finest precision globally

multi-precision-rule.txt — global step is the finest
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
Module 1: `timescale 1ns / 1ps
Module 2: `timescale 1ns / 100ps
Module 3: `timescale 1ns / 1ns
 
Finest precision among the three:  1ps
→ The simulator's internal time step is 1ps.
→ Every module's events are timestamped on the 1ps grid.
→ Module 3's `#5.5` (which it interprets as 5ns + 500ps in 1ns precision)
  is now rounded against the 1ns grid before, then placed on the 1ps grid.
  Net result: Module 3 still rounds to ns boundaries, but the simulator
  internally tracks at 1ps.

Two practical implications:

  • A single fine-precision module expands the global timeline of every other module. Simulation memory footprint and runtime are proportional to events-per-precision-step, so dropping one module's precision from 1 ns to 1 fs can slow the whole simulation by 1000× without obvious cause.
  • The global precision is unobservable at code level — there is no $timeprecision print that says "the simulator is running at 1 ps." Hunt it down via tool-specific flags (+timescale=…, -timescale, vendor reports).

The discipline: standardise the timescale across a project (every file uses the same `timescale 1ns / 1ps) so the global precision is predictable.

7. `resetall — Clearing the Active Timescale

The companion directive `resetall clears all compiler-directive state back to defaults, including the active `timescale.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale 1ns / 1ps
module a; initial #10 $display("ns"); endmodule
 
`resetall              // timescale (and other directives) reset
 
`timescale 1us / 1ns
module b; initial #10 $display("us"); endmodule

In practice `resetall is rare — most projects standardise on one timescale and never reset. The directive is mostly seen in IP libraries that want a clean slate after their internal includes.

8. Visual Explanation

Three figures cover the timescale model.

8.1 Visual A — unit and precision

The conceptual picture: `timescale declares two numbers, and they map numeric delays in source to simulated time.

`timescale unit and precision — source-to-time mapping

data flow
`timescale unit and precision — source-to-time mapping#5 in sourceunitless numeric× time_unit = 1nsscale to wall-clockround to time_precision = 1psround totime_precision =…snap to time-gridevent scheduledat t = 5nssimulator queues
Two-stage conversion: time_unit scales the unitless numeric to wall-clock; time_precision rounds to the simulator's internal grid. By the time the event lands on the queue, both transforms have been applied.

8.2 Visual B — precision rounding

What happens when a fractional delay doesn't land on a precision boundary.

Precision rounding under different timescales#5.5user-written delay1ns / 1nsrounds to #61ns / 1psexact 5500pst = 6ns0.5ns losst = 5500psexact12
Precision rounding. Under `timescale 1ns / 1ns, the fractional delay #5.5 rounds to 6 (nearest 1ns boundary). Under `timescale 1ns / 1ps, the same #5.5 is preserved exactly as 5500ps. Choosing coarse precision silently quantises fine delays — sub-precision events round to zero or merge.

8.3 Visual C — multi-module precision merge

Same simulation, different timescales — the global step is the finest precision.

Global precision merge across modulesModule 1 1ns / 1psfine precisionModule 2 1ns / 100psmedium precisionModule 3 1ns / 1nscoarse precisionSimulator global step= 1psfinest wins12
Multi-module precision merge. Three modules declare timescales of 1ns/1ps, 1ns/100ps, and 1ns/1ns. The simulator picks the finest precision (1ps) for the global event queue. Every module's events get re-quantised against the 1ps grid — fast-precision modules pay nothing; coarse-precision modules see no benefit but the simulator still tracks at 1ps internally.

9. Choosing the Right Timescale — A Per-Domain Rule

The right timescale depends on the clock frequencies, timing margins, and verification needs of the domain. Four canonical pairings.

DomainRecommendedWhy
Digital RTL (ASIC / FPGA)1ns / 1psMatches sub-GHz clock periods; precision captures setup / hold
High-speed interfaces (SerDes, DDR, PCIe)1ps / 1fsMulti-GHz clocks need ps accuracy; jitter measurement needs fs
Slow peripherals (UART, I²C, SPI)1us / 1nsµs-scale clocks; fewer time steps → faster simulation
Mixed-signal1ns / 1psCompromise between digital (ns) and analog (ps) domains
System-level / RTOS1ms / 1usms-scale software loops; faster sim for long runs

Three meta-rules behind the table:

  • Pick the unit close to the clock period. A 100 MHz design (10 ns period) wants 1ns unit so delays read naturally (#5 for half-cycle); same design at 1 GHz (1 ns period) wants 100ps or 10ps unit.
  • Pick precision fine enough for the tightest timing margin. A 50 ps setup/hold check needs at least 10ps precision; a 1 ps jitter measurement needs 100fs precision.
  • Pick precision coarse enough to keep simulation fast. Each 100× drop in precision is roughly a 100× drop in simulation throughput for time-dominated benchmarks. Don't go finer than needed.

10. Industry Use Cases

Three patterns where `timescale shows up in production.

10.1 Project-standard header

Most teams standardise on one timescale and put it in a header included by every file:

project_timescale.vh — single-source convention
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// VLSI Mentor reference convention
`timescale 1ns / 1ps

Every file leads with `include "project_timescale.vh". Cross-file precision is consistent; the global precision is predictable. The 7.1 `include page covers the include mechanism this rides on.

10.2 Datasheet-driven timing parameters

Real timing parameters (setup, hold, propagation, recovery) come from the datasheet in absolute time. A testbench encodes them as parameter real and asserts them against actual events. The timescale is the contract that translates the parameters into events:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale 1ns / 1ps
 
module timing_check;
    parameter real T_SETUP = 2.5;   // 2.5 ns — from datasheet
    parameter real T_HOLD  = 1.5;   // 1.5 ns
 
    reg clk, data;
    initial begin
        @(posedge clk);
        #(10 - T_SETUP - 0.5);  // 0.5 ns margin
        data = 1;
        @(posedge clk);
        #(T_HOLD + 0.3);        // 0.3 ns margin
        data = 0;
    end
endmodule

The 2.5 ns figure from the datasheet maps directly to the #(...) expressions because the timescale unit is 1ns. Precision of 1ps gives 1000× more resolution than the timing margin — comfortable headroom.

10.3 Protocol timing modelling

Protocol specs are written in absolute time (I²C: 4.7 µs SCL-low). To model them in a testbench, the timescale needs to be fine enough to express the spec values exactly, coarse enough that simulation doesn't crawl:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale 1ns / 1ps
 
module i2c_tb;
    parameter real T_LOW   = 4700;   // 4.7 µs in ns
    parameter real T_HIGH  = 4000;   // 4.0 µs in ns
    parameter real T_SU_DAT = 250;   // 250 ns
 
    // …drive scl / sda using the parameters
endmodule

1ns / 1ps works well — protocol values map naturally to nanosecond integers, and 1 ps precision is far below any I²C timing margin.

11. Common Mistakes

Six pitfalls that catch every working engineer at least once.

11.1 No `timescale at all

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// No directive — tool-defined default
module loose;
    initial #10 $display("Time = %0t", $time);
    // Vendor A: 10ns. Vendor B: 10us. Result varies between tools.
endmodule

The lazy fix is to rely on the tool default; the disciplined fix is to put `timescale 1ns / 1ps (or whatever the project standard is) at the top of every file or include it from a shared header.

11.2 Inconsistent timescales across project files

When File A uses 1us / 1ns and File B uses 1ns / 1ps, the same #10 means 10 µs in A and 10 ns in B. Setup checks fail with mysterious "looks-right-to-me" violations. Standardise via the project-header pattern in §10.1.

11.3 Precision too coarse for the design

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale 1ns / 1ns
module example;
    initial begin
        #5.5 $display(...);  // Rounds to 6 — 0.5ns silently lost
        #0.001 ...;           // Rounds to 0 — delay dropped entirely
    end
endmodule

Any time the design has sub-unit timing margins (setup/hold in ps, jitter in ps, analog mixed-signal), bump precision down. The cost is simulation speed; the benefit is correctness.

11.4 Precision too fine for the workload

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
`timescale 1ns / 1fs
module slow_runner;
    // No fs-scale events anywhere — but every event in the project
    // is now placed on a 1fs grid. Simulation crawls.
endmodule

The simulator's global precision is the finest among all modules. One file with 1fs precision silently slows the entire simulation by 1000× compared to a 1ps-only project. Don't go finer than the tightest design margin.

11.5 Using the wrong unit for the domain

UART simulations under 1ps / 1fs waste time on events that don't matter. ASIC RTL under 1ms / 1us can't resolve setup/hold. The §9 table is the working rule: match the unit to the clock period and the precision to the tightest timing margin.

11.6 Forgetting `timescale lifetime is per-file

The directive's scope is from the line it appears on to the next `timescale or end-of-file — not just the next module. If two modules in the same file both need different timescales, write a second `timescale before the second module. In practice, prefer one timescale per file (or per project).

12. Debugging Lab

Three `timescale debug post-mortems

13. Coding Guidelines

Working teams converge on the same six rules.

  1. Always declare a `timescale — never rely on tool defaults; they vary between vendors and silently break portability.
  2. One project-wide standard timescale — pick 1ns / 1ps for ASIC, 1ps / 1fs for SerDes, 1us / 1ns for slow-peripheral testbenches; put it in a project_timescale.vh and `include it everywhere.
  3. Match the unit to the clock period — a 100 MHz design (10 ns) uses 1ns unit; a 1 GHz design uses 100ps or 10ps; an I²C controller uses 1us.
  4. Match precision to the tightest timing margin — setup/hold in ps → 1ps precision; jitter in fs → 1fs precision.
  5. Don't over-specify precision — every 10× drop in precision is roughly a 10× drop in simulation speed; finer than the tightest design margin wastes runtime.
  6. Document the rationale — leave a one-line comment above the `timescale directive explaining why those numbers (// 100MHz clock, 500ps setup margin → 1ns/1ps). Avoids the next engineer changing it without context.

14. Interview Q&A

15. Exercises

Three exercises that turn `timescale into reflex.

Exercise 1 — Predict the simulated time

For each combination, predict the simulated time when $display fires.

#DirectiveStatementPredicted $time
1`timescale 1ns / 1ps#10 $display(...);?
2`timescale 1us / 1ns#10 $display(...);?
3`timescale 1ns / 1ns#5.5 $display(...);?
4`timescale 1ns / 1ps#5.5 $display(...);?
5`timescale 1ms / 1us#100 $display(...);?
6`timescale 1ns / 1ns#0.4 $display(...);?

Hints. Apply the scaling rule (unit × N) then the precision rule (round to nearest precision boundary).

Exercise 2 — Pick the right timescale

For each scenario, recommend a `timescale directive.

#Scenario
1A 50 MHz FPGA design with 1 ns setup/hold checks
2A DDR4 SerDes lane at 3.2 Gbps with 5 ps jitter measurement
3An I²C-master testbench at Standard Mode (100 kHz SCL)
4A mixed-signal SAR ADC at 1 MSps with 100 ps clock jitter
5An RTOS scheduler simulation with 1 ms tick

Hints. Match the unit to the clock period and the precision to the tightest timing margin.

Exercise 3 — Debug the precision

In each snippet, identify whether the chosen precision is too coarse, too fine, or appropriate.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Snippet A
`timescale 1ns / 1ns
parameter real T_SETUP = 0.3;   // 300ps setup time
// ...
 
// Snippet B
`timescale 1ns / 1fs
// Simple 100MHz testbench with no sub-ns timing checks
// ...
 
// Snippet C
`timescale 1ns / 1ps
parameter real T_SETUP = 0.5;   // 500ps setup time
parameter real T_HOLD  = 0.2;   // 200ps hold time
// ...
 
// Snippet D
`timescale 1us / 1us
// UART testbench at 9600 baud; bit time ~104us
// ...

What to produce. For each, label "too coarse / too fine / appropriate" and justify in one sentence.

16. Summary

`timescale declares two numbers that define the simulator's measurement contract: time_unit (the multiplier that turns numeric delays into wall-clock time) and time_precision (the smallest time-step the simulator can represent). Without it, every numeric delay rides on a tool-defined default and is non-portable.

The scaling rule:

  • Every #N in source means N × time_unit.
  • Same #10 is 10 ns under 1ns / 1ps, 10 µs under 1us / 1ns, 10 ms under 1ms / 1us.
  • The unit applies to every delay form — #5, #(PERIOD/2), $setup, $hold, repeat (N) @(...).

The precision rule:

  • Any delay finer than precision is rounded to the nearest precision boundary.
  • #5.5 under 1ns / 1ns rounds to 6; same #5.5 under 1ns / 1ps is exact (5500 ps).
  • Sub-precision delays round to zero — silent bug source.

The multi-module rule:

  • Each module uses its own unit and precision for its own #N.
  • The simulator's global event step is the finest precision among all loaded modules.
  • One fine-precision IP silently slows the whole simulation.

The per-domain selection rule:

  • 1ns / 1ps — ASIC / FPGA RTL (the industry default).
  • 1ps / 1fs — SerDes / DDR / PCIe (multi-GHz clocks, jitter measurement).
  • 1us / 1ns — UART / I²C / SPI (slow peripherals, fast simulation).
  • 1ns / 1ps — mixed-signal (compromise between digital and analog domains).
  • 1ms / 1us — system-level / RTOS (long-running software loops).

The day-to-day discipline:

  • Every file leads with `timescale — or `include a project-standard header that does.
  • One project-standard timescale. Cross-file consistency makes global precision predictable.
  • Match unit to clock period, precision to tightest margin. Don't over-refine — every 10× precision drop costs ~10× simulation speed.
  • Document the rationale. One-line comment above the directive — saves the next engineer's debug session.

The next sub-page closes Chapter 7: 7.4 Conditional Compilation covers `ifdef / `ifndef / `elsif / `endif for build-target gating — synthesis vs simulation, fast vs slow models, debug vs release builds.

After Chapter 7 closes, Chapter 8 picks up with system tasks & functions$display, $monitor, $random, $readmemh — the simulation-infrastructure layer that the timescale ultimately serves.

  • `define — Chapter 7.2; macro mechanism for sharing the timescale via a project header.
  • `include — Chapter 7.1; the file-inclusion mechanism that propagates a project-standard timescale.
  • Compiler Directives — Chapter 7; the parent overview of the directive family.
  • Number Representation — Chapter 4.4; literal syntax for delay values like #5.5.