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
    • Formal versus Simulation
    • Transition Systems, Invariants and the Three Property Roles
    • Reset, Initial State and the First Cycle
    • Cone of Influence
    • The Formal Tool Flow, Vendor-Neutral
      • Anatomy of a Formal Harness
      • Tasks, Engines and Time Limits
      • Reading a Result Report
      • Model Fidelity and Unsupported Constructs
  • Properties and SVA16
  • Property Development and Constraints19
  • Proof Engines and Convergence23
  • Formal Applications20
  • Equivalence Checking14
  • Formal Coverage and Signoff15
  • Methodology and Debug13
  • Interview Prep15
  • Capstone: A Chip-Block Verification Lab24
Loading lesson

←The Formal Tool Flow, Vendor-Neutral
  1. Topics
  2. Formal Verification
  3. Formal Foundations
  4. The Formal Tool Flow, Vendor-Neutral
  5. Reading a Result Report
On this page

    Part 1 of 10, lesson 18 of 19Part 1 of 10/Formal Foundations/Lesson 18 of 19All levels

    Reading a Result Report

    What a run reports per property, and how to count it without ever filing a bounded pass or a time-out as a proof.

    Why it matters

    A dashboard showed forty passing lines and the block was signed off; three of the forty were time-outs the summary had counted as passes, and one of them covered the overflow rule. The report had said exactly what happened, but nobody read past the colour. This lesson teaches what a formal run looks like on paper, so the counting is honest before any metric is built on it.

    Job of this lesson: show what a run reports per property and per cover, and give a parser that classifies a generic report and refuses mislabelled lines.

    The core idea

    A run reports, per property: the verdict (proven for the stated model and assumptions, counterexample at a stated step, or inconclusive with the reason), the proof form or depth behind it, the cone size, and the assumptions in force; and, for a proof, the proof core, the part of the model the proof used (a later lesson). Covers report reached with a witness step, or not reached within the bound, which is inconclusive unless an engine proved unreachability. The report below is an illustrative generic format; the values are measured on the running FIFO and the decade counter, so the lesson is the fields, not the format.

    Diagram
    # not-run: illustrative generic report format, not executable here
    # run 1: sync_fifo, helper invariant removed
    # property a_range    : PROVEN (induction, k=1)    cone=3 flops
    # property a_push_inc : PROVEN (induction, k=2)
    # property a_data     : INCONCLUSIVE (base case passed to depth 12, induction step failed at k=12)
    # cover c_full        : REACHED at step 5
    # assumptions: reset at step 0 (1), tracked slot held constant (1)
    # proof core: listed per proven property (a later lesson)
    # run 2: sync_fifo with the overflow bug
    # property a_range    : COUNTEREXAMPLE at step 6
    # property a_ovf_ign  : COUNTEREXAMPLE at step 7
    # run 3: mod10_counter
    # cover c_ten         : NOT REACHED within 20 (inconclusive)

    Property

    Kind

    Earliest failing step

    Why that step

    a_range

    Current state (combinational)

    6

    Reports the step where the bad state exists: the count reads 5.

    a_ovf_ign

    Looks back with $past (clocked)

    7

    Judged at its closing edge, so one step later.

    Worked example: a parser that refuses to misfile

    The parser sorts each line into proven, counterexample, inconclusive or cover-reached, and raises an error on a line that claims a proof while saying it was bounded, unknown or timed out, or that claims a proof with no proof form. Bounded passes, unproven results with a failed induction step, and unreached covers all count as inconclusive. The self-test holds realistic lines, including five realistic lines that naive parsers misfile; the check is applied to the parser and to a naive one, which it catches.

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    import re
    
    INCONCLUSIVE_WORDS = ("BOUNDED", "UNKNOWN", "TIMEOUT", "TIME-OUT", "UNPROVEN", "INCONCLUSIVE", "STEP FAILED", "NOT REACHED", "UNREACHED")
    
    class Mislabelled(ValueError):
        pass
    
    def classify(line):
        up = line.upper()
        weak = any(word in up for word in INCONCLUSIVE_WORDS)
        claims_proof = bool(re.search(r"\bPROVEN\b", up))
        if claims_proof and (weak or "INDUCTION" not in up):
            raise Mislabelled(line)
        if weak:
            return "inconclusive"
        if "CEX" in up or "COUNTEREXAMPLE" in up:
            return "counterexample"
        if "REACHED" in up:
            return "cover-reached"
        if claims_proof:
            return "proven"
        raise Mislabelled(line)
    
    def naive(line):
        up = line.upper()
        if "CEX" in up or "FAIL" in up:
            return "counterexample"
        if "REACHED" in up and "NOT" not in up:
            return "cover-reached"
        if "PROVEN" in up or "PASS" in up:
            return "inconclusive" if ("TIMEOUT" in up or "UNKNOWN" in up) else "proven"
        return "inconclusive"
    
    CASES = [
        ("property a_range : PROVEN (induction, k=1)", "proven"),
        ("property a_ovf_ign : COUNTEREXAMPLE at step 7", "counterexample"),
        ("property a_data : INCONCLUSIVE (base case passed to depth 12, induction step failed at k=12)", "inconclusive"),
        ("property a_x : PASS (bounded to 12)", "inconclusive"),
        ("property a_y : UNPROVEN (base case passed, induction step FAILED)", "inconclusive"),
        ("cover c_full : REACHED at step 5", "cover-reached"),
        ("cover c_ten : NOT REACHED within 20", "inconclusive"),
        ("cover c_q : UNREACHED within 12", "inconclusive"),
    ]
    REFUSED = ["property a_z : PROVEN (bounded to 12)", "property a_t : PROVEN (timeout after 60s)", "property a_u : PROVEN"]
    
    def check(fn):
        for line, want in CASES:
            assert fn(line) == want, line
        for line in REFUSED:
            try:
                fn(line)
            except Mislabelled:
                continue
            raise AssertionError("accepted: " + line)
    
    check(classify)
    counts = {}
    for line, _ in CASES:
        kind = classify(line)
        counts[kind] = counts.get(kind, 0) + 1
    assert counts == {"proven": 1, "counterexample": 1, "inconclusive": 5, "cover-reached": 1}
    caught = False
    try:
        check(naive)
    except AssertionError:
        caught = True
    assert caught
    print("PASS: report classified 1 proven, 1 counterexample, 5 inconclusive, 1 cover reached; mislabelled lines are refused and the naive parser is caught")

    Report says

    Count as

    Demands next

    Proven with model, assumptions and proof form

    Proven

    Keep the assumption list; rerun on RTL change.

    Counterexample at step K

    Counterexample

    Triage the trace; fix design or model.

    Bounded pass to N

    Inconclusive (bounded to N)

    A sound result, not a proof: justify the bound or strengthen.

    Time-out, unknown, induction step failed

    Inconclusive

    Diagnose; never file as a pass.

    Cover reached at step K

    Witness

    File as exercised.

    Cover not reached within N

    Inconclusive

    Prove unreachable or extend the bound.

    What the review looks for

    • Three separate counts, proven, counterexample, inconclusive, with the depth beside every bounded line; covers counted as reached or inconclusive, never as proven.

    • Every proven property names its model, assumptions and proof form, and a counterexample table gives the earliest failing step per property.

    Verify and debug

    Run the parser over every report before signoff and confirm the counts add up to the property list. Inject a mislabelled line periodically to confirm the check still refuses it. When a count moves between runs, diff the assumption list first: results move when models move.

    Time-out, unknown or bounded pass reported as a pass. Symptom: forty passing lines over stalled coverage. Cause: a parser or a habit that treats anything without FAIL as proven. Fix: three-way results with a bounded-depth column, and a parser that refuses a line that claims a proof beside a bound word. Found by injecting a tiny time limit and reading the summary.

    “What does the report say, exactly?” Answer per property: verdict, proof form or depth, cone size, assumptions, and for failures the earliest failing step. Then the counts. Examiners ask this to see whether you read reports or colours; quote the parser above as the discipline.

    Check yourself A summary shows 40 passes and 0 failures, but 3 lines say timeout. What are the honest counts?

    At most 37 proven, 3 inconclusive and 0 counterexamples: the time-outs are not passes, and the signoff waits for them.

    Check yourself A cover is not reached within depth 12. What may you claim?

    Only that no witness appeared within 12 steps: inconclusive. Unreachable needs an engine proof or a separate argument, not a missed bound.

    Related topics

    • Next: Model Fidelity

    • Later: Debugging Counterexamples

    Previous

    23 / 183

    Next: Model Fidelity and Unsupported Constructs

    Up next

    Up nextModel Fidelity and Unsupported Constructs

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Anatomy of a Formal Harness