GLS-05: Setting Up a GLS Flow — VLSI Trainers
⌂ Home / GLS Series
Gate-Level Simulation · Article 5 of 7

GLS-05: Setting Up a GLS Flow

The four required inputs, how to run zero-delay and SDF-annotated GLS step by step, reading the elaboration log and annotation statistics, using verbose debug switches, and interpreting the regression loop from first delivery to signoff.

📥The Four GLS Inputs

Every GLS run — whether zero-delay or SDF-annotated — requires exactly four inputs. If any one is missing or mismatched, the simulation either fails to compile or produces misleading results.

Figure 1 — The four required inputs for a GLS run
① Gate-Level Netlist Verilog or VHDL file of cell instantiations and wire connections. Post-synthesis or post-P&R. design_netlist.v ② Cell Library Models Verilog simulation models for every standard cell in the library. Contain specify blocks with timing. stdcell_lib.v ③ SDF Timing File Back-annotated delays from P&R or STA tool. Contains IOPATH and timing check values. timing.sdf ← optional for zero-delay ④ Testbench Instantiates the DUT, drives stimulus, checks outputs. May contain $sdf_annotate call. tb_top.v HDL Simulator (compile → elaborate → simulate) vlsitrainers.com

Four required GLS inputs. The gate-level netlist and cell library models are always required — together they define the structural description and the logical/timing behaviour of every cell. The SDF file is required for SDF-annotated simulation but is ignored (with a warning) in zero-delay mode. The testbench exercises the design; in SDF mode it may contain a $sdf_annotate call, or annotation can be driven externally via an SDF command file.

InputWhat it providesWho delivers itRequired for zero-delay?
Gate-level netlist Structural instantiation of all standard cells and their interconnections Synthesis or P&R tool (backend team) Yes
Cell library models Verilog simulation models for every cell type, including specify blocks with timing arcs and checks Standard cell library vendor (process design kit) Yes — for cell behaviour even without timing
SDF timing file Back-annotated IOPATH delays and timing check values for every instance P&R or STA tool (backend team) No — suppressed in zero-delay mode
Testbench Stimulus generation, DUT instantiation, output checking, and optionally $sdf_annotate Verification team Yes

🗺️Overall GLS Flow

Every GLS run follows the same three-phase sequence regardless of delay mode: compile (parse and check all HDL source files), elaborate (build the design hierarchy, apply delay annotation, compile timing checks), and simulate (run the testbench, evaluate timing checks, report violations).

Figure 2 — Three simulation phases and what happens in each
① Compile • Parse all HDL source files • Check syntax and semantics • Build module library cache • Report compile errors/warnings netlist + library + testbench ② Elaborate • Build full design hierarchy • Apply SDF annotation (if present) • Compile specify blocks / tfile • Print annotation statistics delays annotated here — not at sim time ③ Simulate • Evaluate logic transitions • Propagate delays through cells • Evaluate timing checks per edge • Report violations and results all failures appear here vlsitrainers.com

Three GLS phases. Compile parses and checks all HDL source. Elaborate builds the hierarchy, applies SDF annotation, and compiles timing check infrastructure — delays are annotated here, not at simulation time. Simulate runs the testbench, propagates transitions through cells using annotated delays, and evaluates timing checks at every clock edge. Errors in elaboration must be fixed before simulation can start; timing violations appear during simulation.

Many simulators provide a single-step invocation that performs all three phases in one command, or a three-step invocation (compile, elaborate, simulate as separate commands) that allows incremental re-runs. For large designs, the three-step approach is preferred — recompile only the changed files, re-elaborate only if the hierarchy changed, re-simulate without recompiling when only testbench content changed.

0️⃣Running Zero-Delay GLS

Zero-delay GLS is the simplest and fastest mode. The only timing-specific addition to a standard compilation is the flag that suppresses specify blocks. The design, library, and testbench are compiled and elaborated normally; the specify blocks (which contain path delays and timing checks) are simply not activated.

