← Design Verification Interviews

Interview Question · Code Reading

Type Coverage vs Instance Coverage

L2 Mid-LevelL3 Seniorfunctional coveragecoverage options

The Question

The interviewer asks

Two instances of one covergroup watch two ports. Between them they hit all four bins. What does this print?

systemverilog
covergroup cg with function sample(bit [1:0] x);
  option.per_instance = 1;
  cp: coverpoint x { bins b[] = {[0:3]}; }
endgroup
cg port_a = new(), port_b = new();
initial begin
  port_a.sample(0); port_a.sample(1);   // port A sees 0 and 1
  port_b.sample(2); port_b.sample(3);   // port B sees 2 and 3
  $display("A=%0.2f B=%0.2f type=%0.2f", port_a.get_inst_coverage(),
           port_b.get_inst_coverage(), port_a.get_coverage());
end
Reveal the Model Answer

It prints A=50.00 B=50.00 type=50.00. Each instance has its own coverage, and per_instance = 1 keeps it in the report. The type figure, get_coverage(), is by default the weighted average of the instances. It is not the union of their bins. With type_option.merge_instances = 1 the type becomes the union, so it reads 100%.

Two Instances, Two Ways to Combine ThemThe run and its twin. Arrows show which bins each instance hit and how the type figure is built.
Two Instances, Two Ways to Combine ThemThe run and its twin. Arrows show which bins each instance hit and how the type figure is built. component port_a.sample() Values 0 and 1 component port_b.sample() Values 2 and 3 component Instance A 2 of 4 bins: 50% component Instance B 2 of 4 bins: 50% component Type figure,default Average of theinstances: 50% component Type withmerge_instances= 1 Union of the bins:100% b[0], b[1]b[2], b[3]5050binsbins
Read the diagram as text
  • port_a.sample(): Values 0 and 1
  • port_b.sample(): Values 2 and 3
  • Instance A: 2 of 4 bins: 50%
  • Instance B: 2 of 4 bins: 50%
  • Type figure, default: Average of the instances: 50%
  • Type with merge_instances = 1: Union of the bins: 100%
  • port_a.sample() → Instance A: b[0], b[1]
  • port_b.sample() → Instance B: b[2], b[3]
  • Instance A → Type figure, default: 50
  • Instance B → Type figure, default: 50
  • Instance A → Type with merge_instances = 1: bins
  • Instance B → Type with merge_instances = 1: bins

Measured: the run prints type=50.00, and the fixed twin with merging prints 100.00.

RUNVerilator (coverage build) · simulator service
Edit the code, then run it
Expected: A=50.00 B=50.00 type=50.00

Self-Check

Tick each key point you covered in your answer.

What Interviewers Listen For (Mid-Level)

A good mid-level answer predicts 50% for the type figure and explains the average rule first. Only after that does it mention merge_instances.

Cross-Questions

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

WhyWhat IfBreak ItCompare

  1. Type Coverage vs Instance Coverage
  2. WhyWhy the Type Figure Is an AverageL2 Mid-Level

    Why does the type figure read 50% when the instances together hit every bin?

    Reveal the Model Answer

    With merging off, each instance is scored against its own bins, and the type is the weighted average of those scores. Port A scores 50 and port B scores 50, so the type is 50. The rule asks "how well was each instance covered", not "was each bin hit somewhere". One idle instance therefore pulls the type figure down.

    FigureBins hitScore
    Instance Ab[0], b[1]50%
    Instance Bb[2], b[3]50%
    Type, default (average)each instance scored on its own50%
    Type, merge_instances = 1 (union)all four, from either instance100%

    The same samples as the root question. Only the rule for combining instances changes.

    Self-Check

    Tick each key point you covered in your answer.

    Tool as Truth

    "The average rule is a tool bug."

    It is the standard's default. Tools that show the union have merge_instances set, or show a merged database view.

    Source Mehta, Introduction to SystemVerilog, Table 15.2 (PDF p613)

  3. CompareWhen to Merge InstancesL2 Mid-LevelL3 Senior

    Compare the merged view with the averaged view. When do you want each?

    Reveal the Model Answer

    Merge when the instances are interchangeable and a case seen on any one of them is enough. Identical lanes behind one arbiter are an example. Average, and read per-instance numbers, when every instance must see every case, such as ports with their own logic. The choice belongs in the coverage plan, written next to the covergroup.

    Self-Check

    Tick each key point you covered in your answer.

    Half-Truth

    "Always merge; the higher number is the true one."

    A merged 100% can hide an instance that never saw traffic at all, as the next question shows.

    Source IEEE 1800-2017 §19.7.1

  4. Break ItA Dead Port Behind a Merged 100 PercentL2 Mid-LevelL3 Senior

    Four ports share one covergroup type. Port 3 never sees traffic. What do the averaged and merged figures say?

    systemverilog
    module tb;
      covergroup avg_cg with function sample(bit [1:0] x);
        cp: coverpoint x { bins b[] = {[0:3]}; }
      endgroup
      covergroup union_cg with function sample(bit [1:0] x);
        type_option.merge_instances = 1;
        cp: coverpoint x { bins b[] = {[0:3]}; }
      endgroup
      avg_cg a[4];
      union_cg u[4];
      initial begin
        foreach (a[i]) begin a[i] = new(); u[i] = new(); end
        for (int p = 0; p < 3; p++)              // ports 0-2 see every value; port 3 is dead
          for (int v = 0; v < 4; v++) begin a[p].sample(2'(v)); u[p].sample(2'(v)); end
        $display("average over ports=%0.2f union over ports=%0.2f", a[0].get_coverage(), u[0].get_coverage());
      end
    endmodule
    
    Reveal the Model Answer

    The average reads 75%, and the union reads 100%. Merging asks whether any instance hit each bin, so three busy ports cover for the dead one. The averaged figure at least shows a gap. Only the per-instance report says which port is dead.

    RUNVerilator (coverage build) · simulator service
    Edit the code, then run it
    Expected: average over ports=75.00 union over ports=100.00

    Self-Check

    Tick each key point you covered in your answer.

    Misconception

    "A merged 100% means every port saw every case."

    It means every case was seen on some port. The run reads 100% with port 3 idle.

    Source Measured: the run on this question, Verilator coverage build (master b8e7f1e)

  5. What IfCoverage Without the Per-Instance OptionL2 Mid-Level

    What if option.per_instance is left at 0?

    Reveal the Model Answer

    Each instance still contributes to the type figure. But the per-instance data is not saved to the coverage database, so the report cannot show which port is weak. Set per_instance = 1 whenever instances watch different things. It can only be set on the covergroup, not on a coverpoint.

    Self-Check

    Tick each key point you covered in your answer.

    Spec Misquote

    "Set per_instance on the one coverpoint you care about."

    It is a covergroup-level option. It cannot be given in a coverpoint or a cross.

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

What People Get Wrong

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

Misconception

"The type figure is the union of what all instances hit, so 100%."

That is true only with merge_instances set. By default the twin reads 50%, the average of two half-covered instances.

Run It

The interview code, read as one type figure.

RUNVerilator (coverage build) · simulator service
Edit the code, then run it
Expected: type coverage=50.00 (merge_instances=0) FAIL: by default the type figure is the average of the instances (50 and 50), not their union
See the Fix
module tb;
  covergroup cg with function sample(bit [1:0] x);
    option.per_instance = 1;
    type_option.merge_instances = 1;     // the fix: the type is the union of the instances
    cp: coverpoint x { bins b[] = {[0:3]}; }
  endgroup
  cg port_a = new(), port_b = new();
  initial begin
    port_a.sample(0); port_a.sample(1);
    port_b.sample(2); port_b.sample(3);
    $display("type coverage=%0.2f (merge_instances=1)", port_a.get_coverage());
    if (port_a.get_coverage() == 100.0) $display("PASS: with merge_instances = 1 the type is the union, so every bin counts once");
  end
endmodule

Prints: type coverage=100.00 (merge_instances=1) PASS: with merge_instances = 1 the type is the union, so every bin counts once

Spec Misquote

"By default the standard merges all instances into one set of bins."

Merging is an option, off by default. With merge_instances = 0 the standard scores the type as a weighted average of instances.

Source IEEE 1800-2017 §19.7.1

Half-Truth

"get_inst_coverage() and get_coverage() are the same thing."

One is this instance only; the other is the whole type. They match only when there is a single instance.

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

Learn It, Then Prove It