← Design Verification Interviews

Interview Question · Debug

Three Coverage Holes, Three Causes

L2 Mid-LevelL3 Seniorfunctional coveragecoverage closuredebug

The Question

The interviewer asks

Coverage has stayed at 70.83% across three seeds. Here is the report. What causes each hole, and what do you do about it?

log
after seed 1: 500 packets, pkt_cg = 70.83%
after seed 2: 1000 packets, pkt_cg = 70.83%
after seed 3: 1500 packets, pkt_cg = 70.83%
bin len.max (16):           hits=0
bin crc.bad:                hits=0
bin kind_x_len CONFIG/long: hits=0
Reveal the Model Answer

Treat each hole on its own, because they have different causes. No length 16 in 1500 packets means the bench cannot make it, so read the constraints: they stop at 15 while the spec allows 16. No CRC errors means no test turns on error injection, so a test or a knob is missing. CONFIG with a long burst is forbidden by the spec, so exclude it with a reference. More seeds fix none of the three.

Three Holes, Three Different FixesThe three empty bins from the report. Arrows show the cause of each hole and the work that closes it.
Three Holes, Three Different FixesThe three empty bins from the report. Arrows show the cause of each hole and the work that closes it. component len.max (16) 0 hits in 1500packets component crc.bad 0 hits component kind_x_lenCONFIG/long 0 hits component Fix theconstraint It stops at 15; thespec allows 16 component Add a knob and atest No test turns onerror injection component Exclude with areference The spec saysCONFIG is one beat bench cannot make itno test asks for itspec forbids it
Read the diagram as text
  • len.max (16): 0 hits in 1500 packets
  • crc.bad: 0 hits
  • kind_x_len CONFIG/long: 0 hits
  • Fix the constraint: It stops at 15; the spec allows 16
  • Add a knob and a test: No test turns on error injection
  • Exclude with a reference: The spec says CONFIG is one beat
  • len.max (16) → Fix the constraint: bench cannot make it
  • crc.bad → Add a knob and a test: no test asks for it
  • kind_x_len CONFIG/long → Exclude with a reference: spec forbids it

Measured by the twin: three seeds give 70.83% each time. With the three fixes, the first seed reaches 100.00%.

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Mid-Level)

A good mid-level answer sorts each hole into one of three causes before fixing anything. The bench cannot generate it, no test asks for it, or the spec forbids it.

Cross-Questions

Where the interviewer goes next. Open a node to practise that follow-up.

WhyWhat IfProve ItBreak ItCompare

  1. Three Coverage Holes, Three Causes
  2. WhyWhy a Flat Line Points at the BenchL1 JuniorL2 Mid-Level

    Why does the same number across several seeds point to the bench, rather than bad luck?

    Reveal the Model Answer

    Each seed takes a different path through the stimulus space. If a bin is reachable with a fair chance, some seed hits it. When thousands of samples over many seeds never touch it, the chance is probably zero. That usually means a constraint, a disabled knob, or a case the design cannot reach.

    Coverage of the FIFO Bench as the Run Goes On
    012items sent32 random64 random+6 directedbins hit6 of 97 of 99 of 9write when fullreset with datadirected reset
    1. Cycle 0

      After 32 random items, 6 of 9 bins are hit. The holes are level 4, write when full and reset with data.

    2. Cycle 1

      32 more random items reach level 4. Write when full is still a hole, and no seed can produce the reset.

    3. Cycle 2

      Six directed items: the fifth write meets a full FIFO, then a reset finds data stored. All 9 bins are hit.

    Measured on a FIFO bench: 32 more random items reached one more bin, but no seed could produce the case the constraints forbid.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Rare bins just need patience."

    Rare and impossible look the same at first. Prove reachability first, then decide between waiting, biasing the constraints or a directed test.

    Source Spear & Tumbush, SystemVerilog for Verification (3rd ed.), §9.11 (PDF p395)

  3. Break ItA Check That Every Corner Can Be GeneratedL2 Mid-Level

    How could a future constraint edit quietly create a hole like this again? Write a check that would catch it early.

    Reveal the Model Answer

    Add a short test that asks the solver for each corner the coverage model needs, with randomize() with { len == 16; }. If the constraints forbid the corner, randomize() returns 0 and the test fails at once. It runs in seconds, so it can run on every check-in, long before a regression plateaus.

    Self-Check

    Tick each key point you covered in your answer.

    Missed Corner

    "The constraints allow every legal length; we reviewed them once."

    Constraints change over a project. The twin asks for length 16 and the solver refuses, exposing the hole in one run.

    Run It

    Asking the solver for each corner of the length coverpoint.

    RUNVerilator (coverage build) · simulator service
    Edit the code, then run it
    Expected: corner len=1: reachable corner len=16: the constraints forbid it FAIL: the generator cannot produce length 16, so the len.max bin can never be hit
    See the Fix
    class pkt;
      rand bit [4:0] len;
      constraint c_len { len inside {[1:16]}; }   // the spec allows 1 to 16
    endclass
    module tb;
      initial begin
        pkt p = new();
        int corners[$] = '{1, 16};
        int blocked = 0;
        // A reachability check: ask the solver for each corner the coverage model needs.
        foreach (corners[i]) begin
          if (!p.randomize() with { len == corners[i]; }) begin
            blocked++;
            $display("corner len=%0d: the constraints forbid it", corners[i]);
          end else $display("corner len=%0d: reachable", corners[i]);
        end
        if (blocked == 0) $display("PASS: every corner in the coverage model can be generated");
      end
    endmodule
    

    Prints: corner len=1: reachable corner len=16: reachable PASS: every corner in the coverage model can be generated

  4. CompareExcluding a Cell vs Relaxing the ConstraintL1 JuniorL2 Mid-Level

    Compare excluding the CONFIG/long cells with relaxing the CONFIG constraint so they get hit.

    Reveal the Model Answer

    The spec says CONFIG is one beat, so a long CONFIG is illegal stimulus. Relaxing the constraint would make the bench send packets the design is allowed to reject or mishandle. The scoreboard would then raise false errors. Exclude the cells, cite the spec, and keep a check that the design never sees a long CONFIG from a real source.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Relax it; more stimulus is always better."

    Illegal stimulus tests behaviour the spec leaves undefined. Its failures waste debug time, and its coverage proves nothing.

    Source Mehta, SystemVerilog Assertions and Functional Coverage (3rd ed.), §26.19 guidelines (PDF p477)

  5. What IfA Hole the Design Itself Cannot ReachL2 Mid-LevelL3 Senior

    What if the bench can generate the case, but the design never enters the state the bin describes?

    Reveal the Model Answer

    Then either the bin is wrong, or the design is missing a feature. Ask the designer which one, and settle it with evidence. A formal cover on the state either finds a trace or proves it unreachable. If the spec requires the state, an unreachable result is a design bug, not a waiver.

    Self-Check

    Tick each key point you covered in your answer.

    Missed Corner

    "If the design can't reach it, exclude it."

    The spec decides what must be reachable, not the RTL. Excluding it would hide a missing feature.

    Source Spear & Tumbush, SystemVerilog for Verification (3rd ed.), §9.2.2 (PDF p364)

  6. Prove ItSolve 7.5.9: The Cross That Can Never CloseSimulator-graded

    Show it, don't just say it: this Silicon Lab problem is graded by the simulator.

    Open Problem 7.5.9