Required files

Elaboration flag for zero-delay

The -nospecify switch is passed at elaboration. It suppresses all specify blocks across all modules, disabling path delays and timing checks. If the testbench contains a $sdf_annotate call, the simulator will warn that it is being ignored — this warning is expected and benign in zero-delay mode.

// Zero-delay GLS: compile, elaborate, simulate
// Step 1 — compile all sources
compile \
  counter_netlist.v \
  stdcell_lib.v \
  counter_tb.v \
  -timescale 1ns/10ps

// Step 2 — elaborate with zero-delay switch
elaborate \
  counter_tb \
  -nospecify         // suppress all specify blocks

// Step 3 — simulate
simulate -run
What -nospecify does to $sdf_annotate: If the testbench calls $sdf_annotate("timing.sdf", top.dut) at time 0, the elaborator will print a warning such as: “Ignoring $sdf_annotate on line N because of -nospecify option.” This is the correct and expected behaviour. The SDF file is not read, no delays are annotated, and simulation proceeds in true zero-delay mode. No action is needed.

📋Reading the Zero-Delay Elaboration Log

The elaboration log is the first place to look after every GLS run. For zero-delay mode, the key things to confirm in the log are:

// Example zero-delay elaboration log output (annotated)

file: counter_netlist.v
  module worklib.counter:v
  errors: 0, warnings: 0     ← netlist compiled cleanly

file: counter_tb.v
  module worklib.counter_tb:v
  errors: 0, warnings: 0

file: stdcell_lib.v
  module stdcell_lib.INVX1:v
  errors: 0, warnings: 0
  module stdcell_lib.NAND2X1:v
  errors: 0, warnings: 0
  module stdcell_lib.DFFX1:v
  errors: 0, warnings: 0
  ... (all library cells)

Elaborating design hierarchy:
  Top level: counter_tb

*W,SDFSKPA: Ignoring $sdf_annotate on line 12 in counter_tb.v
           because of -nospecify option.
            ↑ Expected — confirms zero-delay mode is active

Design hierarchy summary:
  Modules:    24   Unique: 8
  Primitives: 79
  Registers:  12
  Timing checks: 0   ← confirms specify blocks are inactive

The critical indicator for zero-delay mode is “Timing checks: 0” in the design hierarchy summary. This confirms that no specify block timing checks were compiled. If this number is non-zero in a zero-delay run, the -nospecify switch was not applied correctly.

SDFSKPA warning is expected in zero-delay mode. This warning indicates the $sdf_annotate call in the testbench was suppressed. It is informational — confirming that zero-delay mode is correctly active. If you do not see this warning and the testbench has a $sdf_annotate call, investigate whether the SDF is being inadvertently annotated.

📊Running SDF-Annotated GLS

SDF-annotated GLS is structurally identical to zero-delay GLS except that the -nospecify switch is removed and the SDF file is provided — either via an SDF command file or via a $sdf_annotate call in the testbench. The elaborator reads the SDF file, annotates every timing arc, and compiles the timing checks before simulation begins.

Method A — SDF command file (recommended)

The SDF command file approach keeps annotation configuration external to the testbench. The same testbench runs both zero-delay GLS (without the command file argument) and SDF GLS (with the command file argument) without any testbench modification.

// sdf_cmd_file contents:
SDF_FILE    "timing.sdf"
SCOPE       counter_tb.dut       // DUT root in the testbench
MTM_CONTROL MAXIMUM             // use worst-case delays for setup signoff
LOG_FILE    "sdf_annotate.log"   // annotation detail log

// Elaboration command:
elaborate \
  counter_tb \
  -sdf_cmd_file sdf_cmd_file
  // no -nospecify — specify blocks active

Method B — $sdf_annotate in testbench

The system task approach embeds the annotation instruction directly in the testbench HDL. This is simpler for single-corner runs but requires testbench changes to switch between corners or SDF files.

