From Physics to Numbers: The Art of Delay Modeling

In the previous module, you learned what gets characterized in Liberty files—delays, transition times, setup and hold constraints. Now we'll explore how this data is organized, stored, and used. The bridge between analog transistor behavior and digital timing analysis is built on delay models, and understanding these models is crucial for effective timing closure.

At first glance, delay tables might seem like simple spreadsheets of numbers. But behind these tables lies a sophisticated modeling approach that balances accuracy with computational efficiency. This module demystifies NLDM tables, explains why we use 2D lookups, and teaches you to read timing tables like a native speaker reads text.

The Challenge of Delay Modeling

Why Delay Modeling Is Difficult

The Analog Reality
Every digital gate is fundamentally an analog circuit:

  • Transistors have non-linear voltage-current relationships
  • Capacitors charge and discharge with exponential curves
  • Short-channel effects create complex device physics
  • Temperature, voltage, and process variations all interact

The Digital Necessity
Yet we need to analyze designs with:

  • Millions of gates
  • Billions of timing paths
  • Sub-picosecond accuracy requirements
  • Hour-long (not year-long) runtime targets

The solution? Precompute delays under many conditions, store them in tables, and use fast lookup and interpolation during analysis.

Historical Perspective: The Evolution of Delay Models

Linear Delay Model (Ancient History)

Delay = K1 + K2 × Load

Simple, fast, but horribly inaccurate for modern processes.

Piecewise Linear Models
Better, but still couldn't capture the real non-linear behavior of deep submicron transistors.

Non-Linear Delay Model (NLDM) - The Current Standard
Uses 2D lookup tables indexed by input transition and output load. Accurate enough for most digital designs, fast enough for modern design sizes.

Composite Current Source (CCS) - Advanced Alternative
Models output current waveforms directly. More accurate, especially for signal integrity, but requires more data and computation time. We'll focus on NLDM in this module.

NLDM: The Non-Linear Delay Model

Core Concept

NLDM recognizes that cell delay depends primarily on two factors:

  1. Input transition time (how fast the input changes)
  2. Output load capacitance (how much the output must drive)

By characterizing cells across a range of these two parameters, we can capture the non-linear behavior without needing complex analog simulation during timing analysis.

The NLDM Philosophy

Precharacterization
Run detailed SPICE simulations once during library development:

  • Apply different input transition times (5-7 values)
  • Apply different output loads (5-7 values)
  • Measure resulting delays and transition times
  • Store results in 2D tables

Runtime Lookup
During timing analysis:

  • Determine actual input transition and output load
  • Look up delay in the precomputed table
  • Interpolate if between table entries
  • Repeat millions of times per second

This trades storage space (larger Liberty files) for runtime speed (no analog simulation during analysis).

Understanding 2D Lookup Tables

Table Structure and Indexing

Basic NLDM Table Format

cell_rise (delay_template_5x5) {
    index_1 ("0.01, 0.05, 0.1, 0.2, 0.4");     // Input transition (ns)
    index_2 ("0.01, 0.05, 0.1, 0.2, 0.4");     // Output load (pF)
    values ( \
        "0.045, 0.053, 0.068, 0.098, 0.158", \  // Row 1: Tin = 0.01ns
        "0.048, 0.056, 0.071, 0.101, 0.161", \  // Row 2: Tin = 0.05ns
        "0.054, 0.062, 0.077, 0.107, 0.167", \  // Row 3: Tin = 0.1ns
        "0.066, 0.074, 0.089, 0.119, 0.179", \  // Row 4: Tin = 0.2ns
        "0.090, 0.098, 0.113, 0.143, 0.203" \   // Row 5: Tin = 0.4ns
    );
}

How to Read This Table

  • Rows correspond to different input transition times (index_1)
  • Columns correspond to different output loads (index_2)
  • Each value is the measured delay in nanoseconds

Example Lookup
For input transition = 0.1ns and output load = 0.2pF:

  • Find row 3 (index_1[2] = 0.1)
  • Find column 4 (index_2[3] = 0.2)
  • Delay = 0.107ns

