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

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • The NanoSoC Tour
  • Reading Path
  • SoC Glossary10
  • SoC Metrics Reference
  • SoC Cheatsheet
  • What SoC Integration Is12
  • Architecture and Budgets21
  • Memory Maps and Address Decode26
  • Interconnect and Bus Fabrics26
  • Clock and Reset Architecture24
  • Power Architecture21
  • Interrupts, DMA and Peripherals15
  • Memories, Boot and Security21
  • IP Integration and Handoff21
    • IP Collateral and Versioning
    • Wrappers and Adapters
    • Integration Lint and Connectivity Checks
    • Top-Level SDC and Constraint Merge
      • Clock Definitions Belong at the Top
      • Merging Block Constraints
      • Exceptions and Their Review
    • DFT Integration
    • Debug Infrastructure
    • Safety and Fault Architecture
  • Top-Level Verification and Bring-up21
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Top-Level SDC and Constraint Merge
  1. Topics
  2. SoC Design
  3. IP Integration and Handoff
  4. Top-Level SDC and Constraint Merge
  5. Merging Block Constraints
On this page

    Part 9 of 14, lesson 11 of 21Part 9 of 14/IP Integration and Handoff/Lesson 11 of 21All levels

    Merging Block Constraints

    What survives the trip to the top: case analysis, boundary exceptions, and everything that must be rewritten.

    Why it matters

    The DMA's block constraints pin its test modes, waive its asynchronous reset release, and bound its APB inputs against a 96 MHz clock that its file defines locally. At the top, the test pins belong to the test controller, the reset release belongs to the synchroniser the wrapper supplies, and the clock belongs to the previous lesson. Keeping the file intact double-constrains, under-constrains and mis-constrains at once. The way through is a sort: per constraint class, what survives, what is rewritten against top clocks, and what is deleted.

    The core idea

    Four classes decide every line. Clock definitions are deleted from block files and live only at the top, as the previous lesson demands. Boundary input and output delays depend on what sits across the boundary. Delays between blocks that are now timed together are deleted, because the real driver and the real load exist and are timed directly; keeping them would double-constrain the path. Delays on real chip pins are rewritten against the board plan. Delays on a block that stays a budgeted partition are re-budgeted, and the interface-budget discipline from STA governs that rewrite. Case analysis and mode constants are replaced by the top-level mode matrix: a block's test-mode setting becomes one case of the chip's modes, owned with the other modes in one place. Exceptions, false paths and multicycle paths survive only with evidence re-qualified at the top, which is the next lesson. The checker below enforces the sort mechanically: it reads each block line's class, applies the verdict, and refuses any file whose clock definitions, stale boundary delays or unqualified exceptions reach the top.

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    # The merge sort: every block-constraint line gets exactly one verdict.
    def verdict(kind, detail):
        if kind == "clock_def":
            return "delete: defined at the top only"
        if kind == "io_delay":
            where = detail.get("across")
            if where == "block":            # both sides now timed together
                return "delete: real driver and load are timed at the top"
            if where == "chip_pin":
                return "rewrite: against the board plan"
            if where == "partition":
                return "re-budget: block stays a budgeted partition"
            return "unknown: human decision required"
        if kind == "case_mode":
            return "replace: fold into the top-level mode matrix"
        if kind == "exception":
            ok = detail.get("evidence") and not detail.get("expired", True)
            return "keep" if ok else "quarantine: re-qualify or drop"
        return "unknown: human decision required"
    
    lines = [("clock_def", {}), ("io_delay", {"across": "block"}),
             ("io_delay", {"across": "chip_pin"}), ("io_delay", {"across": "partition"}),
             ("case_mode", {}),
             ("exception", {"evidence": "cdc-report-41", "expired": False}),
             ("exception", {"evidence": None, "expired": True})]
    got = [verdict(k, d) for k, d in lines]
    assert got[0].startswith("delete") and got[1].startswith("delete")
    assert got[2].startswith("rewrite") and got[3].startswith("re-budget")
    assert got[4].startswith("replace")
    assert got[5] == "keep" and got[6].startswith("quarantine")
    assert sum(1 for g in got if g == "keep") == 1
    assert verdict("io_delay", {}).startswith("unknown")   # unclassified lines are not guessed
    print("PASS: 7 lines sorted; 1 exception kept, 1 quarantined, unclassified delay refused")

    What the review looks for

    • The sorted list per block: every line classified, every clock definition gone, every rewrite traced to a top clock.

    • The mode matrix covering test, mission and sleep cases in one file instead of scattered case constants.

    • Zero unqualified exceptions surviving the trip, and no boundary delay left between two blocks that are timed together; quarantine is a decision with an owner, not a parking lot.

    Verify and debug

    After the merge, compare constrained-clock coverage before and after: every top clock must constrain strictly more endpoints than the sum of the block assumptions it replaced, because top paths the blocks never saw now exist. If coverage drops on any clock, a block file was deleted rather than rewritten and its boundary delays went with it. For the synthesis-side handoff view see Physical-Aware Synthesis and Handoff.

    Hand edit of the merged constraint file: a quick timing fix typed into the merged output, never back-annotated to its block or top source, so the next regeneration reverts it silently and the violation returns the night before signoff. Route every change through the block or top source, never the merged output, and diff the regenerated file against the last signed one.

    If asked what you keep from block SDC, answer per class: clocks never, boundary delays deleted between timed blocks and rewritten at chip pins, modes folded into the top matrix, exceptions only with fresh evidence. Then say what the merge check enforces: no clock definitions and no unevidenced exceptions below the top.

    Check yourself A block exception waives a path between two flops that the top level replicates per domain. Keep it?

    Quarantine and re-qualify: the replicated path is a new path the block evidence never saw. The evidence must be rerun against the top-level instance, or the exception is dropped and the path timed.

    Related topics

    • Clock Definitions Belong at the Top

    • Next: Exceptions and Their Review

    • STA: Corner and Mode Matrix Design

    Previous

    182 / 289

    Next: Exceptions and Their Review

    Up next

    Up nextExceptions and Their Review

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error