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
    • Directed Tests
    • Why Random Works
    • Constrained Random
    • Distributions and Bias
    • The Long Tail
    • Scenarios and Layered Stimulus
    • Error Injection
    • Timing and Back-Pressure
    • Seeds and Regressions
    • Hunting the Zoo with Random
    • Drills: Stimulus
  • 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
  • Part 16: Case Studies5
  • Part 17: Capstones5
  • Part 18: Interview Preparation6
Loading lesson

‹Part 4: Stimulus
  1. Topics
  2. First Principles of Verification Strategy
  3. Part 4: Stimulus
  4. The Long Tail

Part 4 · Stimulus · Senior (S)

The Long Tail

Uniform random stimulus finds common cases quickly and rare corners almost never. The arithmetic of rare events (1/p trials on average, 1 − (1 − p)^N chance in N), a DCRouter corner that random misses, and how biasing distributions changes the odds.

On this page

    Note

    Level: Senior (S) · Answers: How do we drive the design into the states that matter?

    Before this: Part 4 overview, You Cannot Test Everything

    A team's random regression runs 100,000 packet groups through DCRouter every night, and has done so for a month. Every common case has been hit thousands of times. Then a reviewer asks: has all four inputs sending maximum-length packets to the same output at once ever happened? The answer, worked out on a whiteboard: in any one night, almost certainly not, and over the whole month, only about three chances in five. Random testing is very good at the middle of the distribution and very bad at its tail.

    How long does random stimulus take to reach a rare corner, and what can be done about it?

    The obvious answer, and why it breaks

    The obvious belief is that random testing, run long enough, eventually covers everything, so a big enough regression catches every bug. "Eventually" hides the problem. A corner needs several independent conditions in the same cycle, and the probabilities of independent conditions multiply. Four conditions of 1 in 60 each give 1 in 13 million. The waiting time grows as fast as the corner shrinks, and real bugs live disproportionately in these corners, because the common cases were already exercised by designers' own tests.

    The idea: rare events follow simple arithmetic

    If a corner has probability p per trial, and trials are independent (fact M3):

    E[trials to first hit]=p1​P(at least one hit in N)=1−(1−p)N
    • Expected wait 1/p: a corner of one in a million needs a million trials on average, and often several times more.

    • Confidence needs more: to be 95% sure of at least one hit you need about 3/p trials, since (1 − p)^(3/p) ≈ e^(−3) ≈ 0.05.

    • Conditions multiply: k independent conditions of probability q each give p = q^k, so each extra condition divides the chance again.

    Build it: a DCRouter corner

    Packets in this model are uniform random: each input picks one of 4 outputs and one of 15 lengths with equal probability, and the model treats a "packet group" as one header arriving on each input at once (illustrative). It computes three corners of increasing rarity, checks the formula by Monte Carlo, then repeats the hardest corner with the length biased so that 15 is chosen 20% of the time.

    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
    """The long tail: how long uniform random stimulus takes to hit a rare corner.
    
    A corner is a combination of conditions that must hold in the same cycle. For DCRouter,
    "all four inputs present a header for the same output, each with the maximum length 15"
    needs four independent choices to line up. With uniform random packets each input picks
    the same output with probability 1/4 and length 15 with probability 1/15, so (illustrative,
    assuming all four headers arrive together) p = (1/4 * 1/15)^4 relative to output 0, times 4
    outputs. Part 1 computes p for that corner and for two simpler ones, the expected number of
    trials 1/p, and the chance of at least one hit in a regression of N trials, 1 - (1 - p)^N.
    Part 2 checks the formula with a Monte Carlo run for the two-input corner. Part 3 shows what
    biasing does: choosing length 15 with probability 0.2 instead of 1/15 multiplies p by 3^4 = 81.
    """
    import random
    
    corners = {
        "len 15 on one input":                 1 / 15,
        "two inputs, same output, both len 15": 4 * (1 / 4 * 1 / 15) ** 2,
        "four inputs, same output, all len 15": 4 * (1 / 4 * 1 / 15) ** 4,
    }
    trials = [1e3, 1e4, 1e5, 1e6, 1e7]
    print("trials (packet groups):           " + " ".join(f"{int(t):>9d}" for t in trials))
    probs = {}
    for name, p in corners.items():
        probs[name] = [1 - (1 - p) ** t for t in trials]
        print(f"{name:34s}" + " ".join(f"{v:9.3f}" for v in probs[name]) + f"   (p = {p:.2e}, 1/p = {1 / p:,.0f})")
    
    rng = random.Random(3)
    p2 = corners["two inputs, same output, both len 15"]
    runs, n = 4000, 1000
    hits = sum(any(rng.random() < p2 for _ in range(n)) for _ in range(runs)) / runs
    print(f"Monte Carlo, two-input corner, {n} trials, {runs} runs: hit rate {hits:.3f} (formula {1 - (1 - p2) ** n:.3f})")
    
    biased = 4 * (1 / 4 * 0.2) ** 4
    bprobs = [1 - (1 - biased) ** t for t in trials]
    print(f"{'four-way corner, len 15 biased 20%':34s}" + " ".join(f"{v:9.3f}" for v in bprobs) + f"   (p = {biased:.2e}, 1/p = {1 / biased:,.0f})")
    print(f"biasing the length alone makes the four-way corner {biased / corners['four inputs, same output, all len 15']:.0f} times more likely")
    
    assert abs(hits - (1 - (1 - p2) ** n)) < 0.04
    assert probs["four inputs, same output, all len 15"][2] < 0.05 and bprobs[2] > 0.9
    print("PASS: in 100,000 trials uniform random has a 3% chance of the four-way corner; biasing the length raises it to 92%")

    It prints:

    Diagram
    trials (packet groups):                1000     10000    100000   1000000  10000000
    len 15 on one input                   1.000     1.000     1.000     1.000     1.000   (p = 6.67e-02, 1/p = 15)
    two inputs, same output, both len 15    0.671     1.000     1.000     1.000     1.000   (p = 1.11e-03, 1/p = 900)
    four inputs, same output, all len 15    0.000     0.003     0.030     0.266     0.954   (p = 3.09e-07, 1/p = 3,240,000)
    Monte Carlo, two-input corner, 1000 trials, 4000 runs: hit rate 0.663 (formula 0.671)
    four-way corner, len 15 biased 20%    0.025     0.221     0.918     1.000     1.000   (p = 2.50e-05, 1/p = 40,000)
    biasing the length alone makes the four-way corner 81 times more likely
    PASS: in 100,000 trials uniform random has a 3% chance of the four-way corner; biasing the length raises it to 92%
    The model's numbers: the two-input corner is certain by ten thousand trials; the four-way corner has a 3% chance in a 100,000-trial regression under uniform stimulus, and 92% once the length is biased.

    How to read it: the two-input corner (1 in 900) is hit almost at once. The four-way corner (1 in 3.2 million) needs ten million trials for a 95% chance; the nightly 100,000 gives 3%, and even a month of nightly runs (about three million trials) gives only about three chances in five. Changing nothing but the length distribution, so that 15 is chosen 20% of the time instead of 1 in 15, multiplies the chance by 3^4 = 81 and turns the same nightly run into a 92% hit. The Monte Carlo line confirms the formula: 0.663 measured against 0.671 predicted.

    What to do about the tail

    Approach

    How it reaches the corner

    Cost

    Bias the distributions

    Weight boundary values (minimum, maximum, zero, full) so they appear far more often than uniform

    Less uniform coverage of the middle; must keep some breadth

    Directed or scenario tests

    Construct the corner on purpose

    Only corners someone thought of

    Coverage-driven stimulus

    Measure which bins are unhit and steer randomness towards them (Part 6)

    Needs a coverage model and feedback

    Reduce the number of conditions

    Make the corner easier to reach: smaller FIFOs, fewer credits, fewer ports in a test configuration

    The test configuration must still be legal and representative

    Formal

    Proves the property for every combination, including the corner (Part 7)

    Block-sized designs only

    In SystemVerilog, biasing is a constraint (fact V1). For DCRouter's length field:

    design.sv
    1
    2
    3
    4
    5
    6
    // snippet: weighting the boundary lengths of a DCRouter packet
    class dcr_packet;
      rand bit [3:0] len;
      rand bit [1:0] dst;
      constraint c_len { len dist { 1 := 20, 15 := 20, [2:14] :/ 60 }; }   // 1 and 15 each 20%; :/ shares 60 across the range
    endclass

    The dist weights make each boundary length appear 20% of the time while the 13 middle values share the remaining 60%.

    How real teams do it

    Practice

    Effect on the tail

    Weighted dist constraints on boundary values (fact V1)

    Moves probability from the middle to the corners

    Test configurations with small resources

    Small FIFOs and few credits make full, empty and back-pressure corners common

    Coverage crosses on combined conditions

    Make the multi-condition corner visible as an unhit bin, so someone acts on it

    Formal on the block that owns the corner

    Removes the dependence on luck for control logic

    What breaks

    A team (illustrative) shipped a switch whose arbiter mis-counted when all ports issued maximum bursts in the same cycle. Their random regression had run for months with uniform burst lengths and uniform port choice. Afterwards they computed the corner's probability under their stimulus: about one in two hundred million per cycle group. A coverage cross of "ports requesting × burst length at maximum" had never been written, so nobody saw the hole. Adding the cross and weighting maximum bursts made the corner appear in every nightly run.

    Why this matters

    Senior lens. For every corner in the verification plan, estimate its probability under the actual stimulus before trusting random testing to reach it. If 1/p is near or above your regression size, random will not find it: bias the distribution, shrink the configuration, add a coverage cross that makes the hole visible, or prove the property formally. "We run millions of tests" is not an argument until it is compared with 1/p.

    Interview

    Asked: "How long does it take random testing to hit a one-in-a-million case?"

    Weak answer: About a million tests.

    Strong answer: A million on average, since the expected wait for an event of probability p is 1/p, but to be 95% sure of at least one hit you need about three million, because (1 − p)^N ≈ e^(−pN) and you need pN ≈ 3. And most interesting corners are several independent conditions together, so their probabilities multiply and get rare very fast. Instead of running longer I'd bias the distributions towards boundary values with dist constraints, add coverage crosses so the corner shows as a hole, shrink resources in a test configuration, or prove that block formally.

    Follow-ups: (1) What does biasing cost you? (2) How would you know the corner was never hit?

    Check yourself A corner has p = 10^−5 per trial. How many trials give a 95% chance of at least one hit?

    About 3/p = 300,000, since (1 − 10^−5)^300,000 ≈ e^−3 ≈ 0.05.

    Check yourself Three independent conditions each happen 1 time in 20. How rare is the corner where all three coincide?

    1 in 20^3 = 8,000 trials on average.

    Check yourself Why can't you bias every field to its boundaries?

    The middle of each range would then be rarely tested, and many bugs need ordinary values in unusual combinations; biasing must keep breadth while lifting the corners.

    Key takeaways

    • A corner of probability p takes 1/p trials on average and about 3/p for 95% confidence.

    • Independent conditions multiply, so multi-condition corners are far rarer than any single condition.

    • Bias distributions, shrink configurations, add coverage crosses or prove formally, instead of running longer.

    Keep going

    Next: Lesson 4.6, Scenarios and Layered Stimulus. Building realistic traffic from small, reusable pieces.

    Related topics

    • Part 4 overview: Stimulus

    • SystemVerilog course: Constraint Operators

    Previous

    44 / 160

    Next: Scenarios and Layered Stimulus

    Up next

    Up nextScenarios and Layered Stimulus

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Directed Tests
    • Why Random Works
    • Constrained Random