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
  • Part 16: Case Studies5
  • Part 17: Capstones5
    • Write the Plan
    • Hunt the Zoo
    • Review a Plan
    • The Sign-Off Board
    • Debug the Regression
  • Part 18: Interview Preparation6
Loading lesson

‹Part 17: Capstones
  1. Topics
  2. First Principles of Verification Strategy
  3. Part 17: Capstones
  4. Hunt the Zoo

Part 17 · Capstones · Senior (S)

Hunt the Zoo

Capstone: find all 24 DCRouter bugs with the cheapest mix of techniques. A new targeted directed bench is measured against the Bug Zoo, every combination of the course's ten testbenches and proofs is searched with illustrative costs, and the cheapest complete mix turns out not to be the testbench that caught everything. Then the catch: you could only write the cheap mix because the expensive one showed you where to look.

On this page

    Note

    Level: Senior (S) · Answers: Can you apply all of it?

    Before this: Signing Off DCRouter

    The covered hunt of lesson 6.9 catches all 24 planted bugs. It is also the most expensive testbench in the course: random stimulus, assertions, an arbitration checker, a coverage model and a phase written from its holes. A manager with half the budget asks: what is the cheapest mix of techniques that still catches everything?

    Your task: choose the cheapest set of testbenches and proofs that catches all 24 DCRouter bugs, and say what that answer hides. Try it from the matrix in lesson 14.6 before reading on.

    A new candidate: the targeted bench

    Two bugs, BUG_16 and BUG_23, were caught only by the covered hunt, by its phase written from coverage holes. That phase needs no random stimulus at all. Taken out as a directed bench of its own:

    tb.sv
    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
    // uses: dcrouter
    // Capstone 17.2: the register and port checks that the coverage model's holes asked for,
    // written as a cheap directed bench with no random stimulus: reset value of CTRL, STATUS and
    // an unmapped address, clear each counter and re-read all of them, saturate an error counter,
    // and disable each port while offering it a packet.
    module tb;
      `include "dcr_env.svh"
      initial begin
        reset_dut();
        check_reg(8'h00, 32'h3F, "CTRL after reset (R11)");
        apb_rd(8'h04);                                           // STATUS
        apb_rd(8'h40);                                           // unmapped (R12)
        if (rd_err !== 1'b1) fail("R12: no pslverr for unmapped address 0x40");
        for (int i = 0; i < 4; i++) queue_pkt(i, (i + 1) % 4, 0, 2);     // one good packet per input
        for (int i = 0; i < 4; i++) queue_pkt(i, i, 0, 2, 1);            // one fault per input
        wait_drain();
        for (int k = 0; k < 4; k++) begin                        // clear each counter; only that one clears (R9, R10)
          apb_wr(8'h10 + 8'(4 * k), 0);  bad_pkts[k] = 0;
          apb_wr(8'h20 + 8'(4 * k), 0);  got_pkts[k] = 0;
          for (int j = 0; j < 4; j++) begin
            check_reg(8'h10 + 8'(4 * j), bad_pkts[j], $sformatf("ERR_CNT%0d after clearing ERR_CNT%0d", j, k));
            check_reg(8'h20 + 8'(4 * j), got_pkts[j], $sformatf("PKT_CNT%0d after clearing PKT_CNT%0d", j, k));
          end
        end
        for (int n = 0; n < 260; n++) queue_pkt(2, 3, 0, 1, 1);  // saturate ERR_CNT2 (R9)
        wait_drain(20000);
        check_reg(8'h18, 255, "ERR_CNT2 after 260 faults");
        for (int k = 0; k < 4; k++) begin                        // a disabled port accepts nothing (R1)
          apb_wr(8'h00, 32'h30 | (32'hF & ~(32'h1 << k)));
          queue_pkt(k, (k + 1) % 4, 0, 2);
          repeat (30) @(posedge clk);
          if (pending() != 4) fail($sformatf("R1: disabled port %0d accepted flits", k));
          apb_wr(8'h00, 32'h3F);
          wait_drain();
        end
        finish("targeted register and port bench");
      end
    endmodule

    Run against the Bug Zoo it catches:

    Diagram
    clean design: PASS
      BUG_1  caught  ERROR @1805: out3: unexpected flit 005d
      BUG_2  caught  ERROR @255: out0: unexpected flit 0580
      BUG_8  caught  ERROR @155: out0: out_err 1 on flit 0580, expected 0
      BUG_11 caught  ERROR @465: PKT_CNT1 after clearing PKT_CNT0: read 0, expected 2
      BUG_14 caught  ERROR @495: ERR_CNT2 after clearing ERR_CNT0: read 2, expected 1
      BUG_15 caught  ERROR @11985: ERR_CNT2 after 260 faults: read 4, expected ff
      BUG_16 caught  ERROR @1485: PKT_CNT3 after clearing PKT_CNT3: read 2, expected 0
      BUG_17 caught  ERROR @55: CTRL after reset (R11): read 37, expected 3f
      BUG_18 caught  ERROR @115: R12: no pslverr for unmapped address 0x40
      BUG_19 caught  ERROR @435: ERR_CNT1 after clearing ERR_CNT0: read 0, expected 1
      BUG_21 caught  ERROR @63725: 4 flits still pending after 5000 cycles (lost or stuck)
      BUG_23 caught  ERROR @12315: R1: disabled port 0 accepted flits
      BUG_24 caught  ERROR @205: out0: unexpected flit c581

    13 of 24, including BUG_16 and BUG_23, for a fraction of the covered hunt's machinery. It misses everything that needs traffic patterns: arbitration, back-pressure, and sleep in the middle of traffic (BUG_20, 22).

    Costs (illustrative)

    Testbenches share parts, so cost is counted per component: a mix pays for each component once, however many of its benches use it. The numbers are illustrative engineer-days; what matters is the reasoning, which the page recomputes from them.

    Component

    Effort (days)

    Shared environment: drivers, sinks, scoreboard, APB tasks (lesson 4.1)

    4

    Directed tests (lesson 4.1)

    2

    Error injection (lesson 4.7)

    2

    Back-pressure and timing variation (lesson 4.8)

    1

    Constrained-random hunt (lesson 4.10)

    3

    Pin-level assertions (lesson 5.3)

    2

    Arbitration checker (lesson 5.10)

    3

    Coverage model (lesson 6.9)

    3

    Phase written from coverage holes (lesson 6.9)

    2

    Designer formal properties and harness (lesson 7.9)

    4

    Sign-off gap bench (lesson 14.6)

    2

    Targeted register and port bench (this lesson)

    2

    Testbench or proof

    Bugs caught

    Cost alone (days)

    Directed

    10

    6

    Error injection

    13

    6

    Back-pressure

    12

    5

    Random hunt

    15

    7

    SVA hunt

    15

    9

    Checked hunt

    18

    12

    Covered hunt

    24

    17

    Formal proof

    9

    4

    Gap bench

    6

    6

    Targeted bench

    13

    6

    The search

    With ten candidates there are 1,023 non-empty mixes; the page checks all of them for missed bugs and cost.

    Mix

    Missed

    Cost (days)

    Covered hunt alone

    none

    17

    Checked hunt + Targeted bench

    none

    14

    Cheapest complete mix: Random hunt + Formal proof + Targeted bench

    none

    13

    Cheapest without formal: Checked hunt + Targeted bench

    none

    14

    Cheapest without the targeted bench: Covered hunt

    none

    17

    How to read it: the cheapest complete mix, Random hunt + Formal proof + Targeted bench, costs 13 days against 17 for the covered hunt (Error injection + Back-pressure + Formal proof + Targeted bench ties at the same cost; the search prefers fewer runs). Formal takes over the arbitration bugs (BUG_5, 6, 7) that otherwise need the arbitration checker; the targeted bench takes the register and port bugs; the random hunt takes the traffic bugs. Without formal, the cheapest is Checked hunt + Targeted bench at 14 days. Without the targeted bench, nothing cheaper than the covered hunt catches BUG_16 and BUG_23. Different illustrative costs would change the winner, but not the shape: a mix of techniques with different pools beats one testbench that does everything.

    What the answer hides

    • Hindsight: the targeted bench was written from the covered hunt's coverage holes. Without the coverage model, nobody would have known that counter clears and disabled ports were untested.

    • Planted bugs are not real bugs: the mix is cheapest for these 24. Unknown bugs need breadth, which random stimulus and coverage provide and directed tests do not (lesson 4.2).

    • Single points of failure: in the cheapest mix 14 of the 24 bugs are caught by exactly one run; a regression change that weakens one bench lets them escape (lesson 14.6).

    • Formal's scope: the proofs cover the FIFOs, arbiter and credits under their assumptions; if the assumptions are wrong, the arbitration bugs have no other net in this mix (lesson 7.4).

    The capstone's real answer is therefore two answers: the cheapest mix for the bugs you know, and the investment (coverage, plan, independent checks) that finds the bugs you do not.

    Why this matters

    Senior lens. Optimise the mix of techniques by their pools, not by adding more of one: cheap directed tests for registers and configuration, random stimulus for traffic, formal for control logic with clean properties. But keep the instruments, coverage and the plan, that tell you where the cheap tests need to go; they are what made the cheap mix possible.

    Interview

    Asked: "With half the budget, how would you still find all the planted bugs?"

    Weak answer: Run the best testbench with fewer seeds.

    Strong answer: Use techniques whose pools complement each other. On the course's router, a cheap directed bench for registers and port enables caught 13 of 24 bugs including the two only the expensive covered hunt had found; formal on the arbiter and FIFOs took the arbitration bugs; a plain random hunt took the traffic bugs. Searching every combination with illustrative costs, that mix was cheaper than the one testbench that caught everything. The caveat: the directed bench was written from the coverage holes, so the coverage model still earned its cost; and the cheap mix leaves most bugs with a single net.

    Follow-ups: (1) What does the cheapest mix risk? (2) How would you choose costs in a real project?

    Check yourself Why does every complete mix need either the covered hunt or the targeted bench?

    BUG_16 and BUG_23 are caught by no other run: no other bench clears every counter and re-reads them, or offers a packet to a disabled port.

    Check yourself Why is the cheapest mix misleading as a plan for the next design?

    It was chosen knowing where the bugs were; for unknown bugs you need the breadth of random stimulus and the coverage model that found the holes in the first place.

    Key takeaways

    • A targeted directed bench caught 13 of 24 bugs, including the two only the covered hunt had found.

    • Searching every mix found a cheaper complete combination than the testbench that catches everything.

    • The cheap mix was only possible because coverage showed where to look.

    Keep going

    Next: Lesson 17.3, Review a Plan. Find the flaws in someone else's plan.

    Related topics

    • Part 17 overview: Capstones

    Previous

    151 / 160

    Next: Review a Plan

    Up next

    Up nextReview a Plan

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • The Sign-Off Board
    • Debug the Regression