// Inside the testbench initial block:
initial begin
  $sdf_annotate(
    "timing.sdf",        // SDF file path
    counter_tb.dut,      // annotation scope
    ,                    // config file (unused)
    "sdf_annotate.log", // annotation log file
    "MAXIMUM"            // MTM control
  );
end

// Elaboration command (no -nospecify):
elaborate counter_tb
Precedence when both methods are present: If the testbench contains $sdf_annotate AND the elaboration command specifies an SDF command file, the command file takes priority and the $sdf_annotate call is suppressed with a warning. The warning will read something like: “Ignoring $sdf_annotate because -sdf_cmd_file was specified.” This precedence rule lets teams use the same testbench for both zero-delay (no command file, $sdf_annotate suppressed by -nospecify) and SDF runs (command file present, overrides the system task).

📈Reading the SDF Annotation Statistics

After SDF annotation during elaboration, the simulator prints a statistics block. This is the most important diagnostic output to examine before trusting any SDF GLS timing results. Never proceed to simulation failure analysis before confirming annotation statistics.

// Example SDF annotation statistics block

Reading SDF file: "timing.sdf"
  Compiled SDF:      timing.sdf.X
  Log file:          sdf_annotate.log
  Annotation scope:  counter_tb.dut
  MTM control:       MAXIMUM
  Scale factors:     1.0 : 1.0 : 1.0

Annotation completed successfully.

SDF statistics:
               Specified    Annotated    Percentage
  PathDelays:       57           57       100.00%
  $setuphold:       96           96       100.00%
  $recovery:         8            8       100.00%
  $removal:          8            8       100.00%
  $hold:             8            0         0.00%
  $width:           24            0         0.00%

  Total Annotated: 169 / 201 = 84.08%

Design hierarchy summary:
  Timing checks: 169    ← non-zero confirms SDF mode active
  Interconnect:   67

Reading this output line by line:

🔍Annotation Percentage Interpretation

Figure 3 — Annotation percentage interpretation guide
Check type Percentage Interpretation and action PathDelays 100% All cell propagation delays applied. Waveforms will show real delays. ✓ Proceed. PathDelays < 100% Serious problem. Check: wrong scope, DIVIDER mismatch, stale SDF, renamed instances. $setuphold 100% All combined setup/hold checks active. Primary timing check coverage confirmed. ✓ $hold 0% Expected if library uses $setuphold. SDF HOLD finds no $hold in model. Investigate once. $width 0% Many flows omit $width from SDF. Confirm with backend team whether this is expected. All checks 0% Library model has no specify block, or -nospecify was applied. Verify elaboration flags. vlsitrainers.com

Annotation percentage interpretation guide. Green rows indicate good annotation coverage. Amber rows ($hold 0%, $width 0%) are common and often expected — investigate once to confirm the explanation, then document. Red rows (PathDelays below 100%, or all checks at 0%) indicate a configuration problem that must be resolved before simulation results can be trusted. The hierarchy summary “Timing checks: N” confirms whether the specify blocks are active at all.

🔎Verbose Annotation and Stats Dump

When annotation statistics are not as expected, two additional debug options provide more detail: verbose annotation logging and the timing dump file.

Verbose annotation log

Verbose mode writes a detailed record of every annotation attempt to the log file — success or failure, the exact arc annotated, and the value applied. This is indispensable for diagnosing partial annotation percentages.

// Add -sdf_verbose to the elaboration command:
elaborate counter_tb \
  -sdf_cmd_file sdf_cmd_file \
  -sdf_verbose           // detailed per-arc annotation log

// Example verbose log entries in sdf_annotate.log:
Time units: 1ps

Annotating to instance counter_tb.dut.u_reg of module DFFX1
  ABSOLUTE (IOPATH (posedge CK) Q) = (180:210:260) rise
  ABSOLUTE (IOPATH (posedge CK) Q) = (175:205:255) fall
  SETUPHOLD D (posedge CK) = (45:52:68) setup (10:12:15) hold

