Skip to content
VLSI Mentor

Ethernet · Module 26

RTL and Verification Review

546 declared coverage bins, 243 unreachable by construction, and one regression that is 51.832% or 93.399% depending on the denominator — plus the twenty bins random stimulus will never reach.

Chapter 26.1 held a review where every item was a number somebody had to produce. This chapter holds the same review one stage later, and the numbers are harder because the most quoted one — coverage — is a fraction whose denominator the verification team chooses.

Start with the arithmetic this chapter exists to produce.

BinsShare
declared in the functional coverage model546100%
unreachable by construction24344.51%
reachable30355.49%
reached by a full week of a 500-licence farm28351.83% of declared, 93.40% of reachable
needing a directed test206.60% of reachable

One regression run. Two defensible coverage numbers — 51.83% and 93.40% — and neither of them is wrong. The difference between them is 243 bins somebody decided could not happen, and that decision is recorded in a file that no review in this track's experience has ever read.

A coverage percentage is a fraction. The numerator is measured and the denominator is declared, and only one of them is audited.

This chapter's central question is the one Chapter 25.6 §20's fourth property asked in one line — compare bound properties against covered ones and report the difference — asked now of a whole verification plan: what could a closed coverage model have failed to reach?

There are exactly three answers and a review that cannot tell them apart has not reviewed anything.

A bin that was not hitWhyWhat it means
unreachable by constructionthe design cannot produce itcorrect to exclude, IF the argument is right
reachable, not reached in budgettoo rare for random stimulusneeds a directed test
reachable, and nobody classified itnobody lookedthe finding

And the third row is the default. A coverage tool reports a percentage; it does not report which of the three each unhit bin belongs to, because that classification is an argument rather than a measurement.

What this chapter does not own. Chapter 26.1 covered architecture and integration, and Chapter 26.3 covers performance closure and the observability debug needs; Chapter 26.4 covers how the whole of it is probed in an interview. This is the pass held when RTL exists and the verification plan claims to be closed.

Four numbers carry the chapter, and all four are derived here rather than quoted.

NumberWhat it isSection
546 / 243 / 303the coverage model, classified4
±6how far the exclusion list moves on one environmental parameter6
23.24 simulator-yearswhat the rarest reachable bin costs at 95% confidence8
332 of 557 — 59.6%properties whose antecedent needs traffic, from Chapter 21.4 §2010

The last row is the one that makes an assertion suite a reviewable object rather than a count. That chapter measured its own corpus and found that three of every five published properties go silent on a link that never comes up — they do not fail, they stop evaluating — so a regression on a dead link reports 557 passes. A verification review that records "557 properties, 557 passing" has recorded a number that is true and means nothing.


1. Scope — A Coverage Number With Its Denominator

One rule, and it is Chapter 26.1 §1's rule restated for a fraction: a coverage percentage without its denominator's provenance is not a review item.

The failure mode is specific and it is not laziness. A coverage model is built by the same team that builds the testbench, from the same understanding of the design, and every bin it does not contain is invisible to every number it produces. So the model's completeness cannot be measured by the model.

The quoted numberWhat it actually assertsAuditable?
"94% functional coverage"94% of the bins we wrote were hitno — the model is unaudited
"100% after exclusions"every bin we did not exclude was hitno — the exclusions are unaudited
"303 reachable bins, 283 hit, 20 directed tests"three numbers that can each be wrong in a stateable wayyes

Row three is what this chapter's review produces, and the cost of producing it is one classification per unhit bin.

Why the third row is a different KIND of statement. Rows one and two report a measurement over a set. Row three reports the set, and a set can be argued with: somebody can point at a bin in the excluded list and say that one is reachable, here is the sequence. Nobody can argue with 94%.

The reviewable object is not the coverage number. It is the classification of the bins that were not hit — and that classification is an argument, so it has to be written down.

Which gives this chapter the same four-outcome structure Chapter 26.1 §12 arrived at, applied to bins instead of thresholds.

OutcomeWhat it meansWho closes it
HITthe bin was coverednobody
UNREACHABLEan argument exists and is recordeda reviewer, by attacking the argument
DIRECTEDreachable, too rare, a test existsthe test's author
UNCLASSIFIEDnobody lookedthe finding

And a review that cannot express the fourth outcome converts every one of them into the second, because the quickest way to close a coverage report is to exclude what did not hit.

This chapter is not a BCE chapter and Section 12 says why. Its units are bins, simulation-hours, engineer-weeks, and properties whose evaluation count is zero — and mixing any of them with area produces a number with no referent, because area is a property of the object that ships and verification effort is a property of the process that produced confidence in it.


2. The Twenty Items

Every row is a number somebody has to produce, the chapter that derives it, and the kind of threshold it is measured against. No row is an adjective.

#The itemThis design's numberDerived inThreshold kind
1functional coverage bins declared546Section 4structural
2bins unreachable by construction243 — 44.51%Section 5derived
3bins reachable303Section 4derived
4bins reached inside the regression budget283 — 93.40% of reachableSection 8derived
5bins needing a directed test20Section 8derived
6directed tests that existmust equal item 5Section 8structural
7exclusion entries whose argument is recordedmust equal item 2Section 6structural
8exclusion entries that move with a deployment parameter6Section 6, Chapter 26.1 §12environmental
9properties bound in the regression557 in the audited corpusChapter 21.4 §20structural
10properties whose cover count is zero at end of runmust be 0, or each classifiedChapter 25.6 §20derived
11share of properties whose antecedent requires traffic332 of 557 — 59.6%Chapter 21.4 §20derived
12simulation-hours available per week20 000 — 500 licences × 40 hSection 8environmental
13simulation-hours to reach the rarest reachable bin203 764 — 23.24 simulator-yearsSection 8derived
14toggle-coverage bins in the MAC datapath28 332 — 2 per flopChapter 19.7 §19's ~14 166 flopsstructural
15error classes the taxonomy names12Chapter 21.2 §1structural
16classes the injector's five actions can produce9 — so 3 need another routeChapter 20.5 §2structural
17reachable frame shapes qualifying for 2+ classes7 of 12 — 58.3%Chapter 21.2 §2derived
18clock-domain crossings with a bound protocol checkevery one, or the count of exceptionsChapter 18.1 §19structural
19reset and bring-up orders exercisedthe count, against the orders the SoC can produceChapter 19.5 §18environmental
20engineer-weeks of directed-test work6 — 20 tests at 1.5 engineer-daysSection 12derived

Twenty rows. Nine chapters named. And the structure of the list is the point: an item is complete when somebody can say what observation would change its value.

Rows 15 and 16 together are the item nobody writes. Chapter 21.2 §1's taxonomy has twelve classes; Chapter 20.5 §2's injector has five actions — stomp, shorten, lengthen, dribble, suppress idle — and they produce nine of the twelve. So three classes have no injector action at all, and a verification plan that lists "error injection: complete" has covered nine twelfths of a taxonomy it names in full. The item is the number three, and the row next to it is how those three get produced.

Three of the rows are worth reading twice.

Row 6 against row 5. These two must be equal and they are almost never compared. Row 5 is a property of the stimulus and the schedule; row 6 is a property of the test list — so they are produced by different people, at different times, and a difference between them is invisible to both. Section 8 computes row 5 from the traffic model; the review's job is to put the two numbers on the same line.

Row 7 against row 2. Same shape, different failure. Row 2 is a count the tool reports; row 7 is a count of written arguments, and the gap between them is the part of the model that was excluded without a reason. In this design the gap is the whole finding: 243 bins excluded, and Section 6 shows that six of them move when a deployment parameter changes.

Row 11. It is the only row whose value this chapter takes from an audit somebody else already performed, and it is the strongest row in the list because of it. Chapter 21.4 §20 counted its own corpus rather than estimating: 238 properties in Module 19, 162 of them traffic-dependent; 204 in Module 20, 95; 115 in Module 21 so far, 75. Three measurements, one total, 59.6%.


3. RTL 1 — The Verification Package and the Bin Model

