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
      • Product Machine and State Correspondence
      • pipe3 and Its Retimed Twin
      • Latency Alignment and Reset
      • FSM Recoding and Clock-Gating Equivalence
    • RTL to Gate: What LEC Assumes
    • ECO and Alternative-Implementation Checks
  • Formal Coverage and Signoff15
  • Methodology and Debug13
  • Interview Prep15
  • Capstone: A Chip-Block Verification Lab24
Loading lesson

←Sequential Equivalence
  1. Topics
  2. Formal Verification
  3. Equivalence Checking
  4. Sequential Equivalence
  5. Latency Alignment and Reset
On this page

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

    Latency Alignment and Reset

    A golden and a revised block agree only after alignment: assert the latency separately, compare after a defined point.

    Why it matters

    A revised block answers one cycle later than the golden model. The miter compares them sample by sample and fails on every cycle, including the cycles where both are correct. The fix is an alignment delay in the harness, but the fix itself can lie: align a constant-output design by the wrong delay and it still passes, because a flat line matches itself at any shift. This lesson shows both failures and the two-property discipline that catches them.

    This lesson has one job: align latencies so the comparison is meaningful, and prove the alignment rather than trusting it.

    The core idea

    Sequential comparison needs three statements, not one. First, the golden latency property: the reference answers exactly L cycles after the stimulus. Second, the revised latency property: the new block answers exactly M cycles after the stimulus. Third, the aligned comparison: golden delayed by the difference agrees with the revised output, compared only after both pipelines have filled and both sides have left reset.

    Comparing before the defined point invites two symmetric mistakes. An alignment that is wrong by construction fails everywhere and is easy to spot. An alignment that is wrong but unnoticed passes on uninteresting stimulus, flat lines and idle cycles, and is dangerous. The latency properties exist to rule out the second mistake: they pin L and M independently of the comparison.

    Reset and initial state belong to the same discipline. The miter starts both sides from the same reset step and compares equivalence from reset, so it says nothing about arbitrary power-up contents. The model is two-state: a register without a reset is an arbitrary 0 or 1, and a difference between two descriptions that only shows as an unknown in simulation is invisible to it. What the comparison can show is a reset-value difference, which appears only in the first cycles; the second example below shows it.

    Worked example: three alignments over short sequences

    The script models a block that answers a pulse. The golden reference answers one cycle after the stimulus, the revised block two cycles after. Comparing the revised output against the golden delayed by one is the correct alignment and passes on every stimulus. Aligning by two fails on six of the nine compared cycles. And on an all-idle stimulus even the wrong alignment passes, which is exactly the trap: the passing verdict says nothing without an active stimulus and a separately asserted latency:

    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
    def run(lat, stim):
        out = [0] * lat + [s for s in stim]
        return out
    
    def compare(rev, gold, delay, cycles, skip):
        bad = []
        for t in range(cycles):
            g = gold[t - delay] if t - delay >= 0 else 0
            if t >= skip and rev[t] != g:
                bad.append(t)
        return bad
    
    stim = [0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]
    gold = run(1, stim)
    rev = run(2, stim)
    assert compare(rev, gold, 1, 12, 3) == []
    assert len(compare(rev, gold, 2, 12, 3)) == 6
    idle_gold = run(1, [0] * 12)
    idle_rev = run(2, [0] * 12)
    assert compare(idle_rev, idle_gold, 2, 12, 3) == []
    assert compare(idle_rev, idle_gold, 5, 12, 3) == []
    assert gold[2] == 1 and rev[3] == 1
    print("PASS: delay-by-1 clean; delay-by-2 fails active, passes idle")

    The last two asserts are the latency evidence in miniature: the golden pulse of cycle 1 appears at cycle 2, the revised at cycle 3. Without those two facts the idle pass would be worthless. In a real harness the same facts are cover properties: a pulse in, the answer out exactly L cycles later, witnessed.

    The second script adds a reset-value mismatch: the revised block resets its output register to 1 where the golden one resets to 0. With the correct alignment the comparison fails only in the first cycles, 0 and 1 in this model, and is clean from the defined point on; a separate reset-value check at cycle 0 catches the cause directly, and the same comparison started late would never see it:

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    def run_reset(lat, stim, reset_value):
        return [reset_value] * lat + list(stim)
    
    def compare(rev, gold, delay, cycles, skip):
        bad = []
        for t in range(cycles):
            g = gold[t - delay] if t - delay >= 0 else 0
            if t >= skip and rev[t] != g:
                bad.append(t)
        return bad
    
    stim = [0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]
    gold = run_reset(1, stim, 0)
    good_rev = run_reset(2, stim, 0)
    bad_rev = run_reset(2, stim, 1)
    assert compare(good_rev, gold, 1, 12, 0) == []
    assert compare(bad_rev, gold, 1, 12, 0) == [0, 1]
    assert compare(bad_rev, gold, 1, 12, 2) == []
    assert bad_rev[0] != gold[0] and good_rev[0] == gold[0]
    print("PASS: reset-value mismatch shows only in cycles 0 to 1; late comparison misses it")

    What the review looks for

    • The comparison names its alignment delay and its start cycle; nothing before the fill point is compared.

    • Each side has its own latency property or cover, proved independently of the comparison.

    • Reset values are defined for both sides: comparison starts after both have left reset, and the first cycles carry a reset-value check instead.

    Verify and debug

    Shift the alignment by one in each direction and confirm the comparison fails on active stimulus: an alignment nobody can break is not constraining anything. Then run idle-only stimulus and confirm the latency covers still reach: if they do not, the pass rests on flat lines. A mismatch confined to the first cycles after reset is a reset-value difference until proven otherwise; check both reset values before touching the alignment.

    Latency mismatch between golden and revised: the miter aligns by the wrong delay and either fails everywhere, which is loud, or passes on quiet stimulus, which is silent. Symptom of the silent kind is a pass with no active witness. Cause is an asserted alignment with no latency evidence. Fix is the three-statement discipline, and it is found by the shift-by-one test: the comparison must fail when the alignment is deliberately wrong. A reset-value mismatch is the early-cycles cousin: the miter reports a difference only in the first cycles, or never, depending on where the comparison starts. Fix is to define the same reset sequence for both models and compare only after the defined point, with a separate reset-value check.

    If asked how to compare blocks with different latencies, answer with the three statements: golden latency, revised latency, aligned comparison after the fill point. Then volunteer the trap: a wrong delay can still pass on idle stimulus, which is why the latency is asserted separately.

    Check yourself The aligned comparison passes but the revised latency cover never reaches. What is the verdict worth?

    Nothing yet. The comparison may be passing on idle cycles. Reach the latency cover with active stimulus first; only then does the agreement mean the blocks match on real traffic.

    Related topics

    • pipe3 and Its Retimed Twin

    • Next: FSM Recoding and Clock-Gating Equivalence

    • Synthesis: Reset, Initial State and Equivalence

    Previous

    109 / 183

    Next: FSM Recoding and Clock-Gating Equivalence

    Up next

    Up nextFSM Recoding and Clock-Gating Equivalence

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Product Machine and State Correspondence