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

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • Reading Paths
  • Concept Map
  • Meet DCRouter
  • Glossary
  • Part 0: What Verification Is8
  • Part 1: What Can Go Wrong11
  • Part 2: Specifications as Checkable Rules8
  • Part 3: Observability and Controllability7
  • Part 4: Stimulus11
  • Part 5: Checking11
  • Part 6: Coverage10
  • Part 7: Formal and Simulation10
  • Part 8: Verification Levels and Reuse8
  • Part 9: Planning and Risk9
  • Part 10: Emulation and Prototyping8
  • Part 11: Post-Silicon Validation8
  • Part 12: Bug Economics8
  • Part 13: Debug7
  • Part 14: Sign-Off7
  • Part 15: Verification in Context8
    • Functional Safety Verification
    • Security Verification
    • Low-Power Verification Strategy
    • CDC and RDC in the Plan
    • Verifying Processors
    • Verifying AI Accelerators
    • Verifying Configurable IP
    • Drills: Verification in Context
  • Part 16: Case Studies5
  • Part 17: Capstones5
  • Part 18: Interview Preparation6
Loading lesson

‹Part 15: Verification in Context
  1. Topics
  2. First Principles of Verification Strategy
  3. Part 15: Verification in Context
  4. Verifying AI Accelerators

Part 15 · Verification in Context · Principal (P)

Verifying AI Accelerators

AI accelerators compute in floating point and in reduced precision, in whatever order their hardware finds fastest, so their results legitimately differ from a reference model's. The oracle must compare within a tolerance that is tight enough to catch bugs and loose enough to accept correct rounding. A runnable model showing an exact check rejecting every correct result, then a scaled tolerance, then the layers of checking above it.