Why These Specific Index Values?

Non-Uniform Spacing
Notice the indices aren't evenly spaced:

0.01, 0.05, 0.1, 0.2, 0.4

Not: 0.0, 0.1, 0.2, 0.3, 0.4

The Reasoning

  • Delay changes rapidly at small transition/load values
  • Delay changes more slowly at large values
  • Logarithmic-like spacing captures both regions efficiently
  • Concentrates sample points where delay is most sensitive

Typical Index Ranges

For a 1.8V, 65nm technology:

Input transition: 0.01ns to 0.5ns
Output load: 0.005pF to 0.5pF

For a 0.9V, 7nm technology:

Input transition: 0.005ns to 0.2ns (everything is faster/smaller)
Output load: 0.001pF to 0.1pF

Visualizing the Delay Surface

If you plot an NLDM table as a 3D surface:

  • X-axis: Input transition time
  • Y-axis: Output load capacitance
  • Z-axis: Delay

You'd see a curved surface rising in both directions:

  • Increase input transition → delay increases
  • Increase output load → delay increases
  • The surface is NOT a flat plane (non-linear!)
  • The curvature is different in different regions

Key Observations from the Surface

  1. Delay increases monotonically with both variables
  2. The rate of increase changes (non-linear)
  3. Cross-terms exist (interaction between transition and load)
  4. Cannot be represented by simple linear equations

Reading and Interpreting Timing Tables

A Complete Timing Arc Example

Let's examine a complete timing arc with all its tables:

cell (INV_X2) {
    area : 3.456;
    
    pin (A) {
        direction : input;
        capacitance : 0.0030;
    }
    
    pin (Y) {
        direction : output;
        function : "!A";
        max_capacitance : 0.500;
        
        timing () {
            related_pin : "A";
            timing_sense : negative_unate;
            
            /* Delay when A rises and Y falls */
            cell_fall (delay_template_7x7) {
                index_1 ("0.01, 0.025, 0.05, 0.1, 0.2, 0.4, 0.8");
                index_2 ("0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.4");
                values ( \
                    "0.034, 0.038, 0.047, 0.062, 0.092, 0.152, 0.272", \
                    "0.036, 0.040, 0.049, 0.064, 0.094, 0.154, 0.274", \
                    "0.040, 0.044, 0.053, 0.068, 0.098, 0.158, 0.278", \
                    "0.048, 0.052, 0.061, 0.076, 0.106, 0.166, 0.286", \
                    "0.064, 0.068, 0.077, 0.092, 0.122, 0.182, 0.302", \
                    "0.096, 0.100, 0.109, 0.124, 0.154, 0.214, 0.334", \
                    "0.160, 0.164, 0.173, 0.188, 0.218, 0.278, 0.398" \
                );
            }
            
            /* Delay when A falls and Y rises */
            cell_rise (delay_template_7x7) {
                index_1 ("0.01, 0.025, 0.05, 0.1, 0.2, 0.4, 0.8");
                index_2 ("0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.4");
                values ( \
                    "0.042, 0.048, 0.060, 0.084, 0.132, 0.228, 0.420", \
                    "0.044, 0.050, 0.062, 0.086, 0.134, 0.230, 0.422", \
                    "0.048, 0.054, 0.066, 0.090, 0.138, 0.234, 0.426", \
                    "0.056, 0.062, 0.074, 0.098, 0.146, 0.242, 0.434", \
                    "0.072, 0.078, 0.090, 0.114, 0.162, 0.258, 0.450", \
                    "0.104, 0.110, 0.122, 0.146, 0.194, 0.290, 0.482", \
                    "0.168, 0.174, 0.186, 0.210, 0.258, 0.354, 0.546" \
                );
            }
            
            /* Output transition time when Y falls */
            fall_transition (delay_template_7x7) {
                index_1 ("0.01, 0.025, 0.05, 0.1, 0.2, 0.4, 0.8");
                index_2 ("0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.4");
                values ( \
                    "0.022, 0.028, 0.040, 0.064, 0.112, 0.208, 0.400", \
                    "0.024, 0.030, 0.042, 0.066, 0.114, 0.210, 0.402", \
                    "0.028, 0.034, 0.046, 0.070, 0.118, 0.214, 0.406", \
                    "0.036, 0.042, 0.054, 0.078, 0.126, 0.222, 0.414", \
                    "0.052, 0.058, 0.070, 0.094, 0.142, 0.238, 0.430", \
                    "0.084, 0.090, 0.102, 0.126, 0.174, 0.270, 0.462", \
                    "0.148, 0.154, 0.166, 0.190, 0.238, 0.334, 0.526" \
                );
            }
            
            /* Output transition time when Y rises */
            rise_transition (delay_template_7x7) {
                index_1 ("0.01, 0.025, 0.05, 0.1, 0.2, 0.4, 0.8");
                index_2 ("0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.4");
                values ( \
                    "0.026, 0.034, 0.050, 0.082, 0.146, 0.274, 0.530", \
                    "0.028, 0.036, 0.052, 0.084, 0.148, 0.276, 0.532", \
                    "0.032, 0.040, 0.056, 0.088, 0.152, 0.280, 0.536", \
                    "0.040, 0.048, 0.064, 0.096, 0.160, 0.288, 0.544", \
                    "0.056, 0.064, 0.080, 0.112, 0.176, 0.304, 0.560", \
                    "0.088, 0.096, 0.112, 0.144, 0.208, 0.336, 0.592", \
                    "0.152, 0.160, 0.176, 0.208, 0.272, 0.400, 0.656" \
                );
            }
        }
    }
}

