GLS · Chapter 4 · SDF Annotation
What SDF Is and What It Carries
SDF, the Standard Delay Format, is a text file of timing data for one specific netlist and nothing else. It carries three things: per-instance cell delays, per-net interconnect delays, and timing-check values, each written as a min, typical, and max triplet. The SDF is the bridge that back-annotates real timing onto a gate-level simulation: the library and parasitics feed delay calculation, which writes the file, which is applied to the netlist. Just as important is what SDF does not carry. It holds no logic and no function, so it changes timing and never behavior. This lesson explains what an SDF contains, what it leaves out, and why an annotated run is still a dynamic simulation rather than timing signoff.
Foundation11 min readGLSSDFBack-AnnotationDelaysTiming
Chapter 4 · Section 4.1 · SDF Annotation
Project thread — the counter's cells have specify arcs (3.1) and timing checks (3.2) sitting at placeholder zero. This chapter fills them with an SDF; 4.6 annotates the counter end-to-end.
1. Why Should I Learn This?
The SDF is the artifact that turns a zero-delay gate run into a timed one. Without knowing what it carries, you cannot reason about what an annotated run actually models.
- SDF = timing only (cell + net delays + check values), per instance, as
MIN:TYP:MAX. - It is generated from the
.liband SPEF by delay calculation — not written by hand. - It changes timing, never logic — a frequent point of confusion.
This opens the SDF chapter (4.2 anatomy, 4.3 flow, 4.4 triplets, 4.5 debug, 4.6 the counter).
2. Real Silicon Story — the SDF blamed for a logic bug
A gate run produced a wrong logical result. An engineer suspected the SDF and spent a day swapping SDF files, expecting one to "fix" the output.
The SDF was never the cause. SDF carries timing — delays and check values — not function. The wrong result came from the netlist/stimulus logic; no SDF could change it. The right SDF only changes when signals transition, not what value they settle to (barring timing-induced X).
Lesson: SDF is timing-only. If a logical value is wrong, look at the netlist, models, or stimulus — not the delay file.
3. Concept — what an SDF carries (and what it doesn't)
An SDF carries, for one specific netlist:
- Cell delays — per-instance pin-to-pin
IOPATHvalues (thespecifyarcs of 3.1). - Interconnect delays — per-net
INTERCONNECTvalues (post-layout, from SPEF, 3.3). - Timing-check values —
SETUP,HOLD,WIDTH,RECOVERY,REMOVAL(3.2). - Each as a
MIN:TYP:MAXtriplet — three delay values per entry (4.4).
An SDF does not carry:
- No logic / function — that is the netlist + cell models.
- No stimulus — that is the testbench.
- No parasitics — those are in the SPEF; SDF has the delays computed from them.
Where it comes from: .lib + SPEF → delay calculation / STA → SDF (per corner). It is generated, not authored.
Scope: SDF gives GLS real delays, but the run stays dynamic/stimulus-limited — STA is signoff (0.3). Representative snippets are not exact tool output.
4. Mental Model — SDF is a timing overlay, not a redesign
Think of the netlist + cell models as a black-and-white drawing (the logic), and the SDF as a timing overlay laid on top.
- The overlay adds when each edge happens — cell and net delays, check windows.
- It never redraws the lines — the logic underneath is unchanged.
- Remove the overlay (no annotation) and you still have the full drawing, just with every delay at zero.
So SDF colours in the timing; it cannot change what the circuit computes.
5. Working Example — an SDF fragment, and before/after annotation
A representative SDF fragment — the three kinds of entry:
# SDF — REPRESENTATIVE, tool-neutral. Timing ONLY. Each value is MIN:TYP:MAX (4.4).
(CELL (CELLTYPE "DFFRX1") (INSTANCE u_cnt/u_q1)
(DELAY (ABSOLUTE
(IOPATH CK Q (0.08:0.11:0.15)))) # cell delay (3.1)
(TIMINGCHECK
(SETUP D (posedge CK) (0.04:0.05:0.06)) # check value (3.2)
(HOLD D (posedge CK) (0.02:0.02:0.03))))
(CELL (CELLTYPE "XOR2X1") (INSTANCE u_cnt/u_x1)
(DELAY (ABSOLUTE
(INTERCONNECT u_cnt/u_i0/Y u_cnt/u_x1/A (0.03:0.04:0.06)) # net delay (3.3)
(IOPATH A Y (0.05:0.06:0.08)))))Practical context (representative, tool-neutral):
sdf/
counter4_tt.sdf # generated by delay calc from cells_tt.lib + counter4.spef
# The SDF names EXACT instances (u_cnt/u_q1) and pins (CK, Q) in THIS netlist.
# It is consumed by both STA (static) and GLS (dynamic) — same delays, different use.Before vs after annotation, as a real waveform:
Same flop: zero-delay (no SDF) vs SDF-annotated (real clk-to-Q delay)
8 cycles6. Debugging Session — swapping SDFs to fix a logic bug
A wrong logical value is blamed on the SDF and 'fixed' by swapping SDF files — but SDF carries timing only, so no SDF can change a logical result; the bug is in the netlist, models, or stimulus
SDF = TIMING ONLY, NOT LOGICA gate run produces a wrong logical output. An engineer swaps between SDF files expecting one to correct it; none do.
SDF carries timing — cell delays, net delays, timing-check values — and nothing about logic. It changes when signals transition (and, via timing checks, can inject X on violations), but it cannot change what value a correctly-behaving path computes. A wrong logical result therefore comes from the netlist, the cell models, or the stimulus — never from the delay file. Swapping SDFs only changes timing, so the logical output stays wrong.
Debug logical wrongness in the logic domain: compare RTL vs gate behaviour, check the netlist/models, check the stimulus (Chapter 12 covers RTL-vs-GLS triage). Reserve SDF changes for timing questions. Keep the split clear: SDF = timing overlay; netlist + models = logic. And remember an annotated run is still dynamic — a timing-clean SDF run is not a timing signoff; STA is (0.3).
7. Common Mistakes
- Expecting SDF to change a logical value. It carries timing only.
- Thinking SDF contains parasitics. SPEF has parasitics; SDF has the delays computed from them (3.3).
- Assuming one SDF fits all corners. SDF is per-corner (3.4).
- Forgetting SDF is generated, not authored. Delay calc/STA produce it from
.lib+ SPEF. - Reading a clean SDF run as timing closure. GLS stays dynamic; STA signs off (0.3).
8. Industry Best Practices
- Treat SDF as a timing overlay on fixed logic.
- Use the per-corner SDF matching your check (3.4).
- Debug logic in the logic domain, timing in the timing domain.
- Trust generated SDF from delay calc/STA — don't hand-edit values.
- STA signs off timing; SDF-GLS confirms function with real delays.
Senior Engineer Thinking
- Beginner: "The output's wrong — let me try a different SDF."
- Senior: "SDF is timing only. A wrong value is a logic/stimulus issue. SDF changes when, not what — I'll debug the netlist and stimulus, and use SDF for timing questions."
The senior keeps the timing overlay (SDF) and the logic (netlist/models) firmly separate.
Silicon Impact
Conflating SDF with logic wastes debug cycles and can mask the real bug. More subtly, not understanding what SDF carries leads teams to over-trust a timing-clean annotated run as closure — letting a real timing violation (on an unexercised path or uncovered corner) reach silicon (0.3). SDF is the mechanism that lets GLS see real delays; STA is what proves them. Using each for its purpose — SDF/GLS for functional-with-delay confidence, STA for timing signoff — is what keeps both logic and timing bugs off the tape-out.
Engineering Checklist
- Understood SDF carries timing only (cell + net delays + check values,
MIN:TYP:MAX). - Used the per-corner SDF for the check at hand (3.4).
- Debugged logical wrongness in the logic domain (netlist/models/stimulus).
- Treated generated SDF as authoritative (no hand-editing).
- Relied on STA for timing closure, SDF-GLS for function-with-delay.
Try Yourself
- Run the representative flop with no SDF —
Qupdates the instantCKrises (zero-delay). - Observe: the captured value is correct; timing is instant.
- Change: annotate the SDF fragment above (or a tiny hand-made one) with
(IOPATH CK Q (…)). - Expect:
Qnow updates a real delay afterCK— same value, later time. Then deliberately corrupt a logical input and confirm no SDF change fixes it.
Any free Verilog simulator supports $sdf_annotate. Real SDF is generated by EDA delay-calc tools, but the format and effect are identical. No paid tool required.
Interview Perspective
- Weak: "SDF is the delay file that makes gate sim work."
- Good: "SDF carries per-instance cell delays, net delays, and timing-check values as
MIN:TYP:MAX, back-annotated onto the netlist'sspecifyarcs." - Senior: "SDF is timing-only for one specific netlist, generated by delay calc from the
.liband SPEF, per corner. It changes when, not what — logic stays in the netlist and models. And an annotated run is still dynamic; STA is the timing signoff."
9. Interview / Review Questions
10. Key Takeaways
- SDF (Standard Delay Format) is a text file of timing data for one specific netlist: cell delays (
IOPATH, 3.1), interconnect delays (INTERCONNECT, 3.3), and timing-check values (SETUP/HOLD/…, 3.2). - Each delay is a
MIN:TYP:MAXtriplet (4.4), and the whole file is per corner (3.4). - It is the bridge:
.lib+ SPEF → delay calculation → SDF → back-annotation ontospecifyarcs → timed GLS. - SDF carries timing only — no logic, function, or stimulus; it changes when signals move, not what they compute.
- Even fully annotated, GLS stays dynamic/stimulus-limited — STA is the timing signoff (0.3). Next: 4.2 — the anatomy of an SDF file.
Quick Revision
SDF = timing data for one netlist: cell delays (
IOPATH), net delays (INTERCONNECT), check values (SETUP/HOLD), eachMIN:TYP:MAX, per corner. Generated by delay calc from.lib+ SPEF; back-annotated ontospecifyarcs. Timing only — no logic (that's the netlist/models). It changes when, not what. SDF-GLS is still dynamic; STA is signoff. Next: 4.2 — anatomy of an SDF file.