What People Get Wrong

Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.

Misconception

"Run more seeds; random will get there."

A flat number across seeds means the generator cannot reach the bin. The twin runs three seeds and stays at 70.83%.

Run It

The bench behind the log: three seeds of 500 packets.

RUNVerilator (coverage build) · simulator service
Edit the code, then run it
Expected: after seed 1: 500 packets, pkt_cg = 70.83% after seed 3: 1500 packets, pkt_cg = 70.83% bin len.max (16): hits=0 FAIL: three seeds give the same number; no seed can reach length 16 while the constraint forbids it
See the Fix
typedef enum bit [1:0] {READ, WRITE, CONFIG} kind_t;
class pkt;
  rand kind_t kind;
  rand bit [4:0] len;
  rand bit inject_crc;
  bit errors_enabled = 1;                       // the fix: an error test turns the knob on
  constraint c_kind { kind inside {READ, WRITE, CONFIG}; }
  constraint c_len  { len inside {[1:16]}; }               // the fix: the spec allows 1 to 16
  constraint c_cfg  { kind == CONFIG -> len == 1; }     // the spec: CONFIG is one beat
  constraint c_err  { !errors_enabled -> inject_crc == 0; }
endclass
module tb;
  covergroup pkt_cg with function sample(pkt p);
    kind: coverpoint p.kind;
    len:  coverpoint p.len { bins one = {1}; bins mid = {[2:8]}; bins big = {[9:15]}; bins max = {16}; }
    crc:  coverpoint p.inject_crc { bins clean = {0}; bins bad = {1}; }
    kind_x_len: cross kind, len {
      ignore_bins cfg_long = binsof(kind) intersect {CONFIG} && binsof(len) intersect {[2:16]};   // the fix: the spec forbids these
    };
  endgroup
  pkt_cg cov = new();
  int len16 = 0, crc_bad = 0, cfg_long = 0;
  initial begin
    pkt p = new();
    for (int seed = 1; seed <= 3; seed++) begin
      p.srandom(seed);
      repeat (500) begin
        if (!p.randomize()) $display("randomize failed");
        cov.sample(p);
        if (p.len == 16) len16++;
        if (p.inject_crc) crc_bad++;
        if (p.kind == CONFIG && p.len > 1) cfg_long++;
      end
      $display("after seed %0d: %0d packets, pkt_cg = %0.2f%%", seed, seed * 500, cov.get_coverage());
    end
    $display("bin len.max (16):           hits=%0d", len16);
    $display("bin crc.bad:                hits=%0d", crc_bad);
    $display("bin kind_x_len CONFIG/long: hits=%0d", cfg_long);
    if (cov.get_coverage() == 100.0) $display("PASS: fixing the constraint, adding the error knob and excluding CONFIG/long closes the group");
  end
endmodule

Prints: after seed 1: 500 packets, pkt_cg = 100.00% PASS: fixing the constraint, adding the error knob and excluding CONFIG/long closes the group

Wrong Altitude

"Write three directed tests that hit the three bins."

A directed length-16 packet fills the bin but leaves the constraint wrong. Random tests still never combine length 16 with anything else.

Source Spear & Tumbush, SystemVerilog for Verification (3rd ed.), §9.1 (PDF p362)

Delivery

"70% is normal for random tests; waive the rest."

Each hole here has a clear cause and a cheap fix. A waiver needs a reason the spec supports, not a typical number.

Learn It, Then Prove It