Analyzing Delay Patterns

Observation 1: Asymmetry
Compare cell_fall vs. cell_rise at (0.05ns, 0.05pF):

  • Fall delay: 0.068ns (NMOS pulling down)
  • Rise delay: 0.090ns (PMOS pulling up)
  • Rise is 32% slower (typical for inverters)

Observation 2: Load Sensitivity
Looking at cell_fall with Tin = 0.05ns:

Load:  0.005   0.01   0.025   0.05    0.1     0.2     0.4
Delay: 0.040   0.044  0.053   0.068   0.098   0.158   0.278
  • Doubling load from 0.005 to 0.01: 10% increase
  • Doubling load from 0.2 to 0.4: 76% increase
  • Higher loads show more sensitivity (non-linear!)

Observation 3: Transition Sensitivity
Looking at cell_fall with Cload = 0.05pF:

Tin:   0.01    0.025   0.05    0.1     0.2     0.4     0.8
Delay: 0.062   0.064   0.068   0.076   0.092   0.124   0.188
  • Slower inputs cause longer delays
  • Effect becomes more pronounced at very slow transitions
  • Fast transitions (< 0.05ns) show less variation

Observation 4: Transition Time Propagation
The output transition affects the next stage:

Input transition: 0.05ns, Load: 0.1pF
Cell_fall delay: 0.098ns
Fall_transition output: 0.118ns (output is slower than input!)

This slower output becomes the input to the next gate, potentially causing delay accumulation through a chain of gates.

Corner Case Analysis

What Happens at Table Extremes?

Minimum Values (Top-Left Corner)

Input: 0.01ns, Load: 0.005pF
Cell_fall: 0.034ns
  • Fastest possible delay
  • Best-case scenario: fast input, light load
  • Might be relevant for hold timing analysis

Maximum Values (Bottom-Right Corner)

Input: 0.8ns, Load: 0.4pF
Cell_fall: 0.398ns
  • Slowest characterized delay
  • Worst-case scenario: slow input, heavy load
  • Critical for setup timing in slow paths

Out-of-Range Warning
If your design has:

  • Input transition: 1.2ns (exceeds 0.8ns maximum)
  • The tool must extrapolate beyond characterized range
  • Accuracy degrades significantly
  • Solution: Insert buffers to restore transitions

Interpolation Methods

When Interpolation Is Needed

Most real circuit conditions don't exactly match table entries:

Table has: 0.05ns and 0.1ns
You need: 0.073ns