Warning: SDFNEP — path (IOPATH A Y) does not exist in
         instance counter_tb.dut.u_logic.g7 of module NAND2BX1
         ↑ This arc is in the SDF but not in the cell model spec block

Statistics dump file

The statistics dump option writes a structured file listing the annotation results per instance — useful for identifying which specific instances have low annotation coverage when the summary percentage is good but individual blocks are suspect.

// Add -sdfstats to write a statistics file:
elaborate counter_tb \
  -sdf_cmd_file sdf_cmd_file \
  -sdf_verbose \
  -sdfstats annotation_stats.txt

Timing dump file

The timing dump option generates a complete listing of the design hierarchy with all annotated timing values after elaboration. Every scope, every timing arc, and every timing check value actually present in the elaborated simulation is written to the file. This is the definitive check — it shows what the simulator is actually using, bypassing any uncertainty about whether the log represents the real simulation state.

// Request a timing dump (shows actual annotated values):
elaborate counter_tb \
  -sdf_cmd_file sdf_cmd_file \
  -dumptiming timing_dump.txt

// In timing_dump.txt, look for your instance:
// Scope: counter_tb.dut.u_reg
//   pdelay anno='y' delay="210"/>  ← TYP value confirmed
//   pdelay anno='n' delay="0"/>    ← not annotated (problem!)
🔍 Worked Example — Diagnosing Zero Delays in Waveforms

Symptom: SDF annotation statistics show PathDelays 100%, but probing a flip-flop output in the waveform shows it transitioning with zero delay — exactly at the clock edge with no propagation delay.

Step 1 — Check the verbose annotation log. Find the entry for the flip-flop instance. If the log shows ABSOLUTE (IOPATH (posedge CK) Q) = (0:0:0), the SDF itself contains zero for that arc — it is not a simulation issue but an SDF generation issue. Report to the backend team.

Step 2 — Check if TIMESCALE is the problem. If the log shows IOPATH = (180:210:260) but the waveform shows zero delay, the simulation timescale precision is too coarse. The SDF timescale is 1ps but the simulation is running at 1ns/1ns — 210ps rounds to 0.210ns which rounds to 0 at 1ns precision. Fix: add -timescale 1ns/1ps to ensure 1ps precision, or better, -timescale 1ps/1ps.

Step 3 — Use the timing dump. Run with -dumptiming timing_dump.txt and search for the instance. If the dump shows pdelay anno='y' delay="0", the value was annotated as zero after scaling. If it shows pdelay anno='n', the annotation did not happen despite the statistics reporting success — check for scope or DIVIDER mismatch.

🔄The GLS Regression Loop

GLS is not a single run — it is an iterative loop that spans the period from first netlist delivery to final signoff. Understanding the loop structure helps teams plan their schedules and respond to failures efficiently.

Figure 4 — Full GLS regression loop: from first delivery to signoff
Backend delivers Netlist + SDF file Check annotation Statistics ≥ target? Scope correct? Run GLS regression Full test suite with SDF delays Failures? Any? YES Categorise each failure TB Hierarchy Testbench references flattened RTL path Fix: update testbench Annotation Warning SDF path not found in netlist model Fix: VE + backend Timing Violation Setup or hold violated at the specified corner Fix: backend ECO Expected Violation CDC, false path, IP — known and acceptable Fix: add to tfile new netlist NO failures 🎉 GLS Signoff vlsitrainers.com

Full GLS regression loop. The backend delivers netlist and SDF; the verification team checks annotation statistics before running the test suite. Failures are categorised into four types: testbench hierarchy errors (fix in testbench), annotation warnings (joint investigation with backend), genuine timing violations (backend ECO required — new netlist delivered), and expected/known violations (add to tfile with justification). The loop repeats until zero unexpected failures, at which point GLS signoff is granted.

Parallel zero-delay and SDF regression

