top of page

7.3. The  `timescale Directive: Simulation Time Control

What is  `timescale?

The  `timescale directive specifies the time unit and time precision for delay values in simulation. It controls how the simulator interprets delays like #10 or #5.5.

`timescale time_unit / time_precision

​

Format:

​

  • time_unit: Base unit for delays (1s, 1ms, 1us, 1ns, 1ps, 1fs)

  • time_precision: Smallest resolvable time (must be ≤ time_unit)

​

Valid time units: 1s, 10s, 100s, 1ms, 10ms, 100ms, 1us, 10us, 100us, 1ns, 10ns, 100ns, 1ps, 10ps, 100ps, 1fs, 10fs, 100fs

7.3.1. Understanding Time Unit and Precision

​

Example 1: Basic Timescale

 Verilog

`timescale 1ns / 1ps

module clock_gen;

    reg clk;

    initial begin

        clk = 0;

        forever #5 clk = ~clk;  // 5 * 1ns = 5ns, toggles every 5ns

                                // Period = 10ns, Frequency = 100MHz

    end

endmodule

Example 2: Effect of Different Timescales

 Verilog

// Testbench 1

`timescale 1ns / 1ns

module tb1;

    reg clk;

    initial begin

        clk = 0;

        #10 clk = 1;  // 10ns delay

        #5.7 clk = 0; // 5.7ns rounds to 6ns (precision is 1ns)

    end

endmodule

 

// Testbench 2

`timescale 1ns / 1ps

module tb2;

    reg clk;

    initial begin

        clk = 0;

        #10 clk = 1;   // 10ns delay

        #5.7 clk = 0;  // 5.7ns (can represent exactly)

    end

endmodule

 

// Testbench 3

`timescale 1us / 1ns

module tb3;

    reg clk;

    initial begin

        clk = 0;

        #10 clk = 1;   // 10us delay (much longer!)

        #5.7 clk = 0;  // 5.7us

    end

endmodule

7.3.2. Practical Applications

​

Application 1: Clock Generation with Precise Timing

 Verilog

`timescale 1ns / 1ps

module multi_clock_system;

    // System clock: 100 MHz (10ns period)

    reg sys_clk;

    parameter SYS_CLK_PERIOD = 10.0;  // 10ns

    initial begin

        sys_clk = 0;

        forever #(SYS_CLK_PERIOD/2) sys_clk = ~sys_clk;

    end

    // DDR clock: 800 MHz (1.25ns period)

    reg ddr_clk;

    parameter DDR_CLK_PERIOD = 1.25;  // 1.25ns

    initial begin

        ddr_clk = 0;

        forever #(DDR_CLK_PERIOD/2) ddr_clk = ~ddr_clk;

    end 

    // USB clock: 48 MHz (20.833ns period)

    reg usb_clk;

    parameter USB_CLK_PERIOD = 20.833;  // 20.833ns

    initial begin

        usb_clk = 0;

        forever #(USB_CLK_PERIOD/2) usb_clk = ~usb_clk;

    end 

    // UART clock: 1.8432 MHz (542.535ns period)

    reg uart_clk;

    parameter UART_CLK_PERIOD = 542.535;

    initial begin

        uart_clk = 0;

        forever #(UART_CLK_PERIOD/2) uart_clk = ~uart_clk;

    end

endmodule

Application 2: Setup and Hold Time Verification

 Verilog

`timescale 1ns / 1ps

module timing_check_example;

    reg clk;

    reg data;

    reg [7:0] capture; 

    // Clock: 100 MHz

    initial begin

        clk = 0;

        forever #5 clk = ~clk;

    end 

    // Timing parameters from datasheet

    parameter T_SETUP = 2.5;   // 2.5ns setup time required

    parameter T_HOLD = 1.5;    // 1.5ns hold time required 

    // Data changes with proper timing

    initial begin

        data = 0; 

        // Wait for clock edge

        @(posedge clk); 

        // Change data with setup time margin

        #(10 - T_SETUP - 0.5);  // 0.5ns margin before setup requirement

        data = 1; 

        // Hold data after clock edge

        @(posedge clk);

        #(T_HOLD + 0.3);  // 0.3ns margin after hold requirement

        data = 0;

    end 

    // Capture data at clock edge

    always @(posedge clk) begin

        capture <= {capture[6:0], data};

    end 

    // Timing checks using $setup and $hold

    always @(posedge clk) begin

        $setup(data, posedge clk, T_SETUP);

        $hold(posedge clk, data, T_HOLD);

    end