Table has: 0.025pF and 0.05pF
You need: 0.037pF

The timing tool must interpolate to find the delay value.

Linear Interpolation (1D)

For single-dimension interpolation:

Formula

y = y0 + (x - x0) × (y1 - y0) / (x1 - x0)

Where:
  x0, x1 = table index values surrounding x
  y0, y1 = table delay values at x0, x1
  x = actual parameter value
  y = interpolated delay

Example
Need delay at input transition = 0.073ns (load fixed at 0.05pF)

From table row for load = 0.05pF:

Tin = 0.05ns → Delay = 0.068ns
Tin = 0.1ns  → Delay = 0.076ns

Interpolate:

Delay = 0.068 + (0.073 - 0.05) × (0.076 - 0.068) / (0.1 - 0.05)
      = 0.068 + 0.023 × 0.008 / 0.05
      = 0.068 + 0.00368
      = 0.07168ns

Bilinear Interpolation (2D)

When both input transition and output load are between table entries, we need 2D interpolation.

The Process

  1. Identify the four surrounding table points
  2. Interpolate in one dimension (e.g., input transition)
  3. Interpolate in the other dimension (e.g., output load)

Example
Need delay at Tin = 0.073ns, Cload = 0.037pF

Step 1: Find Surrounding Points

                Cload = 0.025pF    Cload = 0.05pF
Tin = 0.05ns:      0.053              0.068
Tin = 0.1ns:       0.061              0.076

Step 2: Interpolate in Transition Direction (for each load)

For Cload = 0.025pF:

D1 = 0.053 + (0.073-0.05)/(0.1-0.05) × (0.061-0.053)
   = 0.053 + 0.46 × 0.008 = 0.0567ns

For Cload = 0.05pF:

D2 = 0.068 + (0.073-0.05)/(0.1-0.05) × (0.076-0.068)
   = 0.068 + 0.46 × 0.008 = 0.0717ns

Step 3: Interpolate in Load Direction

Final = 0.0567 + (0.037-0.025)/(0.05-0.025) × (0.0717-0.0567)
      = 0.0567 + 0.48 × 0.015
      = 0.0639ns

This is the final interpolated delay value.

Advanced Interpolation: Spline Methods

Some advanced timing tools use cubic spline interpolation:

  • Produces smoother delay curves
  • Better matches physical behavior
  • Requires more computation
  • Generally more accurate than linear interpolation

However, linear/bilinear interpolation is the standard and works well for most applications.

Extrapolation Dangers

What Is Extrapolation?
Estimating values outside the characterized range:

Table maximum: 0.4pF
Your design: 0.6pF (extrapolation required!)

Why It's Dangerous

  • Assumes the trend continues linearly (often wrong)
  • Physical behavior may change dramatically outside characterized region
  • Can underestimate delays by 20-50% or more

Example of Extrapolation Error

Characterized range:
  Load 0.2pF → Delay 0.152ns
  Load 0.4pF → Delay 0.272ns
  Slope: 0.6ns/pF

Linear extrapolation to 0.6pF:
  Delay = 0.272 + 0.2 × 0.6 = 0.392ns

Actual SPICE simulation at 0.6pF:
  Delay = 0.520ns (33% error!)

How to Avoid Extrapolation

  • Keep input transitions within table range (insert buffers)
  • Keep output loads within max_capacitance limits (insert buffers)
  • Use appropriate drive strengths (upsize if needed)
  • Check design rule violations in timing reports

Practical Application: Reading Timing Reports

Understanding Tool Interpolation Messages

Typical Warning

Warning: Cell INV_X1/Y output load 0.523pF exceeds 
         max_capacitance 0.500pF (extrapolation used)

What This Means

  • The tool is going beyond characterized data
  • Timing results may be optimistic
  • You need to fix this before tape-out

Solution

Before: INV_X1 driving heavy load (0.523pF)
After:  INV_X1 → INV_X4 → load (split into 0.15pF + 0.373pF)

Interpreting Delay Contributions

Sample Timing Report Fragment

