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
    • Constraint Bug Patterns
    • View Mismatch Triage
    • Path Group War Room
    • Signoff Regression Hygiene
      • Run Comparison
      • Constraint Diffing
      • Reproducibility
      • Final Checklists
  • STA Interview Prep26
  • Capstone Timing Signoff Lab4
Loading lesson

‹Signoff Regression Hygiene
  1. Topics
  2. Static Timing Analysis
  3. STA Debug Playbook
  4. Signoff Regression Hygiene
  5. Constraint Diffing

Part 9 · Debug Playbook · All levels

Constraint Diffing

Compare constraint files as sets of normalised commands and rank each change by risk; a text diff shows lines, a semantic diff shows effects.

On this page

    Why it matters

    A line diff of two constraint files is noisy: reordered commands, changed whitespace and renamed variables look like changes, and a one-character change in an exception looks the same as one in a comment. Normalising commands and ranking them by what they can do separates the harmless from the dangerous.

    Worked example

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    old = """create_clock -name clk -period 2.0 [get_ports clk]
    set_input_delay 0.5 -clock clk [get_ports din]
    set_false_path -from [get_ports rst_n]
    set_clock_uncertainty 0.1 [get_clocks clk]"""
    new = """create_clock -name clk -period 1.8 [get_ports clk]
    set_clock_uncertainty 0.1 [get_clocks clk]
    set_input_delay 0.5 -clock clk [get_ports din]
    set_false_path -from [get_clocks clk] -to [get_clocks clk2]
    set_multicycle_path 2 -setup -from [get_pins u_a/q] -to [get_pins u_b/d]"""
    risk = {"create_clock": 3, "create_generated_clock": 3, "set_false_path": 3, "set_multicycle_path": 3,
            "set_clock_uncertainty": 2, "set_input_delay": 2, "set_output_delay": 2}
    def norm(text):
        return {" ".join(line.split()) for line in text.splitlines() if line.strip()}
    a, b = norm(old), norm(new)
    removed, added = sorted(a - b), sorted(b - a)
    assert len(removed) == 2 and len(added) == 3
    def score(lines):
        return sorted(((risk.get(l.split()[0], 1), l.split()[0]) for l in lines), reverse=True)
    assert score(removed) == [(3, "set_false_path"), (3, "create_clock")]
    assert score(added) == [(3, "set_multicycle_path"), (3, "set_false_path"), (3, "create_clock")]
    assert max(r for r, _ in score(added) + score(removed)) == 3
    unchanged = a & b
    assert len(unchanged) == 2          # reordering alone did not register as a change
    print("PASS: removed", len(removed), "added", len(added), "unchanged", len(unchanged), "; all four logical changes are high risk")

    Change

    Command

    Risk

    Why

    Clock period 2.0 to 1.8 ns

    create_clock

    High

    Changes every check for that clock

    False path from rst_n removed

    set_false_path

    High

    Exceptions change which paths are checked

    New false path between clocks

    set_false_path

    High

    Broad exceptions can hide real paths

    New multicycle setup

    set_multicycle_path

    High

    Relaxes setup, and needs a hold counterpart

    Reordered uncertainty and input delay

    —

    None

    Same commands in a different order

    The normalised comparison shows that the clock period changed, one false path was removed, one was added with a different scope, and a multicycle path was added: five changed lines but four logical changes, all high-risk, and each deserves a reviewer. The reordering of the uncertainty and input delay lines, which a line diff would show as about two changes, correctly registers as no change here because both lines come after the clock definition and neither overrides the other. Order must still be checked separately: a command that references an object before its creation matches nothing, and later commands can override earlier ones, such as case analysis or a second set_input_delay without -add_delay replacing the first. A real tool must also normalise variable expansion and object patterns; this example only normalises whitespace and order, which is already a large improvement over a text diff.

    What the review looks for

    • Constraint changes are reviewed from a semantic diff, ranked by command risk.

    • Any added or changed exception, clock or generated clock needs an approver who is not the author.

    • A new multicycle setup comes with its hold exception in the same change, or an explanation.

    Common pitfall

    Approving a constraint change from a line diff because it 'looks small'. A single line can be a clock definition.

    Interview

    Offer to rank constraint changes by risk and review the high-risk ones first.

    Check yourself Which of the four logical changes needs a companion change?

    The multicycle setup: its hold exception (N-1) must be added at the same time, or hold will move by a period.

    Related topics

    • Run Comparison

    • Forgotten Multicycle Hold

    • Next: Reproducibility

    Previous

    151 / 183

    Next: Reproducibility

    Up next

    Up nextReproducibility

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Final Checklists