endmodule

Application 3: Protocol Timing Simulation

 Verilog

`timescale 1ns / 1ps

module i2c_timing_tb;

    reg scl, sda;

    // I2C Standard Mode timing parameters (from spec)

    parameter real T_LOW = 4700;      // SCL low period (4.7us)

    parameter real T_HIGH = 4000;     // SCL high period (4.0us)

    parameter real T_SU_STA = 4700;   // START condition setup (4.7us)

    parameter real T_HD_STA = 4000;   // START condition hold (4.0us)

    parameter real T_SU_STO = 4000;   // STOP condition setup (4.0us)

    parameter real T_BUF = 4700;      // Bus free time (4.7us)

    parameter real T_SU_DAT = 250;    // Data setup time (250ns)

    parameter real T_HD_DAT = 0;      // Data hold time (0ns min)

    // I2C START condition

    task i2c_start;

        begin

            sda = 1;

            scl = 1;

            #T_SU_STA;

            sda = 0;  // SDA falls while SCL high

            #T_HD_STA;

            scl = 0;

        end

    endtask

    // I2C STOP condition

    task i2c_stop;

        begin

            sda = 0;

            #T_LOW;

            scl = 1;

            #T_SU_STO;

            sda = 1;  // SDA rises while SCL high

            #T_BUF;

        end

    endtask

    // I2C write bit

    task i2c_write_bit(input bit_val);

        begin

            sda = bit_val;

            #T_SU_DAT;  // Setup data before SCL rises

            scl = 1;

            #T_HIGH;

            scl = 0;

            #T_HD_DAT;  // Hold data after SCL falls

        end

    endtask

    // Test sequence

    initial begin

        scl = 1;

        sda = 1;

        #1000;

        // Send START

        i2c_start();

        // Write address byte (0x50, write mode)

        i2c_write_bit(0);  // bit 7

        i2c_write_bit(1);  // bit 6

        i2c_write_bit(0);  // bit 5

        i2c_write_bit(1);  // bit 4

        i2c_write_bit(0);  // bit 3

        i2c_write_bit(0);  // bit 2

        i2c_write_bit(0);  // bit 1

        i2c_write_bit(0);  // bit 0 (write)

        // Send STOP

        i2c_stop();

        $finish;

    end

endmodule

Application 4: Gate-Level Timing Annotation

 Verilog

`timescale 1ns / 1ps

module gate_level_example (

    input wire a,

    input wire b,

    output wire y

);

    wire and_out;

    // Gate delays from technology library

    and #(0.15, 0.18) u_and (and_out, a, b);

    // Rise delay: 0.15ns, Fall delay: 0.18ns

    not #(0.12, 0.10) u_not (y, and_out);

    // Rise delay: 0.12ns, Fall delay: 0.10ns

endmodule

module gate_timing_tb;

    reg a, b;

    wire y;

    gate_level_example dut (

        .a(a),

        .b(b),

        .y(y)

    );

    initial begin

        $dumpfile("timing.vcd");

        $dumpvars(0, gate_timing_tb);

        // Test vectors

        a = 0; b = 0; #10;

        a = 0; b = 1; #10;

        a = 1; b = 0; #10;

        a = 1; b = 1; #10;  // Observe propagation delays 

        $finish;

    end

endmodule

7.3.3. Timescale Scope and Rules

​

Rule 1: Timescale is File-Scoped

 Verilog

// File: module_a.v

`timescale 1ns / 1ps

module module_a;

    initial #10 $display("Module A: 10ns");

endmodule

// File: module_b.v

`timescale 1us / 1ns

module module_b;

    initial #10 $display("Module B: 10us");  // Different timescale!

endmodule

// File: top.v

