FPGA

Verilog Timescale Directive

By CourseTron Team ·  3 min read ·  Updated Oct 2026 💬 𝕏 in f
Table of Contents
    ? Print / Save as PDF

    In short: The `timescale / directive tells the simulator what one delay number means (the unit) and how finely it rounds that delay (the precision), so a wrong or missing timescale silently changes when your signals move.

    Why simulation needs a timescale at all

    Verilog delays such as #5 are plain numbers. They carry no physical meaning until the simulator is told whether 5 means 5 nanoseconds, 5 picoseconds or 5 microseconds. The `timescale compiler directive supplies that meaning. Its syntax is `timescale time_unit / time_precision, for example `timescale 1ns/1ps.

    The first number is the time unit: the length that a delay value of 1 represents inside every module that follows the directive. The second is the time precision: the smallest step to which the simulator rounds delays written in that module. Both must be a power of ten (1, 10 or 100) combined with s, ms, us, ns, ps or fs, and the precision can never be coarser than the unit. `timescale 1ns/10ns is illegal; `timescale 10ns/1ns is fine.

    Key fact: The directive is not a module property you declare once. It is a compiler directive that stays in force for every file compiled after it, until another `timescale or `resetall replaces it.

    Unit versus precision, with real numbers

    Take a module compiled with `timescale 1ns/1ps. A statement #2.5678 a = 1; is first scaled by the unit to 2.5678 ns, then rounded to the precision, giving 2.568 ns. The simulator never schedules the event at 2.5678 ns because it cannot represent anything finer than 1 ps in that module.

    Now change the directive to `timescale 10ns/1ns and write #1.54. One unit is 10 ns, so the delay is 15.4 ns, which rounds to 15 ns. The fractional part you typed is mostly thrown away, and that is exactly the kind of surprise that makes a testbench behave differently from what the author expected.

    `timescale 1ns/1ps : unit sets the scale, precision sets the grid 0 ns 1 ns (unit) 2 ns finer grid = precision (1 ps steps, thinned out here) #1.2345 becomes 1.234 ns after rounding to 1 ps orange dot = the time the event is really scheduled CourseTron · coursetron.com
    The unit decides how long "1" is; the precision decides how closely a fractional delay is rounded.

    The simulator's global time resolution

    A simulator keeps one master clock for the whole design. Its tick is the smallest precision found in any compiled module. If one block is compiled at 1ns/1ps and another at 10ns/1ns, the global tick is 1 ps. Every delay is converted to integer multiples of that tick before it enters the event queue.

    This has a cost. A single stray `timescale 1ns/1fs in a vendor model forces the entire run to femtosecond resolution, which inflates simulation time and memory for large netlists. Gate-level teams working with Synopsys VCS, Cadence Xcelium or Siemens Questa routinely audit precision for this reason; 1 ps is the usual compromise for SDF back-annotated runs because standard-cell delays are quoted to picosecond accuracy.

    Key fact: Precision does not change how fast a module runs, but the finest precision anywhere in the design sets the tick for everybody.

    Mixed timescales: the classic bug

    Suppose a clock generator is compiled with `timescale 1ns/1ps and says #5 clk = ~clk;. A DUT file compiled earlier has `timescale 10ns/1ns and contains #5 q <= d;. The clock toggles every 5 ns, while the DUT delay is 50 ns. The design looks logically correct, yet the output arrives ten clock edges late. Nothing errors out; the waveform is simply wrong.

    The same "#5" in two files tb.v `timescale 1ns/1ps #5 clk = ~clk; 5 x 1 ns = 5 ns dut.v `timescale 10ns/1ns #5 q <= d; 5 x 10 ns = 50 ns Global tick = 1 ps (finest precision in design) 5000 ticks vs 50000 ticks for the "same" #5 CourseTron · coursetron.com
    Identical source text, a tenfold difference in simulated time, because each file carries its own scale.

    Watching time advance

    The animation below shows an event marker walking along a 1 ns/1 ps axis. It does not jump continuously; it lands only on the precision grid, which is how every simulator schedules real events.

    Simulation time stepping on the precision grid 0 1 ns 2 ns 3 ns 4 ns orange marker = current simulation time, pausing at each event CourseTron · coursetron.com
    Animated: simulation time advances only to scheduled event times, never in between.

    Reading time inside the testbench

    $time returns an integer in the time unit of the module that calls it, rounded to the nearest whole unit. In a 10ns/1ns module, an event at 15 ns shows as 2 (15 / 10 = 1.5 rounds up). $realtime returns a real number in the same unit, so it prints 1.5. Use $realtime whenever you work with sub-unit delays, and format output with $timeformat so logs are readable. $printtimescale prints the scale of the calling module and is a quick sanity check, especially when you are unsure which file wins. Pair these with the usual print and finish tasks when you instrument a testbench.

    ItemMeaningExample result
    `timescale 1ns/1psUnit 1 ns, rounding step 1 ps#2.5678 becomes 2.568 ns
    `timescale 10ns/1nsUnit 10 ns, rounding step 1 ns#1.54 becomes 15 ns
    $timeInteger, in caller's unit15 ns in a 10 ns unit gives 2
    $realtimeReal, in caller's unit15 ns in a 10 ns unit gives 1.5

    Best practices that avoid the usual traps

    • Put one `timescale at the top of every file, RTL and testbench alike. Relying on compile order is fragile: the same file behaves differently depending on which file precedes it. If you want a deeper walkthrough of the syntax, see our timescale directive in Verilog guide and the companion Verilog timescale note.
    • Use a single project-wide scale, commonly 1ns/1ps, via a shared include file.
    • Know your tool's default. A file with no directive inherits whatever came before it, or a tool default that is implementation specific and often 1ns/1ns. Tools expose overrides such as -timescale=1ns/1ps in VCS and Xcelium, and a similar option in Questa and Vivado Simulator. Use them only to fix legacy code, not as a habit.
    • Use `resetall carefully at the end of library files so their scale does not leak into the next file.
    • In SystemVerilog prefer the timeunit and timeprecision declarations inside modules and packages; they bind to the scope and remove the compile-order problem.
    • Remember delays on nonblocking assignments follow the same scaling; see blocking vs non-blocking assignments for how those delays interact with the scheduler.

    Key fact: Synthesis ignores `timescale and all # delays. It only affects simulation, which is why a design can pass synthesis and still fail a timing-sensitive testbench.

    Interview angles

    Interviewers like three questions. First, what does #1.55 do under `timescale 1ns/100ps? The answer is 1.6 ns after rounding to the 100 ps step. Second, why does a testbench in a different timescale change DUT behaviour? Because every file scales its own delays and the global tick follows the finest precision. Third, how do you choose a precision for gate-level simulation? Match the SDF timing granularity, usually 1 ps, and avoid femtosecond unless a model demands it. You can practise all of these on real tools in the structured CourseTron courses, and teams that want hands-on training can also look at ChipXpert's VLSI training programs.

    Ready to go deeper? Join the CourseTron Verilog and FPGA courses and simulate every example in this article yourself, with guided labs and interview practice.

    Frequently asked questions

    What is the default timescale if I do not write one?

    The standard leaves it implementation defined. Many simulators fall back to 1ns/1ns or inherit the previous file's directive, so you should always state it explicitly.

    Can precision be larger than the unit?

    No. The precision must be equal to or finer than the unit. `timescale 1ns/1ps is valid; `timescale 1ps/1ns is an error.

    Does timescale affect synthesis or FPGA hardware?

    No. Synthesis tools ignore the directive and the delays, so real timing comes from constraints and place and route, not from the simulation scale.

    Why do my waveforms show times that do not match my delays?

    Usually the module that owns the delay is compiled under a different timescale than you assumed, or a fractional delay was rounded to the precision. Check with $printtimescale.

    Advertisement