Point                        Incr      Path
--------------------------------------------
FF1/CP (rising edge)         0.000     0.000
FF1/Q (DFF_X1)               0.168     0.168  (clk-to-q)
net1 (load: 0.025pF)         0.012     0.180  (wire)
INV1/A (INV_X2)              0.000     0.180
INV1/Y (INV_X2)              0.058     0.238  (cell)
  (Tin: 0.04ns, Cload: 0.03pF, interpolated)
net2 (load: 0.03pF)          0.015     0.253  (wire)
NAND2/A (NAND2_X1)           0.000     0.253
NAND2/Y (NAND2_X1)           0.063     0.316  (cell)
  (Tin: 0.045ns, Cload: 0.02pF, interpolated)

What You're Seeing

  • Each cell delay comes from NLDM table lookup/interpolation
  • Actual input transition and load capacitance are shown
  • You can verify these values against the Liberty tables
  • Net delays come from parasitic RC extraction (different model)

Table Size Considerations

Storage vs. Accuracy Trade-off

5×5 Table

  • 25 data points per table
  • Fast to parse and search
  • May need more interpolation
  • Typical for less critical cells

7×7 Table

  • 49 data points per table
  • Better accuracy with less interpolation
  • Typical for standard cells

9×9 or Larger

  • 81+ data points
  • Maximum accuracy
  • Used for critical cells (clocks, I/O)
  • Larger Liberty files

Complete Cell Cost
For one timing arc:

  • 4 tables (cell_rise, cell_fall, rise_transition, fall_transition)
  • At 7×7 = 49 points each
  • Total: 196 floating-point values per arc

For a complex cell with 10 timing arcs:

  • 1,960 values just for timing
  • Plus power tables (similar size)
  • This adds up across a 500-cell library!

Modern Library Sizes

Typical Modern Library File Sizes

  • Basic standard cells: 50-100 MB per corner
  • Complete library (all corners/modes): 500 MB - 1 GB
  • Advanced nodes (7nm, 5nm): Can exceed 2 GB per corner

This is why Liberty file parsing and caching are important for tool performance.

Best Practices for Working with Delay Tables

1. Always Check Table Ranges

# Quick Liberty file check
grep "index_1" timing_lib.lib | head
grep "index_2" timing_lib.lib | head

Know your library's characterized ranges.

2. Monitor Extrapolation Warnings
During timing analysis:

  • Count extrapolation warnings
  • Goal: Zero extrapolation in final design
  • Each warning is a potential accuracy problem

3. Understand Your Corner Coverage

SS corner: Delays are longest (maximum index values most relevant)
FF corner: Delays are shortest (minimum index values most relevant)

4. Validate Critical Paths
For critical timing paths:

  • Check actual input transition times
  • Verify output loads
  • Ensure both are well within table ranges
  • Consider SPICE verification if on table boundaries

5. Use Table Data for Design Decisions

  • Need to meet timing? Check load sensitivity (column progression)
  • Signal integrity concerns? Check transition sensitivity (row progression)
  • Choosing drive strength? Compare tables across cell variants

Summary

Delay tables and modeling form the computational core of timing analysis:

  • NLDM uses 2D lookup tables indexed by input transition and output load
  • Non-uniform index spacing efficiently captures non-linear delay behavior
  • Bilinear interpolation enables accurate delay calculation between table entries
  • Extrapolation beyond table ranges is dangerous and should be avoided
  • Multiple tables per timing arc capture rise/fall delays and transitions
  • Table interpretation skills are essential for debugging timing issues

Understanding delay tables transforms timing reports from mysterious numbers into physical insights. When you see a delay value, you now know it came from a specific SPICE simulation, was stored in a specific table location, and was retrieved through interpolation. This knowledge enables you to:

  • Identify when tools are working with good vs. poor data
  • Understand why certain optimizations help
  • Debug unexpected timing behaviors
  • Make informed decisions about cell sizing and buffering

In the next module, we'll explore power modeling in Liberty files—another crucial aspect of cell characterization that uses similar table-based approaches.

Did you find what you were looking for?

Quiz

No quiz questions available for this article.