`timescale 1ns / 1ps

module top;

    module_a inst_a();  // Uses its own 1ns timescale

    module_b inst_b();  // Uses its own 1us timescale

    initial #10 $display("Top: 10ns");  // Uses top's 1ns timescale

endmodule

Rule 2: Simulator Uses Most Precise Timescale

​

When multiple modules have different timescales, the simulator uses the finest precision:

 Verilog

// Module 1: 1ns/1ps

// Module 2: 1ns/100ps

// Module 3: 1ns/1ns

// Simulator will use 1ps precision globally

Rule 3: Always Specify Timescale

 Verilog

// Bad - no timescale specified

module no_timescale;

    initial #10 $display("What unit is this?");  // Undefined!

endmodule

// Good - timescale always specified

`timescale 1ns / 1ps

module with_timescale;

    initial #10 $display("This is 10ns");  // Clear!

endmodule

7.3.4. Choosing the Right Timescale

​

7.3.4.1. For Digital RTL Design (ASIC/FPGA)

 Verilog

`timescale 1ns / 1ps

// Why?

// - 1ns unit matches typical clock periods (GHz range)

// - 1ps precision captures setup/hold times

// - Standard for most digital designs

7.3.4.2. For High-Speed Interfaces (SerDes, DDR, PCIe)

 Verilog

`timescale 1ps / 1fs

// Why?

// - Multi-GHz clocks need picosecond accuracy

// - Jitter measurements require femtosecond precision

// - Critical timing margins in picoseconds

7.3.4.3. For Slow Peripherals (UART, I2C, SPI)

 Verilog

`timescale 1us / 1ns

// Why?

// - Clock periods in microseconds

// - No need for sub-nanosecond precision

// - Faster simulation (fewer time steps)

7.3.4.4. For Mixed-Signal Simulation

 Verilog

`timescale 1ns / 1ps

// Why?

// - Compromise between digital (ns) and analog (ps) domains

// - Compatible with most EDA tools

7.3.5. Best Practices for  `timescale

​

7.3.5.1. Always Put Timescale at Top of File

 Verilog

// Good practice

`timescale 1ns / 1ps

 

`include "definitions.vh"

 

module my_module (...);

    // Module content

endmodule

7.3.5.2. Be Consistent Across Project

 Verilog

// Create a standard timescale header

// File: project_timescale.vh

`timescale 1ns / 1ps

 

// Include in all files

// File: module1.v

`include "project_timescale.vh"

module module1 (...);

 

// File: module2.v

`include "project_timescale.vh"

module module2 (...);

7.3.5.3. Document Timescale Choice

 Verilog

/**

 * Timescale: 1ns / 1ps

 * Rationale: 

 *   - System clock: 100MHz (10ns period)

 *   - Setup time: 2.5ns (requires ns resolution)

 *   - Jitter spec: ±50ps (requires ps precision)

 */

`timescale 1ns / 1ps

 

module timing_critical_block (...);

7.3.5.4. Use Realistic Delays

 Verilog

`timescale 1ns / 1ps

 

module realistic_delays;

    reg clk;

    

    // Good - realistic for 100MHz clock

    initial begin

        clk = 0;

        forever #5 clk = ~clk;  // 10ns period

    end

    

    // Avoid - unrealistic for digital design

    initial begin

        #0.001;  // 1fs delay - too small for RTL

    end

endmodule

7.3.6. Common Recommendations with  `timescale

Case 1: Forgetting to Specify Timescale

 Verilog

// No timescale directive!

module broken_module;

    initial #10 $display("Time: %0t", $time);

    // Behavior is tool-dependent!

endmodule

Solution: Always specify timescale, or use tool default carefully.

Case 2: Inconsistent Timescales Causing Confusion

 Verilog

// File A: Uses microseconds

`timescale 1us / 1ns

module slow_module;

    initial #10 $display("10us delay");

endmodule

 

// File B: Uses nanoseconds

`timescale 1ns / 1ps

module fast_module;

    initial #10 $display("10ns delay");  // 1000x faster!

endmodule

Solution: Standardize timescale across project.

Case 3: Precision Too Coarse

 Verilog

`timescale 1ns / 1ns

 

module precision_test;

    reg data;

    

    initial begin

        data = 0;

        #5.5 data = 1;  // Rounds to 6ns!

        #3.2 data = 0;  // Rounds to 3ns!

    end

    

    // Expected: data = 1 at 5.5ns

    // Actual:   data = 1 at 6ns

endmodule

Solution: Use finer precision (1ps or 1fs).

define

Conditional Compilation

© Copyright 2025 VLSI Mentor. All Rights Reserved.©

Connect with us

  • Instagram
  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
bottom of page