Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • Reading Path
  • STA Glossary
  • STA Metrics Reference
  • STA Mastery Cheatsheet
  • Timing Paths and Checks16
  • Constraints & SDC Fundamentals20
  • Delay Graph & Path Analysis16
  • Beyond Setup and Hold16
  • Multi-Corner Multi-Mode Signoff16
  • OCV, AOCV, POCV and Variation16
  • Crosstalk and Noise16
  • ECO and Closure16
  • STA Debug Playbook16
  • STA Interview Prep26
    • STA Whiteboard Framework
    • STA Framework Drills
    • Scenario: MMMC Storm
    • Scenario: ECO Under Pressure
    • Scenario: Constraint Ghost
      • The Scenario
      • Investigation
      • Root Cause and Fix
      • How to Narrate It
    • STA Interview Q&A Bank
    • STA Interview Q&A Bank (Expanded)
  • Capstone Timing Signoff Lab4
Loading lesson

‹Scenario: Constraint Ghost
  1. Topics
  2. Static Timing Analysis
  3. STA Interview Prep
  4. Scenario: Constraint Ghost
  5. Investigation

Part 10 · Interview Prep · All levels

Investigation

Diff the constraints, list the exceptions with their path counts, and rerun with the suspect exception removed.

On this page

    Step 1: diff the constraints semantically

    A semantic diff of the old and new constraint sets shows one high-risk addition among the harmless reordering: a false path between the two clocks, imported from the earlier project where they were unrelated.

    Diagram
    # not-run: SDC is not executable here
    # added during the refactor (imported snippet)
    set_false_path -from [get_clocks clk_a] -to [get_clocks clk_b]

    Step 2: count what the exception covers

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # paths from clk_a to clk_b: (name, truly asynchronous?, slack with the exception removed, ns)
    paths = [("p%d" % i, False, 0.2 + 0.0002 * i) for i in range(1, 1118)]
    paths += [("q1", False, -0.050), ("q2", False, -0.018), ("q3", False, -0.004)]
    covered = len(paths)
    assert covered == 1120
    violations = sorted((p[0], p[2]) for p in paths if p[2] < 0)
    assert violations == [("q1", -0.05), ("q2", -0.018), ("q3", -0.004)]
    async_paths = [p for p in paths if p[1]]
    assert len(async_paths) == 0
    print("PASS: the exception covers", covered, "paths; truly asynchronous:", len(async_paths), "; violating once removed:", violations)

    Measure

    Value

    Paths covered by the exception

    1,120

    Of which truly asynchronous

    0 (clk_b is generated from clk_a)

    Violations when the exception is removed

    3 (worst -0.050 ns)

    Removing the exception and re-running shows three violations on related paths, worst -0.050 ns, exactly the -0.050 ns that disappeared in the refactor. None of the 1,120 paths is truly asynchronous: the clocks are generated, so every path between them is a related path. The silicon failure is one of the three. It is intermittent because the path is only sensitised by a rare data pattern, and hot is where its delay is worst. The ghost was a constraint that deleted real paths.

    Step 3: look for the same pattern elsewhere

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    generated_from = {"clk_b": "clk_a", "clk_c": "clk_b"}               # generated clock -> its source clock
    exceptions = [("false_path", "clk_a", "clk_b"), ("false_path", "clk_x", "clk_y"), ("false_path", "clk_a", "clk_c")]
    def related(c1, c2):
        def root(c):
            while c in generated_from:
                c = generated_from[c]
            return c
        return root(c1) == root(c2)
    flagged = [e for e in exceptions if related(e[1], e[2])]
    assert flagged == [("false_path", "clk_a", "clk_b"), ("false_path", "clk_a", "clk_c")]
    print("PASS: exceptions between related clocks:", flagged)

    A simple lint walks the generated-clock tree and flags any false path between two clocks with the same root. In this example it finds two: the one that caused the failure and a similar one on clk_c, a second divider. Both are suspicious until proven otherwise.

    Common pitfall

    Fixing only the failing crossing. The same snippet may have been used for every divider.

    Interview

    Describe the three steps: semantic diff, coverage count, rerun without the exception.

    Check yourself Why is the removed-exception run's worst slack close to the pre-refactor WNS?

    The pre-refactor WNS was the same set of related paths; the refactor simply removed them from the analysis, so removing the exception restores them.

    Related topics

    • The Scenario

    • Next: Root Cause and Fix

    • Overbroad False Path

    Previous

    170 / 183

    Next: Root Cause and Fix

    Up next

    Up nextRoot Cause and Fix

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • How to Narrate It