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
  • Top-Level Verification and Bring-up21
  • Package, Pads and I/O18
  • Chip Signoff and Tapeout18
    • The Signoff Manifest
    • Waiver Governance
      • What May Be Waived
      • Waiver Ageing
      • The Escape Rate
    • Closure Dashboards
    • Tapeout Readiness Review
    • ECO and Respin Risk
    • Errata and Post-Silicon
  • SoC Interview Prep16
  • Capstone: Integrate NanoSoC14
Loading lesson

←Waiver Governance
  1. Topics
  2. SoC Design
  3. Chip Signoff and Tapeout
  4. Waiver Governance
  5. Waiver Ageing
On this page

    Part 12 of 14, lesson 5 of 18Part 12 of 14/Chip Signoff and Tapeout/Lesson 5 of 18All levels

    Waiver Ageing

    Expiry dates, the ageing calculator, review before expiry, and what happens to waivers nobody looks at.

    Why it matters

    A waiver granted in month three for a synchroniser that is correct in month three can be wrong by month nine, because the clock ratio changed, the library cell arrived, or the path was re-timed around the exception. Without expiry, waivers outlive the facts that justified them, and the tapeout review inherits excuses nobody remembers. Ageing forces each waiver to be re-justified or retired on a schedule. Its one job is the clock attached to every excuse; pricing the excuses that were wrong is next.

    The core idea

    Every waiver carries three dates: granted, review-by, and expires. The review-by date arrives first and demands re-confirmation of the evidence against the current design; the expiry date retires the waiver automatically if nobody re-confirms, returning the violation to the open list. The intervals are teaching values the project sets once: proven-safe waivers review every 90 days and expire at 180, false violations review every 30 days because checker versions change the noise, bounded-risk waivers review every 90 days with the integrator present. An ECO touching the waived path expires its waivers immediately, whatever the calendar says, because the evidence described a design that no longer exists. The rule needs a key: each waiver records the violation identifier, the signal or path pattern it covers and the baseline it was granted on, and the checker compares the waived pattern against the changed-object list of every ECO and expires the matches. A waiver recorded as a free-text note cannot be matched to a netlist change.

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    # Waiver ageing: bucket every live waiver by days to expiry and
    # force the review list. Days and path patterns are illustrative; this is
    # the same waiver table the manifest checker reads.
    import fnmatch
    DAY = 150  # days since project start (week 22)
    REVIEWS = {"false": 30, "proven-safe": 90, "bounded-risk": 90}
    EXPIRES = {"false": 90, "proven-safe": 180, "bounded-risk": 180}
    
    waivers = [  # id, class, granted day, path pattern the waiver covers
        ("W-009", "false", 120, "nano_rstpwr/u_rst_sync_*"),
        ("W-014", "proven-safe", 60, "nano_intc/u_sync_irq_*"),
        ("W-021", "proven-safe", 140, "nano_apb_cdc/u_req_*"),
        ("W-027", "bounded-risk", 100, "nano_sbr/u_err_path/*"),
    ]
    
    def ageing(day, eco_changed=()):
        report = {}
        for wid, kind, granted, pattern in waivers:
            age = day - granted
            left = EXPIRES[kind] - age
            status = "due-review" if age >= REVIEWS[kind] else "fresh"
            touched = any(fnmatch.fnmatch(p, pattern) for p in eco_changed)
            if left <= 0 or touched:
                status = "expired"
            report[wid] = (age, left, status)
        return report
    
    report = ageing(DAY)
    assert report["W-009"] == (30, 60, "due-review"), report["W-009"]
    assert report["W-014"] == (90, 90, "due-review"), report["W-014"]
    assert report["W-021"] == (10, 170, "fresh"), report["W-021"]
    assert report["W-027"] == (50, 130, "fresh"), report["W-027"]
    due = sorted(w for w, r in report.items() if r[2] != "fresh")
    assert due == ["W-009", "W-014"], due
    # expiry days: grant day plus the class lifetime
    assert {w: g + EXPIRES[k] for w, k, g, _ in waivers} == {
        "W-009": 210, "W-014": 240, "W-021": 320, "W-027": 280}
    # an ECO that touches the synchroniser expires only the waiver it matches
    eco = ageing(DAY, eco_changed=["nano_intc/u_sync_irq_dma/q0"])
    assert eco["W-014"][2] == "expired"
    assert [w for w, r in eco.items() if r[2] == "expired"] == ["W-014"]
    # and the calendar alone expires W-009 on day 210
    assert ageing(210)["W-009"][2] == "expired"
    print("PASS: 4 waivers aged, review list W-009 and W-014, ECO expires only W-014")

    What the review looks for

    • No waiver in the manifest is past expiry; expired means open, and open violations block the agenda.

    • The review-by list for the next 30 days has named owners, starting with the two the calculator flags above (W-009 and W-014).

    • Every ECO since the last review names the waivers it expired, matched by path pattern against its changed-object list.

    Verify and debug

    Run the calculator nightly beside the manifest checker: it reads the same waiver table, so a waiver edited in one place and not the other fails loudly. When a review-by date arrives, the owner re-attaches evidence against the current revision; re-confirmation without fresh evidence is a new violation of process, and the integrator treats it as one.

    Diagram
    # not-run: the ageing rule card, NanoSoC teaching values (illustrative)
    false violation:      review every 30 days,  expires at 90
    proven safe:          review every 90 days,  expires at 180
    bounded risk:         review every 90 days,  expires at 180
    ECO touches path:     waiver expires immediately, no calendar applies

    A reset-release-order failure, the NanoSoC case where the CPU reset is released before the fabric: a waiver granted when the release order was peripherals, fabric, CPU becomes wrong the day someone reorders for convenience. The ECO-expires rule exists for exactly this: the order changed, so the evidence died with the old order.

    If asked how many waivers a tapeout can carry, refuse the number and give the rule instead: as many as are live, owned, evidenced and unexpired, each re-confirmed against the frozen baseline. Then quote the NanoSoC set: four live waivers on day 150, two due for review, all with owners.

    Check yourself A proven-safe waiver expires next week but the evidence is unchanged and still valid. Cheapest correct action?

    Re-confirm with fresh evidence against the current revision before expiry: rerun the check, re-attach the waveform, reset the dates. Letting it lapse turns a good waiver into an open violation the night before the review.

    Related topics

    • What May Be Waived

    • Next: The Escape Rate

    • Verification: Waivers

    Previous

    236 / 289

    Next: The Escape Rate

    Up next

    Up nextThe Escape Rate

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error