The package holds the four axes, the four outcomes and the constants the rest of the chapter computes with. The module classifies one bin.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// verifreview_pkg -- the coverage model's axes, the four outcomes a bin
// can have, and the constants Sections 4 to 8 derive.
//
// The axes are taken from chapters that already own them rather than
// invented here: the seven RMON size buckets from Chapter 19.7 Section 2,
// the twelve error classes from Chapter 21.2 Section 1, three tag depths
// and two directions. Seven times thirteen times three times two is the
// 546 bins Section 4 counts.
// ---------------------------------------------------------------------
package verifreview_pkg;

  // The four axes. ERR_NONE is the thirteenth value of the error axis:
  // twelve classes plus "no error", which is the bin most frames land in.
  typedef enum logic [2:0] {
    SZ_LE64, SZ_65_127, SZ_128_255, SZ_256_511,
    SZ_512_1023, SZ_1024_1518, SZ_GE1519
  } size_bucket_e;                       // 7 -- Chapter 19.7 Section 2

  typedef enum logic [3:0] {
    ERR_NONE,  ERR_FCS,      ERR_ALIGN,   ERR_RUNT,
    ERR_GIANT, ERR_SYMBOL,   ERR_DROP,    ERR_FIFO_OVF,
    ERR_DESC,  ERR_FILTER,   ERR_VLANMEM, ERR_MTUMIS,
    ERR_JABBER
  } err_class_e;                         // 13 -- Chapter 21.2 Section 1

  typedef enum logic [1:0] { TAG_NONE, TAG_SINGLE, TAG_DOUBLE } tag_e;
  typedef enum logic       { DIR_RX, DIR_TX }                   dir_e;

  localparam int N_SIZE = 7;
  localparam int N_ERR  = 13;
  localparam int N_TAG  = 3;
  localparam int N_DIR  = 2;
  localparam int N_BINS = N_SIZE * N_ERR * N_TAG * N_DIR;   // 546

  // The four outcomes of Section 1's table. UNCLASSIFIED is the default
  // and it is the one the review exists to count.
  typedef enum logic [1:0] {
    BIN_UNCLASSIFIED,   // nobody looked -- the finding
    BIN_HIT,            // covered
    BIN_UNREACHABLE,    // an argument exists, and is recorded
    BIN_DIRECTED        // reachable, too rare, a test exists
  } bin_outcome_e;

  // Why a bin is unreachable. A reason is not a boolean: a reviewer
  // attacks the REASON, so the reason has to be nameable.
  typedef enum logic [2:0] {
    UR_NONE,
    UR_LENGTH,        // the class needs a length this bucket excludes
    UR_DIRECTION,     // the class is a receive-side decision
    UR_CONFIG,        // excluded only at this build's parameters
    UR_ENVIRONMENT    // excluded only at this deployment's parameters
  } unreach_reason_e;

  // A bin, flattened. The index is the review's identifier for it and
  // the exclusion list is a list of these indices.
  typedef struct packed {
    size_bucket_e    sz;
    err_class_e      ec;
    tag_e            tg;
    dir_e            dr;
  } bin_key_t;

  function automatic int unsigned bin_index(bin_key_t k);
    return ((int'(k.sz) * N_ERR + int'(k.ec)) * N_TAG + int'(k.tg))
           * N_DIR + int'(k.dr);
  endfunction

  // Section 6: the peer MTU decides where an MTU-mismatch bin becomes
  // reachable, and it is Chapter 26.1 Section 12's environmental
  // threshold appearing inside a coverage model.
  localparam int MTU_BUCKET_576  = 4;   // mismatch visible from SZ_512_1023
  localparam int MTU_BUCKET_1024 = 5;   // from SZ_1024_1518
  localparam int MTU_BUCKET_1500 = 6;   // SZ_GE1519 only

endpackage

Classification, Model or Production? A CLASSIFICATION MODEL. It computes no design behaviour; it decides, for one bin, which of the four outcomes applies and — when the outcome is BIN_UNREACHABLE — which reason supports it.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// bin_model -- one bin in, one outcome out, with the reason attached.
//
// The module's whole value is that it separates UNREACHABLE from
// UNCLASSIFIED. A coverage tool reports both as "not hit".
// ---------------------------------------------------------------------
module bin_model
  import verifreview_pkg::*;
#(
  // The peer's maximum transmission unit, expressed as the first size
  // bucket in which a mismatch can be observed. Section 6 shows the
  // exclusion count moving by six as this parameter moves.
  parameter int MTU_BUCKET = MTU_BUCKET_1024
)(
  input  logic            clk,
  input  logic            rst_n,

  input  logic            bin_valid,
  input  bin_key_t        bin_key,
  input  logic            was_hit,        // the coverage tool's report
  input  logic            has_directed,   // a directed test names it
  input  logic            has_argument,   // an exclusion argument exists

  output logic            out_valid,
  output bin_outcome_e    outcome,
  output unreach_reason_e reason,
  output logic            reason_is_soft  // CONFIG or ENVIRONMENT
);

  // Structural unreachability. Every arm here is a fact about the frame
  // definition or the direction, and each cites the chapter that owns it.
  function automatic unreach_reason_e structural(bin_key_t k);
    // A runt is shorter than 64 octets, so it lives in one bucket only.
    if (k.ec == ERR_RUNT && k.sz != SZ_LE64)
      return UR_LENGTH;
    // A giant and a jabber are longer than the MTU. Chapter 21.2 Sec 1.
    if ((k.ec == ERR_GIANT || k.ec == ERR_JABBER) && k.sz != SZ_GE1519)
      return UR_LENGTH;
    // Five classes are receive-side facts. A transmitter emits whole
    // octets by construction, so an alignment error has no TX form.
    if (k.dr == DIR_TX &&
        (k.ec == ERR_SYMBOL   || k.ec == ERR_ALIGN ||
         k.ec == ERR_FIFO_OVF || k.ec == ERR_FILTER ||
         k.ec == ERR_VLANMEM))
      return UR_DIRECTION;
    return UR_NONE;
  endfunction

  // Environmental unreachability. This arm is the one Section 6 is
  // about: it is true at this build's parameter and false at another.
  function automatic unreach_reason_e environmental(bin_key_t k);
    if (k.ec == ERR_MTUMIS && int'(k.sz) < MTU_BUCKET)
      return UR_ENVIRONMENT;
    return UR_NONE;
  endfunction

  unreach_reason_e r_struct, r_env;

  always_comb begin
    r_struct = structural(bin_key);
    r_env    = environmental(bin_key);
  end

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      out_valid      <= 1'b0;
      outcome        <= BIN_UNCLASSIFIED;
      reason         <= UR_NONE;
      reason_is_soft <= 1'b0;
    end else begin
      out_valid <= bin_valid;
      if (bin_valid) begin
        if (was_hit) begin
          outcome        <= BIN_HIT;
          reason         <= UR_NONE;
          reason_is_soft <= 1'b0;
        end else if (r_struct != UR_NONE) begin
          outcome        <= BIN_UNREACHABLE;
          reason         <= r_struct;
          reason_is_soft <= 1'b0;
        end else if (r_env != UR_NONE) begin
          outcome        <= BIN_UNREACHABLE;
          reason         <= r_env;
          reason_is_soft <= 1'b1;      // Section 6 counts these
        end else if (has_directed) begin
          outcome        <= BIN_DIRECTED;
          reason         <= UR_NONE;
          reason_is_soft <= 1'b0;
        end else begin
          // Not hit, no structural reason, no environmental reason,
          // no directed test. The honest outcome, and the finding.
          outcome        <= has_argument ? BIN_UNREACHABLE
                                         : BIN_UNCLASSIFIED;
          reason         <= has_argument ? UR_CONFIG : UR_NONE;
          reason_is_soft <= has_argument;
        end
      end
    end
  end

endmodule

What it teaches: that the interesting output is reason, not outcome. A coverage tool already computes was_hit; nothing in a standard flow computes why an unhit bin is acceptable. And the reason has a type — structural reasons are theorems about the frame definition, environmental reasons are claims about a deployment — so reason_is_soft separates the exclusions a reviewer can check from the ones that need somebody outside the room, which is exactly Chapter 26.1 §12's derived-against-environmental split arriving inside a coverage model.

Deliberately simplified: has_argument is an input rather than a text field, so the model records that an argument exists and not what it says. A real flow keeps the argument in the exclusion file and this bit is the answer to "is the field non-empty". The two structural arms are also a summary rather than a proof — a complete implementation derives them from the same frame-shape predicates Chapter 21.2 §2 uses, so that a change to the taxonomy propagates. And MTU_BUCKET is a parameter here where in practice it is a comment in a spreadsheet.

Production implication: the outcome to instrument is BIN_UNCLASSIFIED, and it is the one no coverage report has a column for. A flow that reports hit, excluded and total has three numbers; this model has four, and the fourth is the count of bins that were neither hit, nor argued about, nor scheduled for a directed test. In a plan that claims closure that number must be zero, and the cost of proving it is one boolean per unhit bin. The failure when it is not measured is specific: the closure report is true and the design is untested in a part of its input space nobody has named.


4. The Coverage Model, Counted

A functional coverage model built as a cross product of four axes. Seven frame size buckets, thirteen error values which are twelve classes plus no error, three tag depths and two directions give five hundred and forty six declared bins. Four rules then remove bins that cannot occur. A runt is shorter than sixty four octets so it exists in one bucket only, removing thirty six bins. A giant and a jabber are longer than the maximum transmission unit so each exists in one bucket only, removing seventy two. Five error classes are receive side facts, namely symbol, alignment, receive FIFO overflow, filter and VLAN membership, removing one hundred and five. And a mismatch of maximum transmission units is invisible below the peer's own unit, removing thirty. Those four rules remove two hundred and forty three bins, which is forty four point five one per cent of the model, leaving three hundred and three reachable. A regression that hits two hundred and eighty three of them is fifty one point eight three two per cent of the declared model and ninety three point three nine nine per cent of the reachable one, and the two figures describe the same run.7 × 13 × 3 × 2the four axes546 declaredthe quoteddenominatorLength rulesrunt 36, giant/jabber72Direction rule5 RX-only classes —105Peer MTU rule30 — and it moves243 unreachable44.51% of the model303 reachable283 hit51.832% /93.399%one run, twodenominators12
Figure 1 — one cross-product, four exclusion rules, and two coverage numbers that differ by 41.568 points.

Four axes, and every one of them belongs to a chapter that already derived it.

AxisValuesWhere it comes from
frame size7 — the RMON bucketsChapter 19.7 §2
error class13 — twelve classes plus noneChapter 21.2 §1
tag depth3 — untagged, single, doubleChapter 13.2 §2
direction2

Seven times thirteen times three times two is 546. That is the model a verification plan declares, and it is the denominator of every coverage percentage the project will quote for the next eighteen months.

Now classify it. Three kinds of reason, from Section 3's unreach_reason_e, and the counts are exact.

ReasonRuleBinsShare of 546
UR_LENGTH — runta runt is shorter than 64 octets, so it exists in one bucket366.59%
UR_LENGTH — giant and jabberboth are longer than the MTU, so both exist in one bucket7213.19%
UR_DIRECTIONfive classes are receive-side facts — symbol, alignment, FIFO overflow, filter, VLAN membership10519.23%
UR_ENVIRONMENTan MTU mismatch is invisible below the peer's MTU305.49%
unreachable, total24344.51%
reachable30355.49%

Each row's arithmetic is one multiplication. A runt outside SZ_LE64 is six buckets times three tag depths times two directions — 36. Giant and jabber outside SZ_GE1519 is two classes times the same 36 — 72. Each receive-side class on the transmit side is seven buckets times three tag depths — 21 — and there are five of them, 105. An MTU mismatch below the peer's bucket is five buckets times three times two — 30.

Nearly half of a coverage model that took a week to write describes frames that cannot exist. That is not a defect. The defect is that the number 243 appears nowhere in the flow.

And now the two coverage numbers. Section 8 shows a full week of a 500-licence farm reaching 283 bins.

The report saysAgainstThe number
"functional coverage"546 declared bins51.832%
"functional coverage after exclusions"303 reachable bins93.399%

Same run. Same 283 bins. A difference of 41.568 percentage points, produced entirely by which denominator the report was configured with — and both configurations are defensible, which is why both appear in real projects and why neither is a review item.


5. RTL 2 — The Reachability Classifier

Section 3 classified one bin. This module sweeps the whole model and produces Section 4's five counts, which are the numbers the review reads.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// reachability_classifier -- sweep all 546 bins, count the four
// outcomes, and expose the two coverage fractions separately.
//
// The module exists to make the two denominators VISIBLE AT ONCE.
// A flow that can only express one of them forces a choice that then
// gets defended rather than examined.
// ---------------------------------------------------------------------
module reachability_classifier
  import verifreview_pkg::*;
#(
  parameter int MTU_BUCKET = MTU_BUCKET_1024
)(
  input  logic         clk,
  input  logic         rst_n,

  input  logic         sweep_start,
  // One bit per bin from the coverage tool, and two from the plan.
  input  logic         hit_vec       [N_BINS],
  input  logic         directed_vec  [N_BINS],
  input  logic         argument_vec  [N_BINS],

  output logic         sweep_done,
  output logic [15:0]  n_declared,
  output logic [15:0]  n_unreachable,
  output logic [15:0]  n_reachable,
  output logic [15:0]  n_hit,
  output logic [15:0]  n_directed,
  output logic [15:0]  n_unclassified,
  output logic [15:0]  n_soft_exclusions,   // Section 6's six
  // The two fractions, in parts per million so both fit one unit.
  output logic [19:0]  cov_vs_declared_ppm,
  output logic [19:0]  cov_vs_reachable_ppm
);

  logic [15:0] idx;
  logic        running;

  // The bin at the current index, reconstructed from the flat index.
  bin_key_t k;
  always_comb begin
    k.dr = dir_e'( idx % N_DIR );
    k.tg = tag_e'((idx / N_DIR) % N_TAG );
    k.ec = err_class_e'((idx / (N_DIR*N_TAG)) % N_ERR );
    k.sz = size_bucket_e'( idx / (N_DIR*N_TAG*N_ERR) );
  end

  logic            this_unreach, this_soft;
  always_comb begin
    this_unreach = 1'b0;
    this_soft    = 1'b0;
    if (k.ec == ERR_RUNT && k.sz != SZ_LE64)
      this_unreach = 1'b1;
    else if ((k.ec == ERR_GIANT || k.ec == ERR_JABBER) &&
             k.sz != SZ_GE1519)
      this_unreach = 1'b1;
    else if (k.dr == DIR_TX &&
             (k.ec == ERR_SYMBOL || k.ec == ERR_ALIGN ||
              k.ec == ERR_FIFO_OVF || k.ec == ERR_FILTER ||
              k.ec == ERR_VLANMEM))
      this_unreach = 1'b1;
    else if (k.ec == ERR_MTUMIS && int'(k.sz) < MTU_BUCKET) begin
      this_unreach = 1'b1;
      this_soft    = 1'b1;          // moves with the deployment
    end
  end

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      idx               <= '0;
      running           <= 1'b0;
      sweep_done        <= 1'b0;
      n_declared        <= '0;
      n_unreachable     <= '0;
      n_reachable       <= '0;
      n_hit             <= '0;
      n_directed        <= '0;
      n_unclassified    <= '0;
      n_soft_exclusions <= '0;
    end else begin
      sweep_done <= 1'b0;
      if (sweep_start) begin
        idx               <= '0;
        running           <= 1'b1;
        n_declared        <= '0;
        n_unreachable     <= '0;
        n_reachable       <= '0;
        n_hit             <= '0;
        n_directed        <= '0;
        n_unclassified    <= '0;
        n_soft_exclusions <= '0;
      end else if (running) begin
        n_declared <= n_declared + 16'd1;
        if (this_unreach) begin
          n_unreachable     <= n_unreachable + 16'd1;
          n_soft_exclusions <= n_soft_exclusions +
                               16'(this_soft ? 1 : 0);
        end else begin
          n_reachable <= n_reachable + 16'd1;
          if (hit_vec[idx])
            n_hit <= n_hit + 16'd1;
          else if (directed_vec[idx])
            n_directed <= n_directed + 16'd1;
          else if (!argument_vec[idx])
            // Reachable, not hit, no test, no argument. The finding.
            n_unclassified <= n_unclassified + 16'd1;
        end

        if (idx == 16'(N_BINS - 1)) begin
          running    <= 1'b0;
          sweep_done <= 1'b1;
        end else begin
          idx <= idx + 16'd1;
        end
      end
    end
  end

  // Both fractions, always, and never one of them.
  always_comb begin
    cov_vs_declared_ppm  = (n_declared  == 0) ? 20'd0
                         : 20'((int'(n_hit) * 1000000) / int'(n_declared));
    cov_vs_reachable_ppm = (n_reachable == 0) ? 20'd0
                         : 20'((int'(n_hit) * 1000000) / int'(n_reachable));
  end

endmodule

Classification, Model or Production? A REVIEW INSTRUMENT. It runs on a report rather than on a design, and its outputs are the five numbers Section 2's items 1 to 5 require.

What it teaches: that the two coverage fractions cost one extra divide and are almost never both reported. cov_vs_declared_ppm at 518 315 and cov_vs_reachable_ppm at 933 993 are the same run seen through two denominators, and a flow that emits one of them has made an editorial decision that then becomes the project's definition of coverage. The module also teaches why n_unclassified has to be counted separately from n_directed: both are reachable bins that were not hit, and only one of them has somebody's name attached.

Deliberately simplified: the sweep is one bin per cycle over an unpacked array of 546 bits, which is a testbench structure rather than silicon — this module is never synthesised. this_unreach duplicates Section 3's structural and environmental functions rather than instantiating bin_model, which keeps the sweep combinational at the cost of one place the two can diverge; a real implementation instantiates the model and the duplication becomes a conformance check. And the fractions truncate rather than round, which loses up to one part per million and is the right trade for an integer divide.

Production implication: the output to put in the sign-off report is not either fraction — it is n_reachable, n_hit, n_directed and n_unclassified as four integers. They sum to a number somebody can check, each one can be argued with individually, and the two percentages can be recomputed from them by anybody who wants a percentage. A report that carries the four integers cannot be quoted misleadingly; one that carries a single percentage almost always is, not through bad faith but because the denominator travels in a configuration file and the number travels in an email.


6. The Exclusion List Is the Coverage Model

A verification flow is a chain in which each artefact is tested by the next. The register transfer level design is tested by the testbench. The testbench is tested by the coverage model. The coverage model is tested by the exclusion file, because the exclusion file decides which parts of the model count. And the exclusion file is tested by nothing, which is where the chain terminates. Getting the file wrong has two directions and they behave completely differently. Excluding a bin that is actually reachable removes the instrument, so the flow produces no pass, no failure, no warning and no anomalous percentage, and the error is silent for the product's life. Leaving in a bin that is actually unreachable creates a directed test that can never hit, which appears on a failure list every morning until somebody acts on it. So the error that costs nothing to make is the one nothing detects, and the error that is harmless is the one that announces itself immediately.The RTLtested by thetestbenchThe testbenchtested by the modelThe coveragemodeltested by theexclusionsThe exclusionfiletested by NOTHINGReachable,excludedthe instrument isremovedUnreachable,kepta test that neverhitsSilent for lifeno pass, no fail, noflagLoud by morningon the failure list12
Figure 2 — the verification chain terminates at a text file, and the two ways of getting that file wrong are not symmetric.

Section 4 counted 243 unreachable bins as though the count were a fact. It is not. It is the output of a rule, and one of the four rules has a parameter in it.

The MTU-mismatch rule from Section 3's environmental function: a mismatch is invisible in frames below the peer's maximum transmission unit. Which bucket that is depends on a number nobody in the design team owns — Chapter 26.1 §12's environmental threshold, appearing here as a line in an exclusion file.

The peer's MTUMismatch first visible inExcludedReachable
576 octets — the IPv4 minimumSZ_512_1023237309
1 024 octetsSZ_1024_1518243303
1 500 octets — the standard MTUSZ_GE1519249297

The exclusion list moves by twelve bins across the range and by six between adjacent rows, and every row is the same design, the same RTL and the same testbench. What changed is a number in somebody else's network.

Now put the regression's 283 hits against each row.

The peer's MTUReachableReported coverageBins never tested and never argued about
57630991.586%6 — excluded on an assumption that is false here
1 02430393.399%0
1 50029795.286%0 — but 6 directed tests exist that can never pass

Row one is the failure and row three is the false alarm, and they are not symmetric.

Excluding a reachable bin removes the test. Including an unreachable one adds a test that fails forever. The first is silent; the second is loud on the first night of regression.

That asymmetry is the whole of Section 20's argument and it is worth stating as an engineering fact before it becomes a property. An excluded bin is not sampled. The coverage tool does not instrument it, so it produces no evidence in either direction — not a pass, not a fail, not a warning, and not a suspicious figure above 100%. A wrong exclusion is invisible to the flow that contains it, because the flow's response to an exclusion is to stop looking.

The opposite error announces itself. A bin wrongly left in the reachable set becomes a directed test that never hits, and a test that never hits is on somebody's failure list every morning until they either fix it or exclude it. So the error that costs nothing to make also costs nothing to detect, and the error that costs a design its coverage is undetectable by construction.


7. RTL 3 — The Exclusion Auditor

Section 5 counted bins. This module audits the file that decides which bins get counted.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// exclusion_auditor -- compares the exclusion file against the
// classifier's own rules and reports four disagreements, three of which
// no standard flow produces.
//
// It is the only module in this chapter that treats the exclusion list
// as EVIDENCE rather than as configuration.
// ---------------------------------------------------------------------
module exclusion_auditor
  import verifreview_pkg::*;
(
  input  logic         clk,
  input  logic         rst_n,

  input  logic         entry_valid,
  input  bin_key_t     entry_key,
  input  logic         entry_has_argument,   // the file's reason field
  input  unreach_reason_e entry_claimed,     // the reason it claims

  // The classifier's independent opinion of the same bin.
  input  logic            model_unreachable,
  input  unreach_reason_e model_reason,
  input  logic            model_soft,

  output logic [15:0]  n_entries,
  output logic [15:0]  n_with_argument,
  output logic [15:0]  n_soft,             // depends on a deployment
  output logic [15:0]  n_reason_mismatch,  // file and model disagree
  output logic [15:0]  n_model_disagrees,  // file excludes, model does not
  output logic         file_is_reviewed,   // every entry has an argument
  output logic         file_is_sound       // and the model agrees with all
);

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      n_entries         <= '0;
      n_with_argument   <= '0;
      n_soft            <= '0;
      n_reason_mismatch <= '0;
      n_model_disagrees <= '0;
    end else if (entry_valid) begin
      n_entries <= n_entries + 16'd1;

      // Item 7 of Section 2: an entry without a sentence is an entry
      // nobody can attack.
      if (entry_has_argument)
        n_with_argument <= n_with_argument + 16'd1;

      // The six. An exclusion whose truth depends on a number outside
      // the room is the reviewer's whole budget.
      if (model_soft || entry_claimed == UR_ENVIRONMENT)
        n_soft <= n_soft + 16'd1;

      // The file says one thing and the rules say another. Both may be
      // defensible; the point is that nobody has ever compared them.
      if (model_unreachable && (entry_claimed != model_reason))
        n_reason_mismatch <= n_reason_mismatch + 16'd1;

      // The file excludes a bin the rules say is reachable. This is the
      // silent error of Section 6, and this counter is the only place
      // in the flow where it becomes a number.
      if (!model_unreachable)
        n_model_disagrees <= n_model_disagrees + 16'd1;
    end
  end

  // Two verdicts, and they are deliberately different questions.
  always_comb begin
    file_is_reviewed = (n_entries == n_with_argument);
    file_is_sound    = file_is_reviewed && (n_model_disagrees == 16'd0);
  end

endmodule

Classification, Model or Production? A REVIEW INSTRUMENT, and the most useful one in the chapter.

What it teaches: that an exclusion list can be checked against something, which is the assumption the whole flow lacks. n_model_disagrees is the counter that catches Section 6's silent error — the file excludes a bin and the rules say it is reachable — and it exists only because the rules were written down in Section 3 rather than left in the exclusion file's comment field. The module also teaches the difference between file_is_reviewed and file_is_sound: the first says every entry has a sentence attached, the second says the sentences agree with an independent model. A file can be fully reviewed and entirely wrong, which is Chapter 26.1 §10's witness problem arriving one stage later.

Deliberately simplified: entry_claimed is an enumerated reason where a real exclusion file has free text, so the comparison against model_reason is exact here and fuzzy in practice — which is an argument for constraining the file's reason field to an enumeration rather than for abandoning the check. The model's opinion arrives as inputs rather than by instantiating reachability_classifier, which keeps this module a pure comparator. And there is no counter for the opposite error — a bin the model says is unreachable and the file does not exclude — because that error is loud: it becomes a directed test that never hits.

Production implication: n_soft is the number to put at the top of the review's agenda, and in this design it is six. Those six exclusions are true at one peer MTU and false at another, so they are not properties of the design at all — they are properties of a network the design will be sold into, and the correct handling is the one Chapter 26.1 §12 arrived at for every environmental threshold: name the owner, expose the parameter, and re-run the classifier when the parameter changes. A project that ships one exclusion file for every deployment has hard-coded somebody else's MTU into its definition of "verified".


8. What Random Stimulus Cannot Reach

A design clocked at one point two gigahertz simulated at two thousand cycles per wall clock second is six hundred thousand times slower than real time. With a mean frame of five hundred and ten point zero nine octets on the wire, which is forty point eight one nanoseconds and forty eight point nine seven cycles at one hundred gigabits per second, the wire delivers twenty four point five million frames per second and the simulator delivers forty point eight four. The rarest reachable bin, a jabber above one thousand five hundred and eighteen octets, double tagged, on the receive side, has a probability of one times ten to the minus ten, so ninety five per cent confidence of one hit needs about three times ten to the tenth frames. That is twenty three point two four simulator years and twenty minutes of a real link. A farm of five hundred licences for forty hours delivers two point nine four times ten to the ninth frames in a week and reaches two hundred and eighty three of the three hundred and three reachable bins, leaving twenty. Those twenty can be closed three ways: two hundred and four thousand simulation hours, which is ten point two weeks of the whole farm; six engineer weeks of directed tests; or twenty lines in the exclusion file, which takes an afternoon and verifies nothing.600 000× slower1.2 GHz ÷ 2 000 cyc/s24.5 M/s vs40.84/swire againstsimulatorRarest bin p =1e-1023.24 simulator-yearsOne farm-week2.94e9 frames — 283bins20 bins leftthe review's number204 036sim-hours10.2 farm-weeks6 engineer-weeks20 directed testsOne afternoon20 exclusion lines —verifies nothing12
Figure 3 — the simulator is 600 000 times slower than the wire, and three routes close the same twenty bins.

Section 4 said 303 bins are reachable. This section asks how long reaching them takes, and the answer is the chapter's second finding.

The traffic model, stated so it can be argued with. Four distributions, each a stated assumption rather than a measurement.

AxisDistributionSource of the shape
sizeSZ_LE64 50%, SZ_1024_1518 28%, the other five 5%, SZ_GE1519 2%the bimodal data-centre profile of Chapter 19.7 §9
taguntagged 60%, single 39%, double 1%Chapter 13.3 §2 — Q-in-Q is an edge case
direction50 / 50a symmetric testbench
errortotal error rate 1.12 × 10⁻⁴, split across twelve classesChapter 21.2 §1's classes at injection rates

And the simulator, which is the term everybody leaves out.

QuantityValueHow
design clock1.2 GHzChapter 23.3 §2's pipeline clock
simulator throughput2 000 cycles per wall-clock secondan assertion-heavy UVM environment
slowdown against real time600 000×1.2 × 10⁹ ÷ 2 × 10³
mean frame on the wire510.09 octetsthe size distribution plus 20 octets of preamble and gap, Chapter 8.1 §2
mean frame time at 100 Gb/s40.81 ns510.09 × 8 ÷ 10¹¹
cycles per frame48.9740.81 ns × 1.2 GHz
wire throughput2.4505 × 10⁷ frames/s1 ÷ 40.81 ns
simulator throughput40.84 frames/s2 000 ÷ 48.97

A 100 Gb/s port delivers 24.5 million frames a second. The simulator that verifies it delivers 40.84. Every coverage argument in this chapter is a consequence of that ratio.

Now the rarest reachable bin. A jabber, in SZ_GE1519, double-tagged, on the receive side: 2% × 1 × 10⁻⁶ × 1% × 50% = 1 × 10⁻¹⁰.

FramesSimulationOn the wire
one expected hit1 × 10¹⁰68 012 hours — 7.76 simulator-years408.1 s
95% confidence of one hit2.996 × 10¹⁰203 764 hours — 23.24 simulator-years1 222.6 s — twenty minutes

Twenty minutes of a real link against twenty-three years of a simulator, for one bin. And the ratio is not a surprise once it is written down — it is the 600 000× slowdown, and nothing about the coverage model changes it.

The distribution over all 303 reachable bins, at 95% confidence each.

Simulation needed per binBinsShare of 303
more than 1 hour26186.1%
more than one overnight run — 8 h25483.8%
more than one day23577.6%
more than one week16755.1%
more than one year3511.6%

Which looks catastrophic and is not, because bins are collected from one stimulus stream and streams run in parallel. A farm changes the arithmetic.

The farmValue
licences500
hours per licence per week40
simulation-hours per week20 000
frames per week2.9407 × 10⁹
bins reached at 95% confidence283 of 303 — 93.399%
bins NOT reached20

Twenty bins. That is Section 2's item 5, and it is the number the whole section was built to produce. It is not a coverage hole and it is not a bug — it is a work item, and its correct disposition is twenty directed tests.


9. RTL 4 — The Stimulus Budget Model

The module that turns a bin's probability into a schedule, and a schedule into the count of directed tests the plan needs.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// stimulus_budget -- given a bin's probability and the farm's frame
// budget, decide whether random stimulus will reach it and, if not,
// require a directed test.
//
// The arithmetic is deliberately the 95%-confidence form rather than
// the expectation form: a bin whose EXPECTED hit count is one is missed
// about 37% of the time, and a plan built on expectations is wrong on a
// third of its rarest bins.
// ---------------------------------------------------------------------
module stimulus_budget #(
  // Probabilities arrive scaled by 1e12 so that 1e-10 is 100 and the
  // whole range of interest fits in 40 bits without a real type.
  parameter longint unsigned FRAMES_PER_WEEK = 64'd2_940_700_000,
  // ln(0.05) / ln(1-p) is about 3/p for small p. The 3 is exact enough
  // below p = 1e-3 and this model is only used below 1e-6.
  parameter int unsigned     CONF_MULT       = 3
)(
  input  logic          clk,
  input  logic          rst_n,

  input  logic          bin_valid,
  input  logic [39:0]   bin_p_e12,        // probability x 1e12
  input  logic          has_directed_test,

  output logic          out_valid,
  output logic          reachable_by_random,
  output logic          needs_directed,
  output logic          gap,              // needs one and has none
  output logic [47:0]   frames_needed_e0,
  output logic [31:0]   weeks_needed,
  output logic [15:0]   n_needing_directed,
  output logic [15:0]   n_directed_present,
  output logic [15:0]   n_gaps
);

  // 3 / p, with p expressed times 1e12. The divide is by the scaled
  // probability, so the 1e12 cancels into the numerator.
  function automatic longint unsigned frames_for(logic [39:0] p_e12);
    if (p_e12 == 40'd0) return 64'hFFFF_FFFF_FFFF;   // never
    return (64'(CONF_MULT) * 64'd1_000_000_000_000) / 64'(p_e12);
  endfunction

  longint unsigned need;

  always_comb begin
    need = frames_for(bin_p_e12);
  end

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      out_valid           <= 1'b0;
      reachable_by_random <= 1'b0;
      needs_directed      <= 1'b0;
      gap                 <= 1'b0;
      frames_needed_e0    <= '0;
      weeks_needed        <= '0;
      n_needing_directed  <= '0;
      n_directed_present  <= '0;
      n_gaps              <= '0;
    end else begin
      out_valid <= bin_valid;
      if (bin_valid) begin
        frames_needed_e0 <= 48'(need);
        weeks_needed     <= 32'((need + FRAMES_PER_WEEK - 1)
                                / FRAMES_PER_WEEK);

        if (need <= FRAMES_PER_WEEK) begin
          reachable_by_random <= 1'b1;
          needs_directed      <= 1'b0;
          gap                 <= 1'b0;
        end else begin
          reachable_by_random <= 1'b0;
          needs_directed      <= 1'b1;
          n_needing_directed  <= n_needing_directed + 16'd1;
          if (has_directed_test) begin
            n_directed_present <= n_directed_present + 16'd1;
            gap                <= 1'b0;
          end else begin
            // Section 2's items 5 and 6 differing. The plan believes
            // this bin is covered and nothing will cover it.
            n_gaps <= n_gaps + 16'd1;
            gap    <= 1'b1;
          end
        end
      end
    end
  end

endmodule

Classification, Model or Production? A PLANNING MODEL. It computes a schedule from a probability, and its output is a test list rather than a design decision.

What it teaches: that the confidence multiplier is not a detail. At CONF_MULT = 1 the model plans for the expected hit, and a Poisson process with an expectation of one produces zero hits 36.8% of the time — so a plan built on expectations misses about a third of its rarest bins and discovers it in the last week. At CONF_MULT = 3 the miss probability is 5%. The module also teaches that weeks_needed is the honest unit for a planning conversation: 10.2 weeks of the whole farm is a sentence a programme manager can act on, where 3 × 10¹⁰ frames is not.

Deliberately simplified: probabilities arrive as a pre-computed scalar per bin, which assumes the four axes are independent — and they are not: a jabber is correlated with large frames by definition, so the true probability of the rarest bin is not the product of its marginals. The independence assumption overestimates the rarity of correlated bins and underestimates it for anti-correlated ones, and a real model samples the joint distribution from a traffic capture. frames_for also uses 3/p rather than ln(0.05)/ln(1−p), which is accurate to better than 0.1% for every probability this chapter uses and wrong above about 10⁻³.

Production implication: n_gaps is the output that belongs in the sign-off report and it is one integer. It is the count of bins that need a directed test and do not have one — Section 2's item 5 minus item 6 — and it is computable the day the coverage model is written, months before the regression that would have revealed it. A plan that computes n_gaps early converts a last-week coverage crisis into an early staffing decision; one that does not will find the same twenty bins in the final week and close them with an exclusion, because by then that is the only option left that fits the schedule.


10. The Assertion Corpus, Audited

Chapter twenty one point four section twenty measured the track's own assertion corpus rather than estimating it. Module nineteen published two hundred and thirty eight properties of which one hundred and sixty two, or sixty eight point one per cent, have an antecedent that requires traffic. Module twenty published two hundred and four of which ninety five, or forty six point six per cent. Module twenty one as far as that chapter published one hundred and fifteen of which seventy five, or sixty five point two per cent. Across all three that is three hundred and thirty two of five hundred and fifty seven, or fifty nine point six per cent. Applied to a media access control plan of two hundred and forty bound properties, one hundred and forty three have traffic dependent antecedents. On a healthy link all two hundred and forty evaluate and the report says two hundred and forty passes. On a link that never trains, ninety seven evaluate, one hundred and forty three stop evaluating entirely, none of them fails, and the report still says two hundred and forty passes. The only signal that anything is wrong is the cover count, which a pass and fail summary does not carry.Module 19162 of 238 — 68.1%Module 2095 of 204 — 46.6%Module 2175 of 115 — 65.2%332 of 55759.6%, measured240 bound here143 traffic-dependentHealthy link240 evaluate — 240passLink nevertrains97 evaluate, 143silentReport: 240passedidentical in both12
Figure 4 — a pass count and a cover count answer different questions, and only one of them survives a link that never trains.

Coverage bins are one half of a verification plan and properties are the other, and the properties half has a defect the bins half does not: a property that is never evaluated reports the same result as a property that passed.

Chapter 21.4 §20 measured this on the track's own corpus rather than asserting it.

CorpusPropertiesWith an antecedent that requires trafficShare
Module 19 — the datapath23816268.1%
Module 20 — the environment2049546.6%
Module 21 as far as 21.41157565.2%
all three55733259.6%

Three of every five published properties stop evaluating on a link that never comes up. Not fail — stop. Their antecedents need a frame, the link produces none, and a regression bound to all 557 reports 557 passes on a design that does not work.

A property's pass count says how often it was true. Its cover count says how often anybody asked. A report with the first and not the second is a report of the testbench's activity, not the design's correctness.

Which makes Section 2's item 10 the single cheapest improvement available to any verification plan in this track: count the bound properties whose cover count is zero at the end of the regression, and classify each one. Three outcomes, exactly parallel to Section 1's three for bins.

A property that never firedWhyWhat it means
not bound in this configurationgenerate removed itcorrect — Chapter 25.6 §20's first repair
bound, antecedent unreachable in this builda parameter excludes itcorrect, if the argument is recorded
bound, antecedent reachable, never seenthe stimulus never produced itthe finding — and it is also a coverage hole

Row three is the interesting one because it connects the two halves of this chapter. A property whose antecedent is reachable and never seen is describing a bin that was never hit, so the assertion corpus and the coverage model are measuring the same gap from two directions — and a plan that audits both has two independent witnesses for the same claim, which is Chapter 26.1 §10's independence requirement satisfied for free.

The arithmetic on this design's own plan. Applying the audited 59.6% to a MAC-scale corpus of 240 bound properties:

Properties
bound in the regression240
with a traffic-dependent antecedent, at 59.6%143
that fire on a healthy link240
that fire on a link that never trains97
that FAIL on a link that never trains0

Ninety-seven properties evaluate and 143 go quiet, and the report says 240 passed. The only signal that anything is wrong is the cover count, and it is the one number a pass/fail summary does not carry.


11. RTL 5 — The Bound-Against-Covered Reconciler

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// bound_covered_reconciler -- walk the regression's property table and
// separate the properties that never fired into the three outcomes of
// Section 10, so that "bound minus covered" becomes a classified list
// rather than a number to be explained away.
// ---------------------------------------------------------------------
module bound_covered_reconciler (
  input  logic         clk,
  input  logic         rst_n,

  input  logic         prop_valid,
  input  logic         prop_bound,          // survived elaboration
  input  logic [31:0]  prop_cover_count,    // times the antecedent fired
  input  logic [31:0]  prop_pass_count,
  input  logic [31:0]  prop_fail_count,
  input  logic         prop_excluded_by_cfg,// a generate removed its peer
  input  logic         prop_has_argument,   // somebody wrote the reason
  input  logic         prop_needs_traffic,  // Chapter 21.4's category

  output logic [15:0]  n_bound,
  output logic [15:0]  n_covered,
  output logic [15:0]  n_silent,            // bound, never evaluated
  output logic [15:0]  n_silent_explained,  // and classified
  output logic [15:0]  n_silent_unexplained,
  output logic [15:0]  n_traffic_dependent,
  output logic [19:0]  traffic_dep_ppm,
  output logic         suite_is_reconciled,
  output logic         report_is_honest     // pass count has a denominator
);

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      n_bound              <= '0;
      n_covered            <= '0;
      n_silent             <= '0;
      n_silent_explained   <= '0;
      n_silent_unexplained <= '0;
      n_traffic_dependent  <= '0;
    end else if (prop_valid && prop_bound) begin
      n_bound <= n_bound + 16'd1;

      if (prop_needs_traffic)
        n_traffic_dependent <= n_traffic_dependent + 16'd1;

      if (prop_cover_count != 32'd0) begin
        n_covered <= n_covered + 16'd1;
      end else begin
        // Bound and never evaluated. A pass count of zero here is
        // indistinguishable from a pass count of zero on a property
        // that fired and never held -- except that fail_count settles it.
        n_silent <= n_silent + 16'd1;
        if (prop_excluded_by_cfg || prop_has_argument)
          n_silent_explained <= n_silent_explained + 16'd1;
        else
          n_silent_unexplained <= n_silent_unexplained + 16'd1;
      end
    end
  end

  always_comb begin
    traffic_dep_ppm = (n_bound == 0) ? 20'd0
                    : 20'((int'(n_traffic_dependent) * 1000000)
                          / int'(n_bound));
    // The useful verdict is not "everything fired" -- it is "everything
    // that did not fire has a sentence attached".
    suite_is_reconciled = (n_silent_unexplained == 16'd0);
    // And a pass count means nothing without the cover count beside it.
    report_is_honest    = suite_is_reconciled && (n_covered != 16'd0);
  end

endmodule

Classification, Model or Production? A REVIEW INSTRUMENT.

What it teaches: that prop_fail_count is the input that disambiguates the two zeros. A property with pass_count == 0 has either never been evaluated or been evaluated and failed every time, and the pass count alone cannot tell them apart — which is the assertion-side form of Section 4's two-denominator problem. The module also teaches why traffic_dep_ppm belongs in telemetry rather than in a verdict: it is a property of the suite's style, not of any run, and a suite at 595 833 ppm is not broken — it is normal, and it is the number that predicts how a regression will behave on a link that does not train.

Deliberately simplified: prop_needs_traffic is an input classification where a real flow derives it by walking each property's antecedent for signals in the receive datapath, which is a static analysis rather than a runtime one. The module also treats "bound" as a single bit where a suite with multiple configurations has a property bound in some builds and not others — so a complete implementation reconciles per configuration and then across them, and the cross-configuration total is the one that catches a property no build ever binds.

Production implication: n_silent_unexplained is the number to gate on, and gating on it is different from gating on n_silent. A healthy suite has a large n_silent — configurations differ, features are optional, and generate blocks do their job. A healthy suite has n_silent_unexplained of zero, because every silent property has one line saying which of the three reasons applies. The cost is one line per silent property, once, and the benefit is that the day a property stops firing because somebody renamed a signal, the count moves and somebody sees it — instead of the property joining the 143 that were always quiet.


12. The Units of a Verification Review

Every chapter of this track since Chapter 19.1 has priced something in BCE — one bit of usable on-die SRAM, 0.35 gate-equivalents, twenty to a flip-flop. This chapter prices nothing in BCE, and the reason is not that verification has no cost.

It is that verification's cost is not a property of the object that ships.

AreaVerification effort
what it is a property ofthe siliconthe process that produced confidence in the silicon
when it is fixedat tape-out, forevernever — it accrues after tape-out too
who pays itevery unit shippedthe programme, once
what halving it does to the othernothingnothing

Row four is the one that forbids the sum. A design that halves its area may double its verification cost — a shared resource is smaller and harder to reason about — so the two numbers are not merely in different units, they are not even correlated in sign. Adding them produces a quantity that gets larger when the design gets better, which is the definition of a number with no referent.

So this chapter uses four units, and they do not convert into one another.

UnitWhat it measuresSectionThis design
binsthe size of the claim4546 declared, 303 reachable
simulation-hourswhat random stimulus costs820 000 per week available; 204 036 to close by random
engineer-weekswhat deliberate stimulus coststhis section6
properties with zero evaluationswhat the suite silently did not check10143 of 240 on an untrained link

Four units, four questions, and no exchange rate between any pair of them. A review that reports one number has answered one of the four.

The engineer-week arithmetic, stated so it can be argued with.

Value
bins needing a directed test20
effort per directed test1.5 engineer-days — write, debug, review, land
total30 engineer-days
at five days a week6 engineer-weeks
as a share of a 24-engineer-month programme — 104 engineer-weeks5.77%

Six engineer-weeks against 204 036 simulation-hours is the comparison Section 8 made, and it is the only place the two units meet: not in a sum, but in a schedule, where they compete for the same calendar. That is the correct relationship between incomparable units — they are compared by what they displace, not by conversion.


13. RTL 6 — The Effort Reconciler

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// effort_reconciler -- hold the four units side by side without ever
// summing them, and report the one relationship that is real: what each
// route costs in the calendar.
//
// The module's central refusal is that it has NO output combining a
// simulation-hour with an engineer-day. Section 12 is the reason.
// ---------------------------------------------------------------------
module effort_reconciler #(
  parameter int unsigned FARM_HOURS_PER_WEEK   = 20000,
  parameter int unsigned ENG_DAYS_PER_TEST_X10 = 15,    // 1.5 days
  parameter int unsigned ENG_DAYS_PER_WEEK     = 5
)(
  input  logic         clk,
  input  logic         rst_n,

  input  logic         reconcile,
  input  logic [15:0]  bins_declared,
  input  logic [15:0]  bins_reachable,
  input  logic [15:0]  bins_hit,
  input  logic [15:0]  bins_needing_directed,
  input  logic [47:0]  frames_to_close_by_random,
  input  logic [31:0]  sim_frames_per_hour,
  input  logic [15:0]  props_bound,
  input  logic [15:0]  props_silent,

  // Four outputs in four units. None of them is a sum of the others.
  output logic [15:0]  u_bins_outstanding,
  output logic [31:0]  u_sim_hours_to_close,
  output logic [15:0]  u_eng_weeks_to_close,
  output logic [15:0]  u_props_unevaluated,

  // And two dimensionless ratios, which are the only figures that
  // transfer to another programme.
  output logic [19:0]  unreachable_share_ppm,
  output logic [19:0]  silent_share_ppm,

  // The calendar comparison: the two routes, in weeks, side by side.
  output logic [31:0]  weeks_if_random,
  output logic [15:0]  weeks_if_directed,
  output logic         directed_is_cheaper
);

  logic [31:0] sim_hours;
  logic [31:0] eng_days_x10;

  always_comb begin
    sim_hours = (sim_frames_per_hour == 0) ? 32'hFFFF_FFFF
              : 32'(frames_to_close_by_random / 48'(sim_frames_per_hour));
    eng_days_x10 = 32'(bins_needing_directed) * 32'(ENG_DAYS_PER_TEST_X10);
  end

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      u_bins_outstanding    <= '0;
      u_sim_hours_to_close  <= '0;
      u_eng_weeks_to_close  <= '0;
      u_props_unevaluated   <= '0;
      weeks_if_random       <= '0;
      weeks_if_directed     <= '0;
    end else if (reconcile) begin
      u_bins_outstanding   <= bins_reachable - bins_hit;
      u_sim_hours_to_close <= sim_hours;
      // Round up: a fraction of an engineer-week is a whole week of
      // somebody's calendar.
      u_eng_weeks_to_close <= 16'((eng_days_x10 +
                                   (10*ENG_DAYS_PER_WEEK) - 1)
                                  / (10*ENG_DAYS_PER_WEEK));
      u_props_unevaluated  <= props_silent;

      weeks_if_random   <= (sim_hours + FARM_HOURS_PER_WEEK - 1)
                           / FARM_HOURS_PER_WEEK;
      weeks_if_directed <= 16'((eng_days_x10 +
                                (10*ENG_DAYS_PER_WEEK) - 1)
                               / (10*ENG_DAYS_PER_WEEK));
    end
  end

  always_comb begin
    unreachable_share_ppm =
      (bins_declared == 0) ? 20'd0
      : 20'((int'(bins_declared - bins_reachable) * 1000000)
            / int'(bins_declared));
    silent_share_ppm =
      (props_bound == 0) ? 20'd0
      : 20'((int'(props_silent) * 1000000) / int'(props_bound));
    // The only legitimate comparison between the two routes: which one
    // occupies fewer weeks of the project's calendar.
    directed_is_cheaper = (32'(weeks_if_directed) < weeks_if_random);
  end

endmodule

Classification, Model or Production? A REVIEW INSTRUMENT, and the one whose design decisions are mostly refusals.

What it teaches: that a module can be defined by the port it does not have. There is no total_cost output, no weighting parameter and no exchange rate — and every one of those would have been easy to add and impossible to interpret. The comparison the module does make, directed_is_cheaper, is in weeks: 10.2 weeks of the whole farm against 6 engineer-weeks, which is a real comparison because both routes consume the same calendar. The two ppm outputs are the module's other teaching: they are the only figures here that mean anything on a different project.

Deliberately simplified: ENG_DAYS_PER_TEST_X10 is one constant for all twenty tests, and the twenty are not equally hard — a double-tagged jabber is a constrained-random sequence with two overrides; a FIFO-overflow bin needs a backpressure model. A real estimate is per-test, and the spread is wide enough that the total can be wrong by a factor of two. The farm figure also assumes perfect parallel efficiency, where a real farm loses licences to other projects, to failed jobs and to compile time. Both simplifications push the same way — they make the directed route look relatively better than it is — and Section 18 lists them as assumptions rather than hiding them.

Production implication: the report this module produces has four numbers and two ratios, and it fits on one line of a status e-mail: "20 bins outstanding, 204 036 simulation-hours or 6 engineer-weeks to close, 143 properties unevaluated; 44.5% of the model is unreachable and 59.6% of the suite needs traffic." Every clause is a different unit, none of them has been converted into another, and a reader can act on any one of them independently — which is the practical test of whether a set of units was chosen honestly.


14. What a Verification Review Must Never Do

Six prohibitions. Each is something a review does under schedule pressure, and each converts a finding into a pass.

#NeverBecause
1quote a coverage percentage without its denominatorSection 4 — 51.832% and 93.399% are the same run
2accept an exclusion without an argumentSection 6 — the flow's response to an exclusion is to stop measuring
3close a bin by editing the model rather than testing itSection 8 — an afternoon against six engineer-weeks, and only one of them verifies
4report a pass count without a cover countSection 10 — 143 of 240 properties can pass by never being asked
5sum a simulation-hour and an engineer-daySection 12 — the two are not correlated, even in sign
6treat a reference bin list as this design's modelthe axes are this design's; the distribution is this deployment's

Prohibition 3 is the one that needs a mechanism rather than a rule, because it is the only one whose violation looks like progress. A bin closed by an exclusion and a bin closed by a test are indistinguishable in the coverage report — both stop appearing in the uncovered list — so the review needs the two counts separately or it cannot tell diligence from tidying.

The number that distinguishes them is item 6 of Section 2 minus item 5: directed tests that exist, against directed tests the stimulus arithmetic says are needed. When the first is smaller, the difference was closed with an editor.

And prohibition 6 has a specific form in this chapter. Section 8's traffic distribution is a model, and every probability in Section 8's table is a number about a deployment. Reuse the axes; re-derive the distribution. A coverage model whose bins come from Chapter 21.2 and whose probabilities come from the previous project has a correct numerator and a denominator from somebody else's network.


15. RTL 7 — Verification Telemetry

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// verif_telemetry -- the numbers a verification review should be able
// to read at any moment, not only at sign-off.
//
// Everything here is a count or a ratio of counts. Nothing here is a
// verdict; Section 16 owns those.
// ---------------------------------------------------------------------
module verif_telemetry (
  input  logic         clk,
  input  logic         rst_n,
  input  logic         clear,

  // From the classifier, Section 5.
  input  logic         sweep_done,
  input  logic [15:0]  bins_declared,
  input  logic [15:0]  bins_unreachable,
  input  logic [15:0]  bins_reachable,
  input  logic [15:0]  bins_hit,
  input  logic [15:0]  bins_directed,
  input  logic [15:0]  bins_unclassified,
  input  logic [15:0]  soft_exclusions,

  // From the exclusion auditor, Section 7.
  input  logic [15:0]  excl_entries,
  input  logic [15:0]  excl_with_argument,
  input  logic [15:0]  excl_model_disagrees,

  // From the reconciler, Section 11.
  input  logic [15:0]  props_bound,
  input  logic [15:0]  props_silent,
  input  logic [15:0]  props_silent_unexplained,

  // Events the review wants counted over time rather than at the end.
  input  logic         excl_added,
  input  logic         directed_test_added,

  output logic [19:0]  cov_declared_ppm,
  output logic [19:0]  cov_reachable_ppm,
  output logic [19:0]  unreachable_ppm,
  output logic [19:0]  excl_reviewed_ppm,
  output logic [19:0]  silent_ppm,
  output logic [15:0]  c_exclusions_added,
  output logic [15:0]  c_directed_added,
  output logic [15:0]  c_unclassified,
  output logic         v_denominator_missing,
  output logic         v_exclusion_unargued,
  output logic         v_exclusion_contradicted,
  output logic         v_silent_unexplained,
  output logic         v_closed_by_editing,
  output logic         v_soft_exclusion_present
);

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n || clear) begin
      c_exclusions_added <= '0;
      c_directed_added   <= '0;
    end else begin
      if (excl_added)          c_exclusions_added <= c_exclusions_added + 16'd1;
      if (directed_test_added) c_directed_added   <= c_directed_added   + 16'd1;
    end
  end

  always_comb begin
    cov_declared_ppm  = (bins_declared  == 0) ? 20'd0
                      : 20'((int'(bins_hit) * 1000000) / int'(bins_declared));
    cov_reachable_ppm = (bins_reachable == 0) ? 20'd0
                      : 20'((int'(bins_hit) * 1000000) / int'(bins_reachable));
    unreachable_ppm   = (bins_declared  == 0) ? 20'd0
                      : 20'((int'(bins_unreachable) * 1000000)
                            / int'(bins_declared));
    excl_reviewed_ppm = (excl_entries   == 0) ? 20'd1000000
                      : 20'((int'(excl_with_argument) * 1000000)
                            / int'(excl_entries));
    silent_ppm        = (props_bound    == 0) ? 20'd0
                      : 20'((int'(props_silent) * 1000000) / int'(props_bound));

    c_unclassified = bins_unclassified;

    // Six flags. Each one names a specific sentence somebody must add.
    v_denominator_missing    = (bins_reachable == 16'd0) &&
                               (bins_declared != 16'd0);
    v_exclusion_unargued     = (excl_with_argument < excl_entries);
    v_exclusion_contradicted = (excl_model_disagrees != 16'd0);
    v_silent_unexplained     = (props_silent_unexplained != 16'd0);
    // The prohibition-3 detector: exclusions grew faster than tests.
    v_closed_by_editing      = (c_exclusions_added > c_directed_added) &&
                               (c_exclusions_added > 16'd0);
    v_soft_exclusion_present = (soft_exclusions != 16'd0);
  end

endmodule

Classification, Model or Production? A PRODUCTION-INTENT INSTRUMENT, and the one block in this chapter that would survive into a real flow unchanged, because everything it consumes is already produced somewhere in a modern verification database.

What it teaches: that v_closed_by_editing is computable and nobody computes it. Exclusions added and directed tests added are both events with timestamps in any version-controlled flow; the comparison is a subtraction, and it is the only automatic signal that Section 14's third prohibition was violated. The module also teaches the shape of excl_reviewed_ppm's empty case: a project with no exclusions is fully reviewed by definition, so the ratio returns a million rather than zero — a small decision that stops an empty file from raising a flag.

Deliberately simplified: every ratio is an integer divide with truncation, and bins_hit is treated as a single scalar where a real flow has per-covergroup hit counts that merge across runs with their own subtleties. v_closed_by_editing also has no time window, so one legitimate bulk exclusion early in a project keeps the flag set for its lifetime; a real implementation compares the two counts over a rolling window, which is Chapter 19.7 §14's differencing-counter argument applied to process metrics rather than to frames.

Production implication: the flag that earns its place is v_soft_exclusion_present, because it is the one that changes when nothing about the project changes. Six of this design's 243 exclusions are true at one peer MTU and false at another, so the flag is set for every deployment and the correct response is not to clear it — it is to record which six, name their owner, and re-run Section 5's classifier when the owner answers. A flag that cannot be cleared by the team that sees it is doing exactly what Chapter 26.1 §12's DEFERRED outcome exists for.


16. RTL 8 — The Verification Conformance Monitor

Seven checks. A plan that passes all seven has a coverage number somebody can defend; one that fails any of them has a number that means less than it appears to.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// verif_conformance -- the sign-off gate for Section 2's twenty items,
// expressed as seven checks over the outputs of Sections 5, 7, 11 and 13.
//
// The gate's design rule: every check must be able to FAIL on a plan
// that a project would actually submit. A check that no real plan fails
// is Section 20's refused property with a different name.
// ---------------------------------------------------------------------
module verif_conformance (
  input  logic         clk,
  input  logic         rst_n,

  input  logic         evaluate,

  // Section 5.
  input  logic [15:0]  bins_declared,
  input  logic [15:0]  bins_reachable,
  input  logic [15:0]  bins_hit,
  input  logic [15:0]  bins_unclassified,

  // Section 7.
  input  logic [15:0]  excl_entries,
  input  logic [15:0]  excl_with_argument,
  input  logic [15:0]  excl_model_disagrees,
  input  logic [15:0]  excl_soft,
  input  logic         excl_soft_owners_named,

  // Section 9.
  input  logic [15:0]  bins_needing_directed,
  input  logic [15:0]  directed_tests_present,

  // Section 11.
  input  logic [15:0]  props_bound,
  input  logic [15:0]  props_covered,
  input  logic [15:0]  props_silent_unexplained,

  // Section 13 -- present so the report cannot omit a unit.
  input  logic         both_denominators_reported,

  output logic         c1_denominators_reported,
  output logic         c2_model_classified,
  output logic         c3_exclusions_argued,
  output logic         c4_exclusions_uncontradicted,
  output logic         c5_soft_exclusions_owned,
  output logic         c6_directed_tests_match,
  output logic         c7_suite_reconciled,
  output logic [2:0]   n_failures,
  output logic         conformant,
  output logic         gate_can_fail        // the self-check
);

  logic [2:0] fails;

  always_comb begin
    // 1. Section 4: the report carries both fractions, or it carries
    //    an editorial decision.
    c1_denominators_reported = both_denominators_reported &&
                               (bins_reachable != 16'd0);

    // 2. Section 5: no bin is reachable, unhit and unclassified.
    c2_model_classified      = (bins_unclassified == 16'd0);

    // 3. Section 7, item 7 of Section 2.
    c3_exclusions_argued     = (excl_with_argument == excl_entries);

    // 4. Section 6's silent error: the file excludes what the rules
    //    say is reachable.
    c4_exclusions_uncontradicted = (excl_model_disagrees == 16'd0);

    // 5. Section 7: the six that depend on a deployment have owners.
    c5_soft_exclusions_owned = (excl_soft == 16'd0) ||
                               excl_soft_owners_named;

    // 6. Section 2, item 5 against item 6. A shortfall here is the
    //    difference that got closed with an editor.
    c6_directed_tests_match  = (directed_tests_present >=
                                bins_needing_directed);

    // 7. Section 11: every silent property has a sentence.
    c7_suite_reconciled      = (props_silent_unexplained == 16'd0) &&
                               (props_covered <= props_bound);

    fails = 3'(!c1_denominators_reported)     + 3'(!c2_model_classified)
          + 3'(!c3_exclusions_argued)         + 3'(!c4_exclusions_uncontradicted)
          + 3'(!c5_soft_exclusions_owned)     + 3'(!c6_directed_tests_match)
          + 3'(!c7_suite_reconciled);

    // Every check above compares two quantities the plan supplies, so
    // a plan exists that fails each one. This bit records that the gate
    // is not Section 20's refused property.
    gate_can_fail = (bins_declared != 16'd0) && (props_bound != 16'd0);
  end

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      n_failures <= '0;
      conformant <= 1'b0;
    end else if (evaluate) begin
      n_failures <= fails;
      conformant <= (fails == 3'd0) && gate_can_fail;
    end
  end

endmodule

Classification, Model or Production? A SIGN-OFF GATE.

What it teaches: that gate_can_fail is not decoration. Every other output of this module is a comparison between two numbers the plan supplies, and a plan that supplies zeros passes all seven checks — zero bins declared, zero exclusions, zero properties, seven passes. That is the exact failure Section 20 refuses, arriving inside the gate built to catch it, and the defence is one conjunct: a plan with no bins and no properties is not conformant, it is empty. The module also teaches why check 6 uses >= rather than ==: a plan with more directed tests than the arithmetic demands is over-verified, which is not a defect, and a check that punished it would push teams to delete tests.

Deliberately simplified: both_denominators_reported is an input bit where a real gate parses the generated report and confirms that both figures appear in it — which is the kind of check that is easy to write and easy to satisfy trivially, since a report can contain both numbers in a footnote. The honest implementation checks the summary line. excl_soft_owners_named is similarly one bit for six entries, where the useful form is six names.

Production implication: run this gate at every regression, not at sign-off. Six of the seven checks are computable from artefacts that already exist the day the coverage model is written — only check 2 needs a regression to have run — so a plan can be measured against its own sign-off criteria months before sign-off. The practical consequence is that c6_directed_tests_match fails in week three instead of week thirty, when twenty directed tests are still a staffing question rather than a schedule crisis, and the twenty exclusion lines that would otherwise close the report never get written.


17. The Review, Priced Against What It Prevents

The review costs a day of three people's time. Here is the arithmetic on what it buys, with each row's escape route named.

ItemIf the review skips itWhat it costs later
both denominatorsthe project defines coverage as one of theman 18-month argument about whether 93% is good, with no shared definition
the exclusion audit243 entries, none attackedsix of them wrong for this deployment, and no test will ever say so
n_unclassifiedreachable unhit bins look like exclusionsthe design is untested in a region nobody has named
the stimulus budget20 bins discovered in the last week20 exclusion lines, because six engineer-weeks no longer fit
bound against covered143 properties pass by never being askeda regression that reports 240 passes on a link that never trains
the unitsone number is quoted for four questionsa plan optimised for the number that is easiest to move

Row four is the one with a date on it. Section 8's arithmetic is computable in week three and its conclusion does not change: twenty bins, six engineer-weeks. The same conclusion reached in week thirty is not actionable, and the only remaining action is the one Section 14 prohibits.


18. What the Review Assumes

Six assumptions. Each is stated because a reader on a different design needs to know which of this chapter's numbers survive the journey.

#AssumptionIf it is false
1the four axes are the modela fifth axis multiplies every count in Section 4
2the axes are independentSection 8's rarest-bin probability is wrong, usually optimistic
3the simulator runs 2 000 cycles per wall-clock secondSection 8's hours scale inversely, and nothing else moves
4the traffic distribution is this deployment'severy probability in Section 8 is somebody else's network
5Chapter 21.4 §20's 59.6% generalisesSection 10's 143 becomes a different number; the mechanism does not change
6the exclusion rules are completethe 243 is a floor, not a count

Assumption 2 is the one that fails first and it fails in the direction that matters. The rarest bin — a jabber, above 1 518 octets, double-tagged — has a probability computed as a product of four marginals, and a jabber is correlated with large frames by definition. So the true probability is higher than 10⁻¹⁰ and the true simulation cost is lower than 23.24 simulator-years. How much lower is not knowable from marginals, which is why a real model samples a joint distribution from a capture and this one states the limitation instead.

Assumption 3 deserves a table because it is the assumption readers will most want to substitute.

Simulator throughputFrames per secondFarm-week framesBins needing a directed test
500 cycles/s10.217.35 × 10⁸more than 20
2 000 cycles/s40.842.94 × 10⁹20
8 000 cycles/s163.371.18 × 10¹⁰fewer than 20
an emulator at 1 MHz20 4211.47 × 10¹²near zero

Row four is the honest escape from this chapter's whole argument and it deserves saying plainly: an emulator changes the arithmetic by three orders of magnitude and most of Section 8's conclusions with it. What it does not change is Sections 4, 6 and 10 — the model's denominator, the exclusion file and the silent properties — because none of those is a throughput problem. An emulator closes twenty bins and leaves 243 unaudited exclusions exactly where they were.

Assumption 6 is the one that cannot be discharged from inside. Section 5's classifier knows four rules; a fifth rule would find more unreachable bins, and there is no procedure that says the list of rules is complete. So 243 is a lower bound on unreachability and 303 is an upper bound on reachability — which means Section 4's 93.399% is a pessimistic coverage figure and 51.832% is pessimistic by more. The review's honest form of this is one sentence: the reachable count is an upper bound, and here are the four rules that produced it.


19. The Cost, Accounted — in Simulation-Hours and Engineer-Weeks

Every chapter of this track has closed its accounting section with a BCE figure. This one closes with four numbers in four units and a deliberate refusal to add them.

QuantityValueUnit
coverage model declared546bins
unreachable by construction243 — 44.51%bins
reachable303bins
reached in one farm-week283 — 93.399% of reachablebins
outstanding20bins
regression budget20 000 per weeksimulation-hours
to close the outstanding 20 by random204 036 — 10.2 farm-weekssimulation-hours
to close them with directed tests6engineer-weeks
properties bound240properties
silent on an untrained link143 — 59.6%properties
silent and unexplainedtarget 0properties
exclusion entries243file lines
whose truth depends on a deployment6file lines

And the one comparison the four units support, which is the calendar.

RouteCalendarWhat else stops
20 directed tests6 engineer-weeks, in parallel with everything elsenothing
random closure10.2 weeks of 500 licencesevery other regression
20 exclusion linesone afternoonnothing — and nothing is verified

Three routes to the same closed report. Two of them cost something and one of them costs nothing, and the one that costs nothing is the one that will be taken if the review does not produce the number 20 in week three.


20. Properties Worth Asserting, and One Worth Refusing

Fifty-four properties in six groups. They are properties about a verification plan rather than about a datapath, and the same rules apply: an antecedent that can be reached, a consequent that can be false, and a cover that proves the first.

Group A — the bin model, Section 3.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 1. A hit bin is never also classified unreachable. If it is, one of
//    the two inputs is lying and the exclusion file is the suspect.
p_hit_not_unreachable: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && was_hit) |-> (outcome == BIN_HIT));

// 2. Every unreachable outcome carries a reason. A reason is what a
//    reviewer attacks; an outcome without one cannot be argued with.
p_unreachable_has_reason: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && outcome == BIN_UNREACHABLE) |-> (reason != UR_NONE));

// 3. And a reachable outcome carries none, so the two are exclusive.
p_reachable_no_reason: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && outcome != BIN_UNREACHABLE) |-> (reason == UR_NONE));

// 4. reason_is_soft is set exactly for the two deployment-dependent
//    reasons. Section 6's six bins are found by this bit.
p_soft_iff_env: assert property (@(posedge clk) disable iff (!rst_n)
  out_valid |-> (reason_is_soft ==
                 (reason == UR_ENVIRONMENT || reason == UR_CONFIG)));

// 5. A runt outside the smallest bucket is unreachable for a LENGTH
//    reason, never for a direction one.
p_runt_reason: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && bin_key.ec == ERR_RUNT && bin_key.sz != SZ_LE64)
    |-> (outcome == BIN_UNREACHABLE && reason == UR_LENGTH));

// 6. A transmit-side alignment error is unreachable for a DIRECTION
//    reason at every size.
p_tx_align_reason: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && bin_key.ec == ERR_ALIGN && bin_key.dr == DIR_TX)
    |-> (outcome == BIN_UNREACHABLE && reason == UR_DIRECTION));

// 7. The default, and the finding: not hit, no rule, no test, no
//    sentence is UNCLASSIFIED and nothing else.
p_default_unclassified: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && !was_hit && !has_directed && !has_argument &&
   reason == UR_NONE) |-> (outcome == BIN_UNCLASSIFIED));

// 8. Structural reasons never depend on a parameter.
p_structural_stable: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && (reason == UR_LENGTH || reason == UR_DIRECTION))
    |-> !reason_is_soft);

c_each_outcome_seen: cover property (@(posedge clk)
  out_valid && outcome == BIN_UNCLASSIFIED);

Group B — the classifier, Section 5.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 9. The three counts partition the declared model exactly.
p_counts_partition: assert property (@(posedge clk) disable iff (!rst_n)
  sweep_done |-> (n_unreachable + n_reachable == n_declared));

// 10. And the declared count is the model's size, not a running total.
p_declared_is_model: assert property (@(posedge clk) disable iff (!rst_n)
  sweep_done |-> (n_declared == 16'(N_BINS)));

// 11. The reachable bins partition into the three dispositions.
p_reachable_partition: assert property (@(posedge clk) disable iff (!rst_n)
  sweep_done |-> (n_hit + n_directed + n_unclassified <= n_reachable));

// 12. Both fractions are produced, and neither is produced alone.
p_both_fractions: assert property (@(posedge clk) disable iff (!rst_n)
  (sweep_done && n_declared != 0 && n_reachable != 0)
    |-> (cov_vs_declared_ppm <= cov_vs_reachable_ppm));

// 13. The declared fraction can never exceed the reachable one, which
//     is the arithmetic form of "excluding bins raises coverage".
p_declared_le_reachable: assert property (@(posedge clk) disable iff (!rst_n)
  sweep_done |-> (cov_vs_declared_ppm <= cov_vs_reachable_ppm));

// 14. Soft exclusions are a subset of exclusions.
p_soft_subset: assert property (@(posedge clk) disable iff (!rst_n)
  sweep_done |-> (n_soft_exclusions <= n_unreachable));

// 15. A sweep that starts finishes, in a bounded number of cycles.
p_sweep_terminates: assert property (@(posedge clk) disable iff (!rst_n)
  sweep_start |-> ##[1:N_BINS+2] sweep_done);

c_sweep_completed: cover property (@(posedge clk) sweep_done);
c_unclassified_nonzero: cover property (@(posedge clk)
  sweep_done && n_unclassified != 16'd0);

Group C — the exclusion auditor, Section 7.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 16. Entries with an argument never exceed entries.
p_argued_subset: assert property (@(posedge clk) disable iff (!rst_n)
  (n_with_argument <= n_entries));

// 17. file_is_reviewed is exactly the equality, not a threshold.
p_reviewed_is_equality: assert property (@(posedge clk) disable iff (!rst_n)
  file_is_reviewed == (n_entries == n_with_argument));

// 18. Soundness implies reviewedness, and never the converse.
p_sound_implies_reviewed: assert property (@(posedge clk) disable iff (!rst_n)
  file_is_sound |-> file_is_reviewed);

// 19. A disagreement between the file and the model is recorded, and
//     this is the ONLY place Section 6's silent error becomes visible.
p_disagreement_counted: assert property (@(posedge clk) disable iff (!rst_n)
  (entry_valid && !model_unreachable)
    |-> ##1 (n_model_disagrees == $past(n_model_disagrees) + 16'd1));

// 20. An entry the model calls soft is counted soft regardless of what
//     the file claims, because the file is the thing under audit.
p_soft_from_model: assert property (@(posedge clk) disable iff (!rst_n)
  (entry_valid && model_soft)
    |-> ##1 (n_soft == $past(n_soft) + 16'd1));

// 21. A sound file has no disagreements, by construction.
p_sound_no_disagree: assert property (@(posedge clk) disable iff (!rst_n)
  file_is_sound |-> (n_model_disagrees == 16'd0));

c_file_unsound: cover property (@(posedge clk)
  n_entries != 16'd0 && !file_is_sound);
c_soft_present: cover property (@(posedge clk) n_soft != 16'd0);

Group D — the stimulus budget, Section 9.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 22. A bin reachable by random never also needs a directed test.
p_random_xor_directed: assert property (@(posedge clk) disable iff (!rst_n)
  out_valid |-> (reachable_by_random != needs_directed));

// 23. A gap is exactly "needs one and has none".
p_gap_definition: assert property (@(posedge clk) disable iff (!rst_n)
  out_valid |-> (gap == (needs_directed && !has_directed_test)));

// 24. Zero probability is never reachable by random, however long the
//     run. This is the bin that a coverage model should not contain.
p_zero_p_never: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && $past(bin_p_e12) == 40'd0) |-> !reachable_by_random);

// 25. Frames needed falls as probability rises -- monotonicity, which
//     is the cheapest guard against a scaling error in the divide.
p_frames_monotone: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && $past(bin_p_e12) > $past(bin_p_e12, 2) &&
   $past(bin_p_e12, 2) != 40'd0)
    |-> (frames_needed_e0 <= $past(frames_needed_e0)));

// 26. Weeks needed is at least one whenever frames needed is non-zero.
p_weeks_ceiling: assert property (@(posedge clk) disable iff (!rst_n)
  (out_valid && frames_needed_e0 != 48'd0) |-> (weeks_needed >= 32'd1));

// 27. Gaps are a subset of the bins needing a directed test.
p_gaps_subset: assert property (@(posedge clk) disable iff (!rst_n)
  (n_gaps <= n_needing_directed));

c_gap_seen: cover property (@(posedge clk) gap);

Group E — the assertion reconciler, Section 11.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 28. Covered properties never exceed bound ones.
p_covered_le_bound: assert property (@(posedge clk) disable iff (!rst_n)
  (n_covered <= n_bound));

// 29. The three categories partition the bound suite.
p_suite_partition: assert property (@(posedge clk) disable iff (!rst_n)
  (n_covered + n_silent == n_bound));

// 30. And silence partitions into explained and not.
p_silence_partition: assert property (@(posedge clk) disable iff (!rst_n)
  (n_silent_explained + n_silent_unexplained == n_silent));

// 31. A property with a non-zero cover count is never counted silent.
p_covered_not_silent: assert property (@(posedge clk) disable iff (!rst_n)
  (prop_valid && prop_bound && prop_cover_count != 32'd0)
    |-> ##1 (n_silent == $past(n_silent)));

// 32. Reconciliation is about the unexplained count, never about zero
//     silence -- a healthy suite has silent properties.
p_reconciled_definition: assert property (@(posedge clk) disable iff (!rst_n)
  suite_is_reconciled == (n_silent_unexplained == 16'd0));

// 33. An honest report needs a non-empty denominator as well as a
//     reconciled suite.
p_honest_needs_covered: assert property (@(posedge clk) disable iff (!rst_n)
  report_is_honest |-> (n_covered != 16'd0));

// 34. Traffic-dependent properties are a subset of the bound suite.
p_traffic_subset: assert property (@(posedge clk) disable iff (!rst_n)
  (n_traffic_dependent <= n_bound));

c_silent_but_reconciled: cover property (@(posedge clk)
  n_silent != 16'd0 && suite_is_reconciled);

Group F — effort, telemetry and the gate, Sections 13, 15 and 16.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// 35. The effort reconciler never emits a quantity combining units.
//     Expressed as what it DOES emit: four independent outputs.
p_units_independent: assert property (@(posedge clk) disable iff (!rst_n)
  reconcile |-> ##1 (u_bins_outstanding == $past(bins_reachable) -
                                           $past(bins_hit)));

// 36. Engineer-weeks round up -- a part week is a whole week of a
//     calendar, and rounding down understates every plan.
p_eng_weeks_ceiling: assert property (@(posedge clk) disable iff (!rst_n)
  (reconcile && $past(bins_needing_directed) != 16'd0)
    |-> ##1 (u_eng_weeks_to_close >= 16'd1));

// 37. The dimensionless ratios are bounded, which catches a divide
//     whose operands were swapped.
p_ppm_bounded: assert property (@(posedge clk) disable iff (!rst_n)
  (unreachable_share_ppm <= 20'd1000000) &&
  (silent_share_ppm      <= 20'd1000000));

// 38. Telemetry: the editing detector fires only when exclusions have
//     actually been added.
p_editing_needs_exclusions: assert property (@(posedge clk) disable iff (!rst_n)
  v_closed_by_editing |-> (c_exclusions_added != 16'd0));

// 39. An empty exclusion file is fully reviewed, not unreviewed.
p_empty_file_reviewed: assert property (@(posedge clk) disable iff (!rst_n)
  (excl_entries == 16'd0) |-> (excl_reviewed_ppm == 20'd1000000));

// 40. The unargued flag is exactly the inequality.
p_unargued_flag: assert property (@(posedge clk) disable iff (!rst_n)
  v_exclusion_unargued == (excl_with_argument < excl_entries));

// 41. Every conformance check is a comparison between two supplied
//     quantities, so each one can be false. Expressed per check:
p_c2_can_fail: assert property (@(posedge clk) disable iff (!rst_n)
  (evaluate && bins_unclassified != 16'd0) |-> ##1 !c2_model_classified);

// 42. Check 6 is a floor, not an equality: extra directed tests are
//     never a failure.
p_c6_is_floor: assert property (@(posedge clk) disable iff (!rst_n)
  (evaluate && directed_tests_present > bins_needing_directed)
    |-> ##1 c6_directed_tests_match);

// 43. Conformance requires the gate itself to be non-trivial.
p_conformant_needs_gate: assert property (@(posedge clk) disable iff (!rst_n)
  conformant |-> $past(gate_can_fail));

// 44. An empty plan is never conformant. This is the property that
//     stops the gate from becoming Section 20's refused one.
p_empty_plan_fails: assert property (@(posedge clk) disable iff (!rst_n)
  (evaluate && bins_declared == 16'd0) |-> ##1 !conformant);

// 45. The failure count matches the failing checks.
p_failure_count: assert property (@(posedge clk) disable iff (!rst_n)
  (evaluate && c1_denominators_reported && c2_model_classified &&
   c3_exclusions_argued && c4_exclusions_uncontradicted &&
   c5_soft_exclusions_owned && c6_directed_tests_match &&
   c7_suite_reconciled) |-> ##1 (n_failures == 3'd0));

// 46. Soft exclusions without owners fail check 5, always.
p_c5_needs_owners: assert property (@(posedge clk) disable iff (!rst_n)
  (evaluate && excl_soft != 16'd0 && !excl_soft_owners_named)
    |-> ##1 !c5_soft_exclusions_owned);

// 47. A contradicted exclusion fails check 4, always.
p_c4_contradiction: assert property (@(posedge clk) disable iff (!rst_n)
  (evaluate && excl_model_disagrees != 16'd0)
    |-> ##1 !c4_exclusions_uncontradicted);

// 48. And the gate is stable between evaluations.
p_gate_stable: assert property (@(posedge clk) disable iff (!rst_n)
  !evaluate |-> ##1 (conformant == $past(conformant)));

// The covers that make the whole group mean something. Each one is a
// plan a project would really submit.
c_plan_with_unclassified: cover property (@(posedge clk)
  evaluate && bins_unclassified != 16'd0);
c_plan_closed_by_editing: cover property (@(posedge clk)
  evaluate && directed_tests_present < bins_needing_directed);
c_plan_conformant: cover property (@(posedge clk) evaluate && conformant);
c_empty_plan_submitted: cover property (@(posedge clk)
  evaluate && bins_declared == 16'd0);
c_soft_unowned: cover property (@(posedge clk)
  evaluate && excl_soft != 16'd0 && !excl_soft_owners_named);
c_both_fractions_reported: cover property (@(posedge clk)
  evaluate && both_denominators_reported);

21. Verification Scenarios

Fifty-eight scenarios in six groups, plus one directed test random stimulus will not produce.

Group 1 — the bin model (10).

#ScenarioExpect
1a hit binBIN_HIT; reason = UR_NONE
2a runt in SZ_65_127BIN_UNREACHABLE; UR_LENGTH; not soft
3a jabber in SZ_512_1023BIN_UNREACHABLE; UR_LENGTH
4a jabber in SZ_GE1519reachable — the one bucket it lives in
5a transmit-side symbol errorUR_DIRECTION
6a transmit-side alignment errorUR_DIRECTION — a transmitter emits whole octets
7an MTU mismatch in SZ_256_511, MTU_BUCKET = 5UR_ENVIRONMENT; reason_is_soft high
8the same bin, MTU_BUCKET = 4reachable — the six bins of Section 6
9not hit, no rule, no test, no argumentBIN_UNCLASSIFIED — the finding
10the same with an argumentBIN_UNREACHABLE; UR_CONFIG; soft

Group 2 — the classifier (10).

#ScenarioExpect
11a full sweepn_declared = 546
12the samen_unreachable = 243; n_reachable = 303
13MTU_BUCKET = 4237 and 309
14MTU_BUCKET = 6249 and 297
15283 hits, MTU_BUCKET = 5518 315 ppm and 933 993 ppm
16283 hits, MTU_BUCKET = 4915 857 ppm against reachable
17303 hits1 000 000 ppm against reachable, 554 945 against declared
18zero reachable binscov_vs_reachable_ppm = 0 — the guarded divide
19a sweep interruptedsweep_done low; counts hold
20n_soft_exclusions6 at MTU_BUCKET = 5

Group 3 — the exclusion auditor (10).

#ScenarioExpect
21243 entries, 243 argumentsfile_is_reviewed high
22243 entries, 200 argumentslow; v_exclusion_unargued
23every entry agreeing with the modelfile_is_sound high
24one entry the model calls reachablen_model_disagrees = 1; file_is_sound LOW
25the same entry's effect on coveragenone — an excluded bin is not sampled
26an entry claiming UR_LENGTH where the model says UR_DIRECTIONn_reason_mismatch = 1; both still exclusions
27six entries the model calls softn_soft = 6
28an empty exclusion filereviewed and sound; excl_reviewed_ppm = 1 000 000
29a file of 20 entries added in the final weekv_closed_by_editing if tests did not also grow
30the same with 20 directed tests addedflag clear

Group 4 — the stimulus budget (10).

#ScenarioExpect
31p = 10⁻¹⁰, one farm-weeknot reachable by random; needs directed
32the same, no directed testgap high; n_gaps increments
33the same with a testgap low
34p = 10⁻⁶3 × 10⁶ frames — inside one farm-week
35p = 0never reachable, at any budget
36the rarest bin's frames at 95%2.996 × 10¹⁰
37the same in simulation203 764 hours — 23.24 simulator-years
38the same on the wire at 100 Gb/s1 222.6 s — twenty minutes
39CONF_MULT = 1 instead of 3a third of the rarest bins planned as reachable and missed
40the whole model swept20 bins needing a directed test

Group 5 — the assertion reconciler (10).

#ScenarioExpect
41240 bound, 240 coveredn_silent = 0; reconciled
42240 bound, 97 coveredn_silent = 143 — the untrained link
43the same, all 143 explainedsuite_is_reconciled HIGH — and correctly so
44the same, 12 unexplainedlow; v_silent_unexplained
45a property with pass 0 and fail 0silent, not failing — the two zeros
46a property with pass 0 and fail 40covered, and failing — a real bug
47a property excluded by generatenot bound; outside every count
48143 of 240 traffic-dependenttraffic_dep_ppm = 595 833
49the regression on a healthy link240 covered; the 143 fire normally
50n_covered = 0 on a completed runreport_is_honest LOW — nothing was asked

Group 6 — effort, telemetry and the gate (8).

#ScenarioExpect
5120 bins, 1.5 engineer-days each6 engineer-weeks
523 × 10¹⁰ frames at 40.84 f/s204 036 simulation-hours; 10.2 farm-weeks
53the two compareddirected_is_cheaper high
54243 of 546 unreachableunreachable_share_ppm = 445 054
55an empty plan submitted to the gategate_can_fail LOW; conformant LOW
5625 directed tests where 20 are neededcheck 6 passes — a floor, not an equality
57six soft exclusions, no ownerscheck 5 fails
58all seven checks clear on a non-empty planconformant high

22. Debugging a Coverage Report That Closed

Six symptoms, and five of them arrive after the coverage report said 100%.

SymptomFirst questionWhere to look
a field escape in a frame shape the plan lists as coveredwas that bin excluded?Section 6 — an excluded bin is not sampled, in either direction
a directed test that has never hitis its bin actually reachable?Section 7 — the loud half of the asymmetry; the model says no
coverage that jumped in the final week without new testshow many exclusions were added?Section 15's v_closed_by_editing
a regression reporting all passes on a broken linkwhat was the cover count?Section 10 — 143 of 240 can pass by never being asked
two teams quoting different coverage for one runwhich denominator?Section 4 — 51.832% and 93.399%
a bin nobody can explain and nobody excludedwas it ever classified?Section 5's n_unclassified — the default outcome

Row one has a procedure and it is the one worth memorising. Take the escaping frame, compute its four axis values, form the bin index, and grep the exclusion file for it. If it is there, read the argument; if there is no argument, the investigation is over and the answer is that nobody ever decided this frame could not happen.

Row three's procedure is shorter. git log the exclusion file. Every line added in the last month is a bin somebody chose not to test, and the review's question is whether a sentence was added with it.


23. Misconceptions

Six, in the wrong-model / what-it-costs / corrected-model form this track has used since Chapter 1.1.

Misconception 1 — "Coverage is a percentage."

Wrong model. One number, between zero and one hundred, that summarises how thoroughly a design was tested.

What it costs. Section 4's arithmetic: the same 283 hit bins are 51.832% or 93.399% depending on a setting in a configuration file. The cost is eighteen months of a project in which two teams quote different figures for the same run and neither is wrong, and the schedule gets managed against whichever one is easier to move — which is always the one with the larger denominator, because exclusions raise it for free.

Corrected model. Coverage is a fraction, and a fraction has two numbers. Report hit, reachable and declared as integers; anybody who wants a percentage can divide. A report carrying three integers cannot be quoted misleadingly; one carrying a percentage almost always is, because the denominator travels in a config file and the number travels in an e-mail.

Misconception 2 — "An exclusion is a fact about the design."

Wrong model. A bin gets excluded because the design cannot produce it, and that is a property of the RTL.

What it costs. Six of this design's 243 exclusions are properties of somebody else's network. Section 6: the MTU-mismatch rule's threshold is the peer's MTU, so the exclusion list is 237 entries at one deployment and 249 at another — and shipping one file for every deployment hard-codes a customer's configuration into the definition of "verified".

Corrected model. Exclusions have two kinds, exactly like Chapter 26.1 §12's thresholds. Structural exclusions are theorems about the frame definition and a reviewer can check them in a meeting. Environmental exclusions are claims about a deployment, they need an owner, and the classifier must be re-run when the owner answers. Section 3's reason_is_soft is one bit and it separates the two.

Misconception 3 — "A wrong exclusion will show up eventually."

Wrong model. If we exclude something we should not have, a test will fail or a coverage hole will appear.

What it costs. The asymmetry of Section 6, and it is total. A coverage flow's response to an exclusion is to stop instrumenting the bin — so a wrongly excluded bin produces no pass, no fail, no warning and no anomalous percentage. Section 21's directed test is exactly this: two files, seven identical observables, and the difference visible in nothing the flow prints.

Corrected model. The only thing that catches a wrong exclusion is an independent model of reachability, and Section 5 is 60 lines of it. The opposite error — leaving an impossible bin in — is caught free of charge by a directed test that never hits, which is why projects have a strong intuition that exclusions are self-correcting. They are self-correcting in exactly one direction, and it is not the dangerous one.

Misconception 4 — "More simulation will close the last few bins."

Wrong model. The regression is at 93%; another week or two of farm time will finish it.

What it costs. Section 8's arithmetic: closing the last twenty bins by random stimulus needs 204 036 simulation-hours — 10.2 weeks of all 500 licences, running nothing else. And the reason is not the design: it is that the simulator runs 600 000 times slower than the wire, so twenty minutes of a real link is 23.24 simulator-years for the rarest bin. Another week of farm time closes approximately none of them.

Corrected model. The tail of a coverage model is a directed-test problem, and it is knowable in week three. Probability per bin, frames per farm-week, the count that does not fit — twenty bins, six engineer-weeks. A project that computes it early spends six engineer-weeks; one that computes it late spends an afternoon on exclusions, because by then that is all that fits.

Misconception 5 — "All 240 assertions passed, so the design is behaving."

Wrong model. A green regression means every bound property held.

What it costs. Chapter 21.4 §20's measurement: 332 of 557 published properties — 59.6% — have antecedents that need traffic. On a link that never trains, 143 of a 240-property suite stop evaluating and 97 evaluate; the report says 240 passed. The cost is a week of debugging a "working" design, because the instrument that would have said otherwise reported success.

Corrected model. A pass count means nothing without a cover count. Chapter 25.6 §20's fourth property is one line and every tool already computes both halves — but assert the classified form rather than the equality, because a healthy suite legitimately has silent properties and a check that fires every night gets deleted.

Misconception 6 — "Verification cost and area cost can be traded off."

Wrong model. Spend more die on a simpler block and save verification effort; the two are a single budget.

What it costs. They are not correlated, even in sign. Chapter 23.5 §6's programmable array is 78.6 MAC datapaths and harder to verify, because its behaviour is chosen by software the plan never sees. Chapter 19.4's CRC engine is large and among the easiest blocks in the MAC to verify exhaustively, because its specification is a polynomial. Two examples in one track, opposite signs.

Corrected model. Four units, no exchange rate, and one comparison — the calendar. Section 12: bins, simulation-hours, engineer-weeks and silent properties are four answers to four questions, and the only legitimate comparison between a simulation-hour and an engineer-week is which one occupies more of the schedule.


24. Interview Questions

Six, with what a strong answer contains.

1. What is your coverage?

A strong answer refuses the single number and gives three integers. "546 declared, 303 reachable, 283 hit" — and then volunteers the 243, because the follow-up question is always about the denominator and the candidate who raises it first has demonstrated they know it exists. A weak answer is a percentage. A weak answer that sounds strong is a percentage with a confidence adjective attached.

2. You have 243 excluded bins. How do you know they are right?

The strong answer is that you do not, and here is the check. An independent reachability model, applied to the file, producing the count of disagreements — Section 7's n_model_disagrees. The stronger half of the answer is the asymmetry: a wrongly excluded bin is silent and a wrongly included one is loud, so the check is only needed in one direction and that is the direction nothing else covers.

3. Your regression reports 240 of 240 assertions passing. What else do you need to know?

The cover counts. And the number to have ready is Chapter 21.4 §20's 59.6% — the measured share of published properties whose antecedent needs traffic. On a link that never trains, 143 of those 240 stop evaluating and the report is identical. A candidate who has this number has read a corpus rather than an opinion.

4. How long would it take to close the last twenty coverage bins?

Two answers, both of them arithmetic. By random stimulus: the rarest bin needs 3 × 10¹⁰ frames, which at 40.84 frames per simulated second is 204 036 hours — 10.2 weeks of a 500-licence farm. By directed test: twenty tests, 1.5 engineer-days each, six engineer-weeks. The strong part of the answer is that these are different units that meet only in the schedule, and the third route — twenty lines in the exclusion file — takes an afternoon and verifies nothing.

5. Why is verification effort not measured in gate-equivalents?

Because area is a property of the object and effort is a property of the process. Area scales with units shipped and is fixed at tape-out; effort is spent once and partly recovered on the next design. And they are not correlated in sign — Section 12's two examples run in opposite directions in the same track. A quantity that can move either way against another is not convertible into it.

6. Write the property that catches a wrong exclusion.

The trap is that the natural answer is a counting identity, and Section 20 is about why it fails. n_hit + n_directed + n_unclassified + n_unreachable == n_declared is falsifiable, useful and invariant under exactly the error — swap one reachable bin for one unreachable one and every term is unchanged. The property that works is a membership check: no bin the rules call reachable may appear in the file. A strong answer names the distinction between a cardinality and a set, and keeps the counting identity as well, because it catches a different bug.


25. Questions and Answers


26. What's Next

This chapter took Chapter 26.1's grammar — every item a number, every number a deriving chapter — and applied it where the numbers are fractions whose denominators the team chooses.

Three results are worth carrying forward.

ResultValueWhy it travels
unreachable share of a cross-product model44.51%a property of how coverage models are written
share of properties needing traffic59.6%measured across three modules in Chapter 21.4 §20
simulator against wire600 000×it is the clock ratio, and it sets every stimulus argument

What is left of Module 26.

NextWhat it adds
Chapter 26.3 — Performance and Debug Reviewthe seven environmental thresholds Chapter 26.1 §12 deferred, the percentile that 912.88 ns is missing, and what observability the measurement costs
Chapter 26.4 — How Ethernet Is Actually Probedthe whole of it as an interview subject, and what the track's 124 rejected-property classes have in common

And the sentence this chapter ends on is the one Chapter 25.6 §20 and Chapter 26.1 §21 both reached, now with a second edge on it. A check is worth exactly the set of observations that would have refuted it — and Section 20 adds that a check over a collection's size has a large refutation set which excludes every swap inside the collection. So the set can be big and still have the wrong shape, and the only way to know is to ask what the requirement was about: which things, or how many.


Continue learning

Standards & specifications

Governing standard
IEEE Std 802.3 (Ethernet)(opens IEEE in a new tab)

Defines the Ethernet MAC, the media-independent interfaces and the physical-layer sublayers, including framing, access control, auto-negotiation and per-rate PHY specifications. VLAN tagging, priority and time-sensitive shaping are defined by IEEE 802.1, not by 802.3.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of the Ethernet curriculum.