On this page

    Note

    Level: Principal (P) · Answers: What changes for safety, security, processors and AI hardware?

    Before this: Verifying Processors, Reference Model Depth

    DCRouter's scoreboard compared packets bit for bit: a flit was right or wrong. An AI accelerator multiplies matrices in float32 or smaller formats, adding thousands of products in a tree because that is fast in hardware. Its reference model, written in Python, adds them in a loop in double precision. The two will almost never agree to the last bit, and both are correct.

    How do you check an accelerator whose correct answers are not exact?

    The obvious answer, and why it breaks

    The obvious answer is to compare results with the golden model bit for bit, as with DCRouter. Floating-point addition rounds at every step, so it is not associative: the same numbers summed in a different order give a slightly different result (fact V15), and a reference model usually also computes in higher precision than the hardware. An exact check therefore fails correct hardware, and a team that keeps seeing such failures learns to ignore them, or loosens the check until it catches nothing.

    Build it: exact versus scaled tolerance

    An illustrative accelerator computes 64-element dot products in float32 with tree reduction; the golden model uses double precision in a loop. A buggy version drops the last product in one of every 256 dot products. Both are checked exactly and with a tolerance that scales with the size of the terms.

    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
    """AI accelerators: checking floating-point results against a golden model.
    
    An accelerator computes 64-element dot products in float32, accumulating in a tree (pairs,
    then pairs of pairs), as hardware often does. The golden model computes the same dot product
    in double precision in a simple loop. Two checks compare 2,000 random dot products:
      exact       results must be bit-identical
      tolerance   |hw - golden| <= 1e-5 * (sum of |a_i * b_i|) + 1e-30, a relative bound that
                  scales with the size of the terms, as float32 accumulation error does
    The same checks then run on a buggy accelerator that drops the last product in 1 of every 256
    dot products (an illustrative control bug).
    """
    import random
    import struct
    
    rng = random.Random(17)
    f32 = lambda x: struct.unpack("f", struct.pack("f", x))[0]
    
    def hw_dot(a, b, bug=False, k=0):
        terms = [f32(f32(x) * f32(y)) for x, y in zip(a, b)]
        if bug and k % 256 == 255:
            terms[-1] = 0.0
        while len(terms) > 1:                                 # tree reduction, rounding each add to float32
            terms = [f32(terms[i] + terms[i + 1]) for i in range(0, len(terms), 2)]
        return terms[0]
    
    def golden(a, b):
        return sum(f32(x) * f32(y) for x, y in zip(a, b))
    
    vectors = [([rng.uniform(-1, 1) for _ in range(64)], [rng.uniform(-1, 1) for _ in range(64)]) for _ in range(2000)]
    for name, bug in [("correct accelerator", False), ("buggy accelerator", True)]:
        exact_fail = tol_fail = 0
        for k, (a, b) in enumerate(vectors):
            h, g = hw_dot(a, b, bug, k), golden(a, b)
            scale = sum(abs(f32(x) * f32(y)) for x, y in zip(a, b))
            exact_fail += (h != g)
            tol_fail += abs(h - g) > 1e-5 * scale + 1e-30
        print(f"{name:20s} exact check fails {exact_fail:4d} of 2000; tolerance check fails {tol_fail:3d} of 2000")
        if not bug:
            ok_exact, ok_tol = exact_fail, tol_fail
        else:
            bug_tol = tol_fail
    assert ok_exact > 1500 and ok_tol == 0 and bug_tol > 0
    print("PASS: an exact check fails every correct result; a scaled tolerance passes them all and still catches the dropped products")

    It prints:

    Diagram
    correct accelerator  exact check fails 2000 of 2000; tolerance check fails   0 of 2000
    buggy accelerator    exact check fails 2000 of 2000; tolerance check fails   7 of 2000
    PASS: an exact check fails every correct result; a scaled tolerance passes them all and still catches the dropped products

    How to read it: the exact check fails all 2,000 results of the correct accelerator, so it carries no information: correct and buggy designs look the same. The scaled tolerance passes every correct result and fails exactly the 7 dot products where a product was dropped. The scale matters: an absolute tolerance would be too loose for small results and too tight for large ones, because rounding error grows with the magnitude of the terms being added.

    The idea: layered oracles

    Level

    Oracle

    Catches

    Arithmetic units

    Bit-exact against a reference for one operation (IEEE 754 defines each rounded result exactly)

    Wrong rounding, special values (NaN, infinity, subnormals), format conversion

    Kernels (matrix multiply, convolution)

    Golden model within a scaled tolerance, or bit-exact against a model that reproduces the hardware's order

    Dropped, repeated or misaddressed data; tiling and control bugs

    Layers and whole networks

    Accuracy on a dataset close to the reference framework's

    Systematic precision loss, quantisation errors, scheduling bugs

    Performance

    Throughput and utilisation against the architecture model

    Stalls, poor data reuse, bandwidth bottlenecks (lesson 8.7)

    A useful second reference is a bit-accurate model that reproduces the hardware's exact order and formats: then the RTL can be compared bit for bit again, and the separate question of whether that order is accurate enough is answered once, against the high-precision model.

    What else changes

    • The input space is data: random values miss the distributions of real weights and activations; include real tensors, extreme magnitudes, zeros, denormals and NaNs.

    • Control is most of the bug risk: tiling, addressing, synchronisation and scheduling between engines; these produce dropped or repeated data that a tolerance must be tight enough to see.

    • Compiler and hardware are verified together: the same network compiled differently exercises different schedules.

    • Workloads are long: whole networks run on emulation (Part 10).

    How real teams verify accelerators

    Practice

    Purpose

    Bit-exact arithmetic-unit verification, often formal

    Every rounding and special case right

    Bit-accurate model of the datapath order

    Exact comparison possible at kernel level

    Tolerances derived from error analysis, not tuned to pass

    Checks that still catch bugs

    Network accuracy runs on emulation

    Real workloads end to end

    What breaks

    A team (illustrative) set its tolerance by raising it until a failing regression passed. The failures had been caused by an addressing bug that occasionally read a neighbouring tile's data, whose values were close in magnitude; the loosened tolerance absorbed it. A tolerance should be derived from the formats and accumulation length, then validated by planting bugs, as in the model above, before it is trusted.

    Why this matters

    Principal lens. Layer the oracles: bit-exact arithmetic units, kernels within a derived tolerance or bit-exact against a model of the hardware's order, and network accuracy on real workloads. Never tune a tolerance to make failures go away; derive it, and prove it still catches planted bugs.

    Interview

    Asked: "How do you check an AI accelerator's results?"

    Weak answer: Compare against the Python model.

    Strong answer: Floating-point addition isn't associative, so a correct accelerator that sums in a tree in float32 won't match a loop-based, higher-precision model bit for bit. I'd layer the oracles: arithmetic units bit-exact against IEEE 754, including special values; kernels within a tolerance derived from the format and accumulation length and scaled by the magnitude of the terms, or bit-exact against a model that reproduces the hardware's order; networks by accuracy on real data. In a small model, an exact check failed all 2,000 correct dot products, while a scaled tolerance passed them all and caught every dropped product. I'd validate any tolerance with planted bugs, never loosen it until tests pass.

    Follow-ups: (1) Why must the tolerance scale with the terms? (2) What is a bit-accurate model?

    Check yourself Why is an exact check useless for the correct accelerator in the model?

    It fails every result, so correct and buggy designs look the same; it carries no information.

    Check yourself Why is loosening a tolerance until a regression passes dangerous?

    The failures may be real bugs whose errors are small, such as reading similar neighbouring data; the loosened check absorbs them.

    Key takeaways

    • Correct floating-point hardware differs from a golden model; exact checks fail it.

    • Use tolerances derived from the arithmetic and scaled to the terms, validated with planted bugs.

    • Layer oracles: bit-exact units, tolerant kernels, network accuracy.

    Keep going

    Next: Lesson 15.7, Verifying Configurable IP. Verifying a design that is really thousands of designs.

    Related topics

    • Part 15 overview: Verification in Context

    Previous

    142 / 160

    Next: Verifying Configurable IP

    Up next

    Up nextVerifying Configurable IP

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Functional Safety Verification
    • Security Verification
    • Low-Power Verification Strategy