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
  • Reading Paths
  • Glossary
  • Metrics Reference
  • Formal Cheat Sheet
  • Formal Foundations19
  • Properties and SVA16
  • Property Development and Constraints19
  • Proof Engines and Convergence23
  • Formal Applications20
  • Equivalence Checking14
  • Formal Coverage and Signoff15
    • Cover Properties, Vacuity and Reachability
    • Formal Coverage Metrics
    • Bounded Proof Signoff
    • The Formal Signoff Package
      • The Signoff Checklist in Full
      • Worked Signoff of sync_fifo
      • Formal and Simulation, One Ledger
  • Methodology and Debug13
  • Interview Prep15
  • Capstone: A Chip-Block Verification Lab24
Loading lesson

←The Formal Signoff Package
  1. Topics
  2. Formal Verification
  3. Formal Coverage and Signoff
  4. The Formal Signoff Package
  5. Formal and Simulation, One Ledger
On this page

    Part 7 of 10, lesson 15 of 15Part 7 of 10/Formal Coverage and Signoff/Lesson 15 of 15All levels

    Formal and Simulation, One Ledger

    Assign each verification obligation to the method that proves it, with no gaps and no double-counting.

    Why it matters

    Formal proves control properties for every reachable state when the proof is unbounded, and up to the bound otherwise; simulation exercises long system flows. Neither covers the chip alone. The failure mode is not choosing wrongly but choosing vaguely: an obligation assumed covered by both methods and verified by neither, or counted twice to inflate confidence. One ledger with one owner per obligation removes both.

    The core idea

    Each obligation names its method and its gap. Formal rows carry the proof status, the bound or the induction argument; simulation rows carry the tests and the coverage that shows the scenario ran. Double-counting is forbidden: an obligation proven formally is not also claimed as simulation coverage, and a simulation-tested flow is not quoted as a formal result. Each method's gap is stated plainly: bounded formal misses past its bound, simulation samples rather than exhausts.

    An obligation is assigned to one of two branches, a formal row with its status and bound or a simulation row with its tests and coverage. Both branches end in a single ledger row that names one owner and the stated gap.
    One obligation becomes exactly one ledger row: either a formal row or a simulation row, each with its stated gap.

    Worked example: allocating the six running designs

    The table assigns each design's key obligations, with the formal evidence status the formal runs of this course give. Control properties with small state go to formal; long data flows and system sequences go to simulation with named tests. The bridge's data path is the illustrative split: conservation and integrity proven formally with a tracked word, sustained throughput measured in simulation.

    Design

    Formal owns

    Formal evidence

    Simulation owns

    Gap each side states

    Four-entry FIFO

    Overflow, underflow, flags, ordering.

    Proven at k equal to 2 with the tracked-slot helper.

    Sustained throughput and back-to-back stress.

    Formal: data proof is one tracked slot; simulation: sampled traffic only.

    Four-way arbiter

    One-hot grant, no phantom grant, work conservation, bounded wait (a request waits at most 3 cycles).

    Proven at k equal to 1 with helpers, k equal to 4 without.

    Fairness under realistic request patterns.

    Formal: no request-holding rule assumed; simulation: no exhaustion.

    Skid-buffer bridge

    Conservation, hold of valid and data under stall, tracked-word integrity.

    Proven at k equal to 2 with three helper invariants; no k up to 12 closes it without them.

    Throughput and long stall sequences.

    Formal: tracked-word proof, one word at a time; simulation: sampled.

    Register block

    Reset values, read-write, write-1-to-clear, read-only, isolation.

    Proven at k equal to 2.

    Driver sequences and access timing.

    Formal: single-cycle interface; simulation: system interleavings.

    Pipelined arithmetic

    Latency property and retimed equivalence.

    Latency proven at k equal to 3; equivalence proven at k equal to 3, or 2 with the cut invariant.

    Corner data values at speed.

    Formal: 4-bit operands; simulation: no proof.

    Decade counter

    Range invariant and step behaviour.

    Proven at k equal to 2 with the range invariant.

    Terminal-pulse integration in the system.

    Formal: block level only; simulation: sampled.

    Read each row as a contract: the formal evidence column is what the formal side may claim, the gap column is what it may not. The methods meet in the combination lessons linked below; this lesson only fixes who owns which row.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # illustrative: every obligation has exactly one owning method
    owners = {"fifo-overflow": ["formal"], "fifo-throughput": ["simulation"],
              "bridge-integrity": ["formal"], "bridge-stall-sequences": ["simulation"]}
    required = ["fifo-overflow", "fifo-throughput", "bridge-integrity", "bridge-stall-sequences"]
    
    def audit(owners, required):
        faults = []
        for o in required:
            n = len(owners.get(o, []))
            if n == 0:
                faults.append(o + ": verified by neither")
            elif n > 1:
                faults.append(o + ": claimed by both")
        return faults
    
    assert audit(owners, required) == []
    assert audit(dict(owners, **{"fifo-overflow": ["formal", "simulation"]}), required) == ["fifo-overflow: claimed by both"]
    assert audit({k: v for k, v in owners.items() if k != "bridge-integrity"}, required) == ["bridge-integrity: verified by neither"]
    print("PASS: complete allocation accepted; double-counted and unowned obligations rejected")

    What the reviewer looks for

    • Every obligation has exactly one owning method; no row is claimed by both, none by neither.

    • Formal rows carry status and bounds with justifications; simulation rows carry tests with coverage.

    • Each side states its gap in one sentence, and the other side either covers it or it is a waived risk with an owner.

    Verify and debug

    Audit the ledger by obligation, not by method: list every requirement from the specification and find its row. Requirements with no row are the gaps, and they cluster at the boundary, such as reset sequencing across blocks or error responses under backpressure. When a bug escapes, the first question is which row owned it; the second is whether the row's stated gap already predicted the escape.

    The obligation verified by neither: symptom is a field bug in behaviour both teams assumed the other covered. Cause is a split by habit rather than by ledger, with the boundary obligations unowned. Fix is the allocation table with one owner per row, reviewed against the specification line by line. It is found by the coverage audit that starts from requirements, not from existing tests.

    Expect the probe: where is formal the wrong tool? Answer with the allocation: deep datapaths, long system flows and software-driven sequences go to simulation; control, protocols, arbiters, FIFOs and registers go to formal. Then name one obligation each side cannot cover and how the ledger records it.

    Check yourself A throughput requirement is proven formally at block level and measured in simulation. How is it recorded?

    Once, under simulation with the measured numbers, with formal owning only the losslessness underneath. The block proof supports the measurement; it does not replace it.

    Related topics

    • Verification First Principles: Combining Formal and Simulation

    • RTL: When Formal Helps Most

    • UVM: Cover Properties Coverage

    • SystemVerilog: Assertion-Backed Coverage

    • UVM: SVA Cover vs Covergroups

    Previous

    131 / 183

    Next: Methodology and Debug

    Up next

    Up nextMethodology and Debug

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • The Signoff Checklist in Full