In practice, most teams run zero-delay GLS and SDF GLS as parallel tracks rather than sequential steps:

A failure in the zero-delay track must be resolved before the SDF track results are meaningful — a functional bug in the netlist will contaminate SDF GLS results with irrelevant timing violations on paths that are functionally incorrect anyway.

🔬VLSI Connections

🔬 GLS infrastructure setup — the one-time cost that pays dividends

The first time a team sets up GLS for a design block, the work involves: writing the SDF command file (scope, MTM, log path), configuring the timescale to match the SDF precision, confirming the cell library simulation model paths, updating the testbench to work with the post-synthesis hierarchy, and building the initial tfile for known CDC and IP waivers. This setup work typically takes one to three engineering days for a new block. Once done, the infrastructure is reused for every subsequent GLS run on that block — the command files, tfile skeleton, and testbench updates are permanent. Teams that invest in clean GLS infrastructure early run signoff GLS with confidence; teams that defer it scramble to set it up under tape-out pressure with less time to investigate each failure thoroughly.

🔬 The -sdf_sim_time switch and when annotation at simulation time is needed

The default and strongly preferred behaviour is to annotate the SDF at elaboration time — before simulation begins. This is the fastest and most reliable approach because annotation is done once, the elaborated netlist contains the final delay values, and every simulation run uses those values without re-reading the SDF. However, a few scenarios require annotation to be applied during simulation rather than at elaboration. The most common is a design where different sub-blocks receive different SDF files at different times — for example, an IP block whose SDF is conditionally loaded based on a testbench configuration parameter evaluated at time 0. In these cases, the -sdf_sim_time (or equivalent) switch allows the $sdf_annotate system task to execute after time 0. The performance cost is significant: simulation must pause while annotation is applied, and any checks already evaluated before annotation are done without the correct delays. Simulation-time annotation should be avoided unless architecturally necessary.

🔬 Zero-delay GLS as a continuous integration gate

At advanced SoC projects with continuous integration (CI) pipelines, zero-delay GLS on the gate-level netlist can be integrated as an automated regression gate. Every time the synthesis tool produces a new netlist (triggered by an RTL commit), the CI system automatically runs the zero-delay GLS test suite and reports results alongside the RTL simulation regression. This “GLS in CI” practice catches synthesis bugs within hours of the RTL change that triggered them — rather than weeks later when the verification team manually kicks off a GLS run. The infrastructure requirement is low: zero-delay GLS is fast enough (similar speed to RTL simulation on the same test suite) to run in CI without blocking the development pipeline. SDF GLS remains a scheduled milestone activity, but zero-delay GLS-in-CI has become a best practice at companies shipping complex SoCs at advanced process nodes.

Summary — GLS-05 key points: Four required GLS inputs: gate-level netlist, cell library simulation models, SDF timing file (zero-delay mode only — suppressed in zero-delay), testbench. Three simulation phases: compile (parse HDL, build library cache), elaborate (build hierarchy, apply SDF annotation, compile timing checks — annotation happens here, not at simulation time), simulate (propagate delays, evaluate timing checks, report violations). Zero-delay GLS: add -nospecify at elaboration; SDFSKPA warning expected; verify “Timing checks: 0” in hierarchy summary. SDF GLS: use SDF command file (recommended, no testbench change needed) or $sdf_annotate in testbench; command file takes precedence if both present. After elaboration, always check annotation statistics before proceeding to failure analysis: PathDelays must be 100%; $setuphold should be 100%; $hold and $width at 0% are often expected. Verbose annotation (-sdf_verbose) and timing dump (-dumptiming) are the two key debug tools when statistics look wrong. GLS regression loop: deliver → check annotation → run regression → categorise failures (TB hierarchy: fix testbench; annotation warning: joint VE+backend investigation; timing violation: backend ECO; expected violation: add to tfile) → iterate until clean → signoff. Run zero-delay track continuously in parallel with SDF track at milestones.
Scroll to Top