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
    • Combinational Equivalence and the Miter
    • Sequential Equivalence
    • RTL to Gate: What LEC Assumes
      • What LEC Assumes
      • Key Points and Unmapped State
      • Retiming, Gating and the Limits of LEC
    • ECO and Alternative-Implementation Checks
  • Formal Coverage and Signoff15
  • Methodology and Debug13
  • Interview Prep15
  • Capstone: A Chip-Block Verification Lab24
Loading lesson

←RTL to Gate: What LEC Assumes
  1. Topics
  2. Formal Verification
  3. Equivalence Checking
  4. RTL to Gate: What LEC Assumes
  5. What LEC Assumes
On this page

    Part 6 of 10, lesson 9 of 14Part 6 of 10/Equivalence Checking/Lesson 9 of 14All levels

    What LEC Assumes

    One-to-one state correspondence, quiet scan, consistent constants and black boxes, the same reset: each with its false result.

    Why it matters

    A netlist passes against the RTL on Friday and the tester finds a flop that never resets on Monday. The comparison tied reset to the value the synthesis script declared, while the tester released it the other way, so the two models agreed with each other and the silicon, driven by the tester, did not. Every assumption below has a story like that: a pass that was true under the setup and false outside it.

    This lesson has one job: state the four assumptions a gate-level pass rests on, and the false pass or false fail each one produces when broken.

    The core idea

    One-to-one logic equivalence assumes a correspondence between every sequential element: same encoding, so each RTL flop has exactly one gate-level partner holding the same value in the same cycle. It assumes scan and test logic disabled, so the compared paths are the mission paths. It assumes consistent constants and black boxes: tie-offs, parameter values and undriven-box behaviour identical on both sides. And it assumes the same reset: both sides leave the same values from the same sequence. Retiming and some clock gating break the first assumption structurally, which is why they need sequential methods or dedicated modes rather than the plain comparison.

    Assumption

    Broken how

    False result

    One-to-one state, same encoding

    Retimed or recoded netlist

    False fail: registers match nowhere on a correct design

    Scan and test disabled

    Scan left enabled on one side

    False pass or false fail: test paths compared instead of mission paths

    Consistent constants and black boxes

    Tie-off differs between setups, or a box is abstracted differently per side

    False fail on every vector, or false pass if the differing constant masks a bug or the setup forces the box outputs to agree

    Same reset

    Different reset values or sequences

    False fail in early cycles, or false pass if reset masks the divergence

    Worked example: a state-mapping checker

    The script below models the first assumption as a checker over two flop-name lists. It pairs by name, reports unmapped and extra registers, and flags width mismatches. The clean pair passes. Then an injected extra gate-level register with no RTL partner is reported as unmapped, proving the checker can fail:

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    def check_mapping(rtl, gate):
        rtl_names = {n for n, w in rtl}
        gate_names = {n for n, w in gate}
        rtl_w = dict(rtl)
        gate_w = dict(gate)
        unmapped = sorted(gate_names - rtl_names)
        missing = sorted(rtl_names - gate_names)
        widths = sorted(n for n in rtl_names & gate_names if rtl_w[n] != gate_w[n])
        return unmapped, missing, widths
    
    RTL = [("ctrl", 8), ("status", 2), ("data", 8), ("cnt", 4)]
    GATE = [("ctrl", 8), ("status", 2), ("data", 8), ("cnt", 4)]
    assert check_mapping(RTL, GATE) == ([], [], [])
    GATE_X = GATE + [("scan_shadow", 1)]
    u, m, w = check_mapping(RTL, GATE_X)
    assert u == ["scan_shadow"] and m == [] and w == []
    GATE_W = [("ctrl", 8), ("status", 2), ("data", 7), ("cnt", 4)]
    u2, m2, w2 = check_mapping(RTL, GATE_W)
    assert w2 == ["data"]
    print("PASS: clean pair maps; extra register and width change reported")

    What the review looks for

    • The result names all four assumptions with their concrete values: which scan mode, which constants, which reset sequence.

    • Retimed or recoded blocks are absent from the one-to-one run: they appear under sequential equivalence instead.

    • Unmapped registers are classified, never waived silently: design change, transformation artefact, or setup error.

    Verify and debug

    Rerun the comparison once per assumption flipped: scan enabled, one constant changed, a shorter reset. Each run must fail or be explained; a run that still passes under a broken assumption is not checking what you think. Keep the assumption list beside the verdict in the signoff, not in the script header.

    State mapping incomplete after retiming or re-encoding: the one-to-one assumption is broken, because the transformation moved or recoded registers, and the run reports non-equivalence on a design that is correct. Symptom is a flood of unmapped or mismatching state, often failing from the first cycle. Cause is a setup that still assumes every register has a partner of the same encoding. Fix is to provide the key point mapping, compare at stable points, and prove the encoding relation separately; it is found by checking whether the failing registers are ones the transformation touched.

    If asked what breaks a gate-level pass, answer with the table: retiming breaks correspondence, scan pollutes the paths, constants and black boxes must match, reset must match. Then name the escape hatch: dedicated modes or sequential equivalence for the first row.

    Check yourself The comparison fails on every vector with all bits differing. Which assumption do you check first?

    Constants and tie-offs: a setup difference affects every vector, while a logic difference is usually confined to some corner. Align the constants and rerun before reading any cone.

    Related topics

    • Next: Key Points and Unmapped State

    • Synthesis: Key Points and Black Boxes

    • Formal glossary

    Previous

    111 / 183

    Next: Key Points and Unmapped State

    Up next

    Up nextKey Points and Unmapped State

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Retiming, Gating and the Limits of LEC