Four more GLS issues: diagnosing genuine timing failures vs annotation problems, glitch suppression cancellation, pulse error warnings, and SDF delays not appearing in waveforms. Followed by the complete NTC warning reference table.
During simulation the tool reports a timing check violation. The message includes the specific check type, the instance, simulation time, and file/line of the specify block entry:
Warning! Timing violation $setuphold<setup>( posedge CK:25 NS, negedge D:15330 PS, 10.09 : 10090 PS, 0.00 : 0 FS ); File: ./stdcell_lib.v, line = 9817 Scope: tb_top.dut.u_cpu.count_reg[0] Time: 25 NS
Reading the message anatomy: the setup check fired at 25 ns on instance count_reg[0]. The clock had a positive edge at 25 ns. The data signal D had a negative edge at 15.330 ns. The required setup time is 10.09 ns (about 10.09 ns before the clock edge at 25 ns means data must have been stable by 14.91 ns). But D was still transitioning at 15.330 ns — which is only 9.67 ns before the clock edge, violating the 10.09 ns setup requirement.
Every timing violation falls into one of two categories that require different responses:
Timing violation triage. The waveform shows CK rising at 25 ns and D transitioning at 15.33 ns — only 9.67 ns before the clock edge, violating the 10.09 ns setup requirement. The key diagnostic question: does the waveform show the SDF-annotated delay? If yes, the path genuinely has insufficient timing margin — report to the backend team for an ECO. If the delay in the waveform is zero or does not match the SDF value, the path was not correctly annotated — search the elaboration log for SDFNEP/SDFNET on the driving cell and use -sdf_verbose/-dumptiming to confirm.
The message gives the exact instance, time, and which check fired. Note the clock edge time and the data edge time. Calculate the actual setup margin: clock_time − data_transition_time. Compare against the required setup from the message.
Open the waveform viewer and add signals for the failing flip-flop: CK, D, Q, and the output of the driving combinational cell on the D path. Zoom to the violation time. Measure whether the delay from the previous flip-flop’s Q to this flip-flop’s D matches the SDF-annotated value for that path.
The annotated delay is correctly reflected in the waveform but the path is still too slow. This is a real design timing violation. Gather the instance path, the SDF delay value, and the violation slack, then report to the backend team. They will investigate the physical implementation of that path (cell placement, routing, buffer insertion) and provide an ECO.
Search the elaboration log for SDFNEP or SDFNET warnings mentioning the driving cell instance. If the annotation warning exists for that path, the cell is using its specify block default value (not the SDF value), which may be overly pessimistic and causing a false violation. Resolve the annotation mismatch as described in GLS-06, then re-run to confirm the violation disappears.
// To search the elaboration log for a specific instance: grep -i "SDFNEP\|SDFNET" sdf_annotate.log | grep "count_reg" // To confirm what delay was actually annotated: grep "count_reg" timing_dump.txt // Look for: pdelay anno='y' (annotated) or anno='n' (not annotated)
During simulation, warnings appear indicating that a glitch suppression event was cancelled:
Warning! Glitch suppression Scheduled event for delayed signal of net "DD" at time 6 FS was canceled!
This warning is specific to NTC (Negative Timing Check) delayed signals. When a flip-flop has a negative setup or hold value in the SDF, the simulator generates internally delayed versions of the clock and data signals — denoted here as DD (delayed data). These NTC delayed signals are used by the timing check evaluation logic to determine whether a violation occurred.
The cancellation happens when a new input event arrives at the gate driving DD while a previously scheduled output event is still pending in the event queue. The new input event supersedes the old one, so the old scheduled output event is cancelled. This generates the warning because a transition that was expected to occur at 6 fs is now lost — potentially affecting the timing check evaluation.
This situation occurs specifically when the rise delay and fall delay for the NTC net are different. If a rising transition is scheduled to complete at time T₁ and a falling transition supersedes it before T₁, the rising event is cancelled. The message reports this cancellation.
NTC glitch cancellation. D (blue) has a brief pulse 0→1→0. The NTC delayed signal DD (green dashed = expected) should rise 2 fs after D rises, then fall 4 fs after D falls. But because D falls before the rising event on DD has resolved, the new falling input event cancels the scheduled rising output event. DD actual (red) never fully transitions — the warning reports this cancellation at 6 fs. The root cause is asymmetric rise/fall delays on the NTC net.
Add the -ntc_verbose switch to get detailed information about how NTC delays are being calculated for each affected signal. Compare the calculated rise and fall delays to understand why they differ and whether the NTC algorithm converged.
// Enable verbose NTC reporting at elaboration: elaborate tb_top -sdf_cmd_file sdf_cmd_file -ntc_verbose
Place $monitor statements on the primary inputs that drive the affected NTC net, and on the DD signal itself. This lets you see the sequence of events and compare the input transition times against the calculated delay values to understand exactly when the cancellation occurs and why.
If the glitch cancellation warnings are numerous and not indicating a real design problem, the -nontcglitch switch suppresses the generation of glitch events on NTC nets. This prevents the warning from appearing. Note that this changes simulation behaviour — the NTC mechanism no longer generates the cancelled glitch, which may affect downstream timing check evaluation.
// Suppress NTC glitch generation: elaborate tb_top -sdf_cmd_file sdf_cmd_file -nontcglitch
Warning! Pulse flagged as an error, value = StE File: ./stdcell_lib.v, line = 35, pos = 6 Node: tb_top.dut.u_logic.g15.Z Time: 18754652 PS + 0
The value StE means “Strength to Error” — a pulse that was below the error threshold is propagated as an X (unknown) rather than being absorbed silently. A value of XtX means the output stays at X throughout the pulse cycle.
When a pulse is narrower than the propagation delay of a gate, the inertial delay model rejects it. The simulator has configurable thresholds for this rejection:
With pulse_r=0 and pulse_e=100, any pulse shorter than 100% of the path delay generates this warning and an X on the output. This is the most sensitive configuration — every potential glitch is reported.
Three pulse handling zones. Zone 1 (green): pulse width below pulse_r threshold — absorbed silently, no output transition. Zone 2 (red): pulse width between pulse_r and pulse_e thresholds — output forced to X and warning issued. Zone 3 (blue): pulse width above pulse_e threshold — propagates normally through the gate with delay. With default pulse_r=0 and pulse_e=100, every pulse narrower than the full path delay enters Zone 2.
Widen the reject zone and narrow the error zone to reduce the number of spurious pulse warnings. The correct threshold values depend on the standard cell library — the library vendor characterises the minimum pulse width that reliably causes the cell to switch and provides a recommended pulse_r value.
// Common threshold configurations: // Maximum sensitivity (default): every sub-delay pulse flagged elaborate tb_top ... -pulse_r 0 -pulse_e 100 // Typical production: reject below 50%, flag 50-100% elaborate tb_top ... -pulse_r 50 -pulse_e 100 // Suppress all pulse error messages (not recommended for signoff): elaborate tb_top ... -pulse_r 100 -pulse_e 100
Use -epulse_no_msg to keep the X-on-output behaviour (zone 2 still propagates X) but suppress the warning message from the log. This is appropriate when the team knows the pulse warnings are expected (e.g. on combinational glitch paths in the PDK) but does not want the log flooded with thousands of lines before genuine timing violations.
// Keep X propagation but suppress the message: elaborate tb_top ... -epulse_no_msg
After a successful SDF-annotated GLS run (annotation statistics show 100% path delays annotated), probing a cell output in the waveform viewer shows it transitioning at the exact same time as its input — zero propagation delay — even though the SDF contains a non-zero delay for that arc.
Cause 1 — SDFNEP/SDFNET warnings on that specific path.
Check the elaboration log for annotation warnings on the failing instance. If present, the SDF annotation for that arc failed silently — the specify block default (often 0) is being used. Resolution: fix the annotation mismatch as described in GLS-06.
Cause 2 — Pulse rejection absorbing the transition.
If the input pulse is narrower than the cell’s propagation delay, inertial delay rejects the pulse entirely. No output transition occurs — it looks like zero delay but is actually a rejected pulse. Resolution: set -pulse_r 0 -pulse_e 0 to force all pulses through, or widen the stimulus pulse to exceed the cell delay.
Cause 3 — Timescale/precision mismatch (the most common cause).
The SDF specifies delays in ps but the simulation precision is ns. A 250 ps delay becomes 0.25 ns at the simulator’s precision — which rounds to 0 at 1 ns precision. The annotator reports success (it wrote the value) but the simulator rounds it to zero when it applies the delay.
// Symptom: annotation log shows: IOPATH A→Y = (250:310:420) // Waveform shows zero delay. Simulation timescale is 1ns/1ns. // Fix: set precision fine enough to represent the SDF delays: compile ... -timescale 1ns/1ps // 1ps precision → 250ps is representable // or even finer if SDF delays are in fs: compile ... -timescale 1ns/100fs
Cause 4 — Module-level timescale overrides command-line timescale.
If a module in the design has its own `timescale directive with coarser precision than the command-line setting, that module’s instances use the coarser precision. A 250 ps SDF delay for an instance in a module with `timescale 1ns/1ns still rounds to 0 even with a fine command-line precision. Resolution: use -override_precision to force the command-line precision on all modules, overriding any module-level timescale directives.
// Force command-line precision to override all module-level timescales: compile ... -timescale 1ns/1ps -override_precision
Cause 5 — Annotated delay is genuinely zero in the SDF.
Use the annotation log file (with -sdf_verbose) and check the logged value for the specific arc. If the log shows IOPATH A→Y = (0:0:0), the zero is coming from the SDF itself — not a simulation precision issue. The backend tool generated zero delay for that arc, possibly due to an issue in parasitic extraction or delay calculation. Report to the backend team for investigation.
Timescale precision mismatch. With 1ps precision (top), 250 ps is stored as 250 simulation time units and appears correctly in waveforms. With 1ns precision (bottom), 250 ps = 0.25 ns rounds to 0 simulation time units — annotation reports success but the delay is silently discarded. Always ensure the simulation timescale precision is at least as fine as the smallest delay value in the SDF file.
NTC (Negative Timing Check) warnings arise when setup or hold values in the SDF or specify block contain negative numbers. Advanced-node standard cell libraries frequently include negative timing check values — a negative hold time, for example, means the data is allowed to change slightly before the clock edge. The NTC algorithm handles these values but generates warnings when it encounters edge cases. The following table is the complete reference for NTC-related warnings:
| Mnemonic | Trigger condition | Effect | Resolution |
|---|---|---|---|
SDFNL2 |
Sum of the two limits in $setuphold or $recrem is less than zero (e.g. setup=−6, hold=−4, sum=−10) | Negative limit set to zero. Iteration continues. | Confirm the library characterisation is correct. If intentional, waive. |
SDFIND |
Attempt to annotate a negative delay to a primitive (UDP). UDPs cannot accept negative delays. | Value clamped to zero. | Verify library model. UDPs should not have negative path delays; negative timing checks are normal. |
NONTCTL |
Sum of the two limits is negative. NTC algorithm cannot converge. | Simulation proceeds; limits adjusted. | Use -ntc_tolerance with a positive value to allow the algorithm to converge. |
NTCTLER |
The -ntc_tolerance value specified is not a valid positive number. |
Tolerance ignored; default (0) used. | Correct the tolerance value: must be a positive time value with unit (e.g. 10ps). |
NGLIM2 |
Both limits in $setuphold or $recrem are negative — not just one. | Both limits set to zero. | Investigate library. Both limits negative is unusual and may indicate a characterisation error. |
NTCWID |
The NTC net has different rise and fall delays, and the difference exceeds the limit of a $width check controlled by that net. | $width check may fire spuriously. | Check if the $width check on this net is meaningful. Consider adding to tfile if spurious. |
NTCNNC |
Convergence could not be achieved during NTC delay calculation. Some negative limits set to zero; iteration continues until a solution is found. | Simulation continues with approximated values. | Use -ntc_tolerance. If persistent, investigate the specific $setuphold or $recrem values in the library. |
NTCDNG |
Signals have negative values on both reference and data limits for different edges — this causes non-convergence. Limits set to zero by NTC algorithm. | Timing check limits zeroed; check may not fire correctly. | Report to library vendor. Different-edge negative values for both limits is a library characterisation problem. |
NTCRLX |
Non-convergence due to non-overlapping two-limit constraints for different edges. Limits relaxed by 2 precision units to create minimal overlap. | Limits slightly adjusted; simulation continues. | Usually benign. Verify the relaxed limits do not change the timing check outcome for critical paths. |
NTCELX |
Same as NTCRLX but the relaxation required exceeded a permissible percentage — the limits changed significantly. | Large adjustment to limits; timing check reliability reduced. | Investigate. Large limit changes indicate the NTC values in the library are inconsistent. Report to library vendor. |
NTCPAT |
NTC delay is larger than some portion of an enclosing path delay. The NTC delay may visibly affect the output transition timing. | Output transitions may be delayed beyond what the path delay alone would predict. | Verify that the affected path is not on a critical timing arc. If it is, investigate whether the NTC value is correctly characterised. |
SDFNCAP |
Source and destination for a requested interconnect annotation are not hierarchically connected by a wire — a unidirectional continuous assignment was detected. | Port annotation placed at destination; source annotation skipped. | Review the netlist connectivity around the flagged instance. Usually benign for unidirectional assigns; verify the destination annotation is correct. |
SDFNSB |
A module is being annotated with path delay or timing check information but it has no specify block. | Annotation silently fails for that module. | Add a specify block to the cell model, or confirm the cell genuinely has no timing (e.g. a power/ground tie cell). Issued once per instance. |
In the final weeks before tape-out, GLS timing violations must be triaged with discipline. Every failing instance falls into one of three categories: genuine timing failure (path too slow — backend ECO required), known acceptable violation (CDC, false path — tfile waiver required with documentation), or annotation artefact (wrong delay annotated — requires investigation before categorisation). The danger is misclassifying a genuine failure as an annotation artefact to avoid an ECO cycle. The correct protocol is: any violation where the waveform correctly shows the SDF-annotated delay AND the actual slack is negative is a genuine failure — no matter how inconvenient the timing. Projects that cut corners here find silicon that fails intermittently at timing-marginal paths, which is far more expensive than the ECO cycle that was avoided. Verification leads should track the ratio of genuine failures to annotation artefacts — a high artefact rate indicates a library model or SDF quality problem that itself needs investigation.
Pulse-flagged-as-error warnings (Issue 7) are often the only simulation-time indicator of combinational glitches on control signals. A glitch on a clock enable or asynchronous reset that is shorter than the cell’s propagation delay will be rejected by inertial delay and appear in simulation as a pulse warning on the gate output, with the output driven to X. If that X reaches a flip-flop’s clock enable, it creates an X on the enable signal, which propagates through the flip-flop’s output and contaminates downstream logic. This cascade of X propagation from a single pulse warning is sometimes the first sign of a genuine glitch hazard in the combinational logic. Teams doing formal glitch analysis (using formal property checkers to prove the absence of hazards on specific control signals) should cross-check their formal results against GLS pulse warnings — any path that formal declares glitch-free but GLS flags with pulse warnings deserves investigation, as the formal model may have constraints that the gate-level simulation exercises without restriction.
Negative timing check values are increasingly common in 7nm, 5nm, and 3nm standard cell libraries. A negative hold time (e.g. −20ps) means the cell’s internal clock-to-latch delay is longer than the external hold requirement — data is allowed to change up to 20 ps before the clock edge and the cell will still latch the correct value. This happens because at advanced nodes, cells are aggressively sized to reduce setup time, and the hold margin is “built in” to the cell’s internal timing. From a GLS perspective, negative hold values require the NTC algorithm to generate delayed clock and data signals internally — and the NTC warnings in the reference table above are the simulation manifestations of this processing. Understanding that NTC warnings are a normal feature of advanced-node GLS, not a sign of a broken flow, is important for verification engineers encountering these warnings for the first time. The key question is always: did the NTC algorithm converge (NTCNNC/NTCDNG absent or resolved)? If yes, the timing check is working correctly even if the underlying values are negative.