Skip to content
VLSI Mentor

Ethernet · Module 21

Negotiation Failures

A duplex mismatch loses 95.78% of the collisions on a maximum-size frame and exactly none on a minimum-size one, which is why ping works and the transfer does not.

Chapter 11.4 built the symptom matrix and measured what each symptom is worth in bits. This chapter prices the most expensive of its seven causes, and the price turns out to depend on the frame size in a way that explains the commonest report in networking.

Offered load at the full-duplex end64-octet frames5121 5189 000
1%0.00%0.87%0.95%0.99%
10%0.00%8.33%9.12%9.45%
25%0.00%19.35%21.19%21.96%
50%0.00%34.43%37.69%39.07%

The first column is exactly zero at every load and it is a structural zero rather than a small number. A 64-octet frame is 512 bits — precisely the slot time — so a collision on one can never be a late collision, and a collision that is not late is retried by the MAC and succeeds. Minimum-size traffic on a duplex-mismatched link is delayed and not lost.

A 1 518-octet frame is 12 144 bits, of which 11 632 lie beyond the slot time: 95.78%. A collision on one is almost certainly late, a late collision is not retried, and the frame is gone.

Ping works and the file transfer does not, and the ratio between them is 95.78 to 0.

And the two ends of the same cable report two different faults.

The half-duplex endThe full-duplex end
what it seescollisions, late collisions, deferralsFCS errors and fragments
which counters movetransmit-sidereceive-side
Chapter 21.1's method saysnot its space — no receive faultthe channel, the PHY or the xMII
where the fault isneither end's receive pathneither end's receive path

Row three is the finding. Run Chapter 21.1's procedure at the full-duplex end and it points outward at the cable, correctly following its own table — and the cable is fine. The frames really were cut; they were cut by the far end's MAC aborting them.


1. Scope, and Pricing a Matrix Somebody Else Built

Scope: what a duplex mismatch costs, as a function of offered load and frame size; which counters move at each end; and why the same link produces two incompatible diagnoses.

Not in scope: the taxonomy. Chapter 11.4 §2 enumerated seven ways a link comes up wrong, §3 built the symptom matrix and measured each row's information content, and §15 rejected the property that a symptom implies a cause. All of that stands and none of it is repeated here. This chapter takes cause 1 — the duplex mismatch — and asks what it costs.

Nor a link that will not come up. Chapter 21.4 owns that, and the boundary is sharp: here every rung of Chapter 3.8 §2's ladder passed. The link is up, frames are flowing, and what is wrong is what the two ends agreed about how to use it.

Start from what Chapter 11.4 §3 already established, because the pricing question comes directly out of it.

SymptomCauses it is consistent withBits
collisions at one end only2 of 71.81
late collisions21.81
FCS errors under load31.22
speed below expectation40.81
zero errors, low throughput50.49

The two most decisive symptoms are the two this chapter is about, and Chapter 11.4 §3 noted that both require the far end: "collisions at one end only" is by construction a statement about two ends, and a late collision is decisive only when paired with the other end's collision count being zero.

What that chapter did not ask is how often those symptoms occur. A symptom worth 1.81 bits that never appears is worth nothing, and this chapter's whole content is that the occurrence rate is a function of two things the network chooses rather than of the fault.

Decides whether the symptom appears
the offered load at the full-duplex endcollision probability — Section 4
the frame sizewhether a collision is late — Section 6
the faultpresent or not, and that is all

Three inputs, and the fault is the one that contributes least to whether anybody notices. A mismatched link carrying minimum-size traffic at one per cent load is indistinguishable from a healthy one by every counter in the space, forever.


2. What a Duplex Mismatch Physically Is

A duplex mismatch puts a half duplex media access controller at one end of a link and a full duplex one at the other. The half duplex end senses carrier before transmitting, defers while the line is busy, and watches for a collision throughout its own transmission. The full duplex end does none of those things: it transmits whenever it has something to send, because on a full duplex link there is no reason to wait. So the full duplex end transmits into a frame that is already in flight. The half duplex end detects carrier and transmission at once, which is the definition of a collision, and does exactly what the standard requires: it emits a jam pattern, abandons the frame, backs off and retries. The full duplex end experiences nothing at all, because a collision is not an event it has. What it does experience is the arrival of a short frame with a bad check value, which is the remains of the frame the other end abandoned. The second consequence is that the damage is one directional. Nothing about carrier sense multiple access interferes with reception, so the half duplex end receives the full duplex end's frames perfectly. Only the half duplex end's transmissions are damaged, which means a throughput test measuring the other direction reports a healthy link, and reports it correctly.Half-duplex endsenses, defers,detectsFull-duplex endtransmits regardlessA physicaloverlapone eventIt calls it acollisionjam, abandon, back offIt calls itnothingnot an event it hasIt receives afragmentshort, bad check valueFD to HD:unaffectedreception is fine12
Figure 1 — one physical overlap, two completely different experiences, and damage in one direction only.

One end runs Chapter 9.1's CSMA/CD and the other does not, and every consequence follows from that single asymmetry.

The half-duplex endThe full-duplex end
before transmittingsenses carrier and deferstransmits immediately
during transmissionwatches for a collisiondoes not look
on a collisionjams, backs off, retriesno such event exists
while receivingwill not start a transmissiontransmits anyway

Row four is the mechanism. The full-duplex end transmits while the half-duplex end is transmitting, because it has no reason not to. The half-duplex end detects that as a collision — carrier sense and transmission at once is the definition — and does exactly what the standard tells it to: jam, abandon, back off, retry.

So the two ends experience the same physical event completely differently.

What happens
the full-duplex end transmits mid-framea physical overlap on the pair
the half-duplex end calls ita collision
the full-duplex end calls itnothing — it is not looking
the half-duplex end's frametruncated, jammed, abandoned
the full-duplex end receivesa short frame with a bad check value

Row five is what makes this a Module 21 problem rather than a Module 11 one. Chapter 11.4 diagnoses the negotiation; this chapter is about what the counters do afterwards — and the full-duplex end's receive counters fill up with exactly the pattern Chapter 21.2 §17 called archaeology.

Two properties of the mismatch that decide everything after this.

First, it is unidirectional in its effect. The half-duplex end receives perfectly well: nothing about CSMA/CD interferes with reception, and the full-duplex end's frames arrive intact. Only the half-duplex end's transmissions are damaged.

DirectionAffected?
full-duplex → half-duplexno
half-duplex → full-duplexyes, and severely

A one-directional throughput test therefore reports a healthy link half the time, depending on which direction it measured — and Section 14's third prohibition is about that.

Second, the damage is a function of when the overlap starts, not whether it happens. Chapter 9.1 §5 established that a collision detected within the slot time — 512 bit times — is a normal collision: the frame is abandoned early, backed off and retried, and no data is lost. A collision detected after the slot time is a late collision, and 802.3 does not require the MAC to retry it. The frame is discarded.

A normal collision costs time. A late collision costs the frame. The boundary is 512 bit times, and it is a fixed number of bits rather than a fraction of a frame.

That fixed boundary against a variable frame length is the whole of Sections 6, 7 and 8.


3. RTL 1 — The Mismatch Package and the Collision Classifier

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// dupmis_pkg -- the slot time, the two collision kinds, and the two
// ends' counter sets.
//
// The package's one structural claim: the slot time is a fixed number
// of BITS and a frame is a variable number of bits, so the fraction of
// a frame that is "late" is a function of its length. Everything in
// Sections 6 to 8 is that ratio.
// ---------------------------------------------------------------------
package dupmis_pkg;

  // Chapter 9.1 Section 5's slot time. 512 bit times at 10 and 100
  // Mb/s; it is not a fraction of anything.
  localparam int SLOT_BITS = 512;

  typedef enum logic [1:0] {
    COLL_NONE  = 2'd0,
    COLL_EARLY = 2'd1,   // within the slot time -- retried, costs time
    COLL_LATE  = 2'd2    // beyond it -- not retried, costs the frame
  } coll_kind_e;

  // Which counters a duplex mismatch moves, and at WHICH end. The
  // split is the chapter's second subject: transmit-side at one end,
  // receive-side at the other, and no overlap at all.
  typedef enum logic [2:0] {
    CNT_COLLISIONS   = 3'd0,   // half-duplex end, transmit
    CNT_LATE_COLL    = 3'd1,   // half-duplex end, transmit
    CNT_EXCESS_COLL  = 3'd2,   // half-duplex end, transmit
    CNT_DEFERRED     = 3'd3,   // half-duplex end, transmit
    CNT_FCS_ERRORS   = 3'd4,   // full-duplex end, receive
    CNT_FRAGMENTS    = 3'd5,   // full-duplex end, receive
    CNT_UNDERSIZE    = 3'd6    // full-duplex end, receive
  } counter_e;

  localparam logic [6:0] HALF_DUPLEX_END = 7'b000_1111;
  localparam logic [6:0] FULL_DUPLEX_END = 7'b111_0000;

  // Section 6: the fraction of a frame that lies beyond the slot time.
  // Returned in parts per thousand because there is no float here.
  function automatic int late_fraction_ppt(int wire_len_octets);
    int bits = wire_len_octets * 8;
    if (bits <= SLOT_BITS) return 0;
    return ((bits - SLOT_BITS) * 1000) / bits;
  endfunction

  // Chapter 5.1's minimum frame is 64 octets = 512 bits = the slot
  // time exactly. That is not a coincidence: Chapter 9.1 sized one
  // from the other, and it is why minimum-size traffic loses nothing.
  localparam int MIN_FRAME_OCTETS = 64;

endpackage

Classification: a package whose entire content is one constant, one enum and one ratio.

What it teaches: that the minimum frame size and the slot time are the same 512 bits, and that the coincidence is a design decision rather than an accident. Chapter 9.1 sized the minimum frame so that a transmitter is still transmitting when the furthest collision could reach it — and the consequence, three decades later, is that a minimum-size frame can never suffer a late collision, because there is no part of it beyond the slot time.

And it teaches that the two counter sets do not overlap at all. HALF_DUPLEX_END is four transmit counters; FULL_DUPLEX_END is three receive counters; HALF_DUPLEX_END & FULL_DUPLEX_END is zero. Two ends of one cable, one fault, and not a single counter in common — which is why Section 10's correlation needs both ends' data rather than a comparison of like with like.

Deliberately simplified: SLOT_BITS is 512, which is correct at 10 and 100 Mb/s and wrong at 1 Gb/s, where carrier extension makes the slot time 4 096 bit times — and a gigabit duplex mismatch is rare because gigabit half-duplex is rare. late_fraction_ppt uses integer arithmetic in parts per thousand, so 1 518 octets returns 957 rather than 95.78%. And counter_e has seven members where a real MAC's RMON set distinguishes single from multiple collisions, which matters for Section 4's retry arithmetic and not for the loss.

Production implication: the gigabit exception is worth carrying in a real implementation because it inverts the chapter's headline. At a 4 096-bit slot time a 512-octet frame is 4 096 bits — entirely within the slot — so the late fraction is zero up to 512 octets rather than up to 64. The frame sizes that lose data move by a factor of eight, and a diagnosis calibrated at 100 Mb/s will report a gigabit mismatch as healthy for everything below 512 octets.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// collision_kind_split -- classify a collision by WHEN it happened,
// because that decides whether the frame survives.
//
// Chapter 9.1 Section 5: a collision inside the slot time is normal
// contention and the MAC retries. Outside it, the standard does not
// require a retry, and a conforming half-duplex segment cannot produce
// one -- so a late collision is evidence of a configuration fault
// rather than of traffic.
// ---------------------------------------------------------------------
module collision_kind_split
  import dupmis_pkg::*;
(
  input  logic        clk,
  input  logic        rst_n,

  input  logic        tx_active,
  input  logic        collision_detected,
  input  logic [15:0] bits_transmitted,   // into the current frame

  output coll_kind_e  kind,
  output logic        kind_valid,
  output logic [31:0] c_early,
  output logic [31:0] c_late,
  output logic [31:0] c_frames_lost,
  output logic [31:0] c_frames_delayed,
  output logic        late_seen
);
  always_comb begin
    if (!collision_detected || !tx_active)      kind = COLL_NONE;
    else if (bits_transmitted <= 16'(SLOT_BITS)) kind = COLL_EARLY;
    else                                         kind = COLL_LATE;
    kind_valid = collision_detected && tx_active;
  end

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      c_early <= '0; c_late <= '0;
      c_frames_lost <= '0; c_frames_delayed <= '0; late_seen <= 1'b0;
    end else if (kind_valid) begin
      case (kind)
        COLL_EARLY: begin
          c_early <= c_early + 32'd1;
          // The frame is not lost. It is backed off and retried, and
          // the cost is latency rather than data.
          c_frames_delayed <= c_frames_delayed + 32'd1;
        end
        COLL_LATE: begin
          c_late <= c_late + 32'd1;
          c_frames_lost <= c_frames_lost + 32'd1;
          late_seen <= 1'b1;
        end
        default: ;
      endcase
    end
  end
endmodule

Classification: a one-comparison classifier whose two outcomes have completely different costs.

What it teaches: that c_frames_delayed and c_frames_lost are the two numbers, and an RMON collisions counter reports their sum. A link with ten thousand early collisions and zero late ones has lost nothing — it is a busy shared segment behaving exactly as designed. A link with ten thousand late collisions has lost ten thousand frames. The standard's own counter set distinguishes them; most dashboards add them together and call the result "collisions", which is Chapter 21.2 §11's discard-versus-damage conflation in the transmit path.

And it teaches that late_seen is decisive in a way almost nothing in Module 21 is. Chapter 9.1 §5 established that a conforming half-duplex segment cannot produce a late collision — the slot time was sized so that it cannot. So a single late collision is proof of a configuration fault, not evidence of one, and it is the only sticky bit in the chapter.

Deliberately simplified: bits_transmitted is assumed to count from the first bit of the preamble, where the standard's slot time is measured from the start of transmission including the preamble — an eight-octet difference that moves the boundary by 64 bits. The block does not model the jam pattern or the 96-bit interframe gap after an abort. And c_frames_lost assumes the MAC abandons a late collision, which 802.3 permits rather than requires: an implementation that retries them turns this chapter's loss into latency, and the two are not distinguishable from the far end.

Production implication: that last simplification is a real implementation divergence and it is worth knowing which one you have. A MAC that retries late collisions converts a 37.7% loss at half load into a 37.7% retransmission rate, which is far better for the application and far worse for the link's utilisation — and from the full-duplex end the two are identical, because both produce the same stream of aborted fragments. The distinguishing evidence is at the half-duplex end: c_frames_lost against c_frames_delayed, and only the local MAC knows which it did.


4. The Collision Probability Is 1 − e^(−u)

The half-duplex end transmits a frame. It collides if the full-duplex end starts transmitting at any point during it.

Model the full-duplex end's frame starts as a Poisson process — which is the standard assumption and is close enough for a ratio — at a rate set by its utilisation u and its mean frame time T. Over one half-duplex frame of the same duration:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
P(no full-duplex start during our frame) = exp(−u)
P(collision)                             = 1 − exp(−u)
Full-duplex utilisationP(collision) per half-duplex frame
1%1.00%
5%4.88%
10%9.52%
25%22.12%
50%39.35%
90%59.34%

At low load the collision probability is very nearly the utilisation itself, which is why a mismatched link on a quiet network behaves almost normally: at one per cent load, one frame in a hundred collides, and if the frames are small it is retried and nobody sees anything at all.

Now the retry arithmetic, for the collisions that are not late.

A backed-off frame is retried up to sixteen times. With an independent collision probability p per attempt:

u = 10%u = 50%
P(collision) per attempt9.52%39.35%
expected attempts per frame1.1051.649
P(sixteen consecutive collisions)4.5 × 10⁻¹⁷3.3 × 10⁻⁷

Row three is why excessive collisions is almost never the symptom. Even at fifty per cent load from the other end, a minimum-size frame is abandoned after sixteen attempts about three times in ten million — so the half-duplex end's frame loss from early collisions is negligible. What it loses is time: 1.649 attempts per frame, plus binary exponential backoff between them.

Which gives the first half of the pricing, and it is a latency price rather than a loss one.

Cost of a mismatch on minimum-size traffic
frames lostessentially zero
attempts per frame at 50% load1.649
the visible symptomlatency and jitter
the counter that movescollisions, and it looks like a busy segment

Row four is the trap. A half-duplex end reporting collisions looks exactly like a half-duplex end on a genuinely shared segment, which is what half-duplex is for. The counter does not distinguish "somebody else is talking" from "the other end does not know it should stop talking" — and Chapter 11.4 §3 already said so: collisions at one end only needs both ends to be decisive, and one end alone sees an ordinary collision count.

One refinement of the collision model, because it changes the shape at high load rather than the value at low load.

The derivation above treats each transmission attempt as independent, which is right for the first attempt and wrong for the retries: after a collision the half-duplex end backs off and retries, and the far end is still transmitting. So the retries are correlated with exactly the condition that caused the first collision.

Independent modelWhat actually happens
first attemptP(collision) = 1 − e^(−u)the same
retry after backoffthe same probabilityhigher while the far end's burst lasts
expected attempts at u = 50%1.649more
the loss figureunchangedunchanged

Row four is why the refinement does not matter for this chapter's headline. The retries affect early collisions, which cost latency; a late collision is not retried at all, so the loss figure is decided by the first attempt alone and the independence assumption is exactly right for it. The correlation makes the latency worse and the loss identical, which is a convenient split: the number this chapter projects is the robust one.


5. RTL 2 — The Late-Collision Discriminator

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// late_collision_discriminator -- Section 3's split, applied across a
// whole traffic mix rather than to one frame.
//
// The output that matters is the late RATIO, because Section 6 shows it
// is decided by the frame size distribution and not by the fault. A
// mismatched link carrying minimum-size traffic has a late ratio of
// exactly zero.
// ---------------------------------------------------------------------
module late_collision_discriminator
  import dupmis_pkg::*;
#(
  parameter int N_BUCKETS = 7        // Chapter 19.7 Section 2's histogram
)(
  input  logic        clk,
  input  logic        rst_n,

  input  logic        coll_event,
  input  coll_kind_e  kind,
  input  logic [2:0]  size_bucket,
  input  logic [13:0] wire_len,

  output logic [31:0] c_coll_by_bucket [N_BUCKETS],
  output logic [31:0] c_late_by_bucket [N_BUCKETS],
  output logic [15:0] late_ratio_ppt,
  output logic [15:0] predicted_ppt,
  output logic        model_disagrees,
  output logic        loss_is_structural_zero
);
  logic [31:0] total_coll, total_late;

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      for (int i = 0; i < N_BUCKETS; i++) begin
        c_coll_by_bucket[i] <= '0;
        c_late_by_bucket[i] <= '0;
      end
    end else if (coll_event) begin
      c_coll_by_bucket[size_bucket] <= c_coll_by_bucket[size_bucket] + 32'd1;
      if (kind == COLL_LATE)
        c_late_by_bucket[size_bucket] <= c_late_by_bucket[size_bucket] + 32'd1;
    end
  end

  always_comb begin
    total_coll = 32'd0; total_late = 32'd0;
    for (int i = 0; i < N_BUCKETS; i++) begin
      total_coll += c_coll_by_bucket[i];
      total_late += c_late_by_bucket[i];
    end

    late_ratio_ppt = (total_coll == 32'd0) ? 16'd0
                   : 16'((total_late * 32'd1000) / total_coll);

    // Section 6: the predicted ratio is a property of the frame's
    // length alone. Measuring it and predicting it and comparing is
    // what turns a count into a confirmation.
    predicted_ppt = 16'(late_fraction_ppt(int'(wire_len)));

    // A measured ratio far from the predicted one means the model is
    // wrong for this link -- a different slot time, or a MAC that
    // retries late collisions after all.
    model_disagrees = (total_coll > 32'd64) &&
                      ((late_ratio_ppt > (predicted_ppt + 16'd200)) ||
                       (predicted_ppt > (late_ratio_ppt + 16'd200)));

    // The headline: at the minimum frame size there is no part of the
    // frame beyond the slot time, so no collision on one can be late.
    loss_is_structural_zero = (wire_len <= 14'(MIN_FRAME_OCTETS));
  end
endmodule

Classification: a two-dimensional collision counter, crossed with the one dimension that decides the cost.

What it teaches: that a collision count is not a loss figure until it is crossed with the frame size. Ten thousand collisions on minimum-size traffic is zero frames lost; ten thousand on maximum-size traffic is 9 578 frames lost — and the RMON collisions counter reports ten thousand in both cases. Chapter 19.7 §2's size histogram is already in the MAC, and crossing it with the collision counter costs six more counters.

And it teaches that predicted_ppt makes the measurement falsifiable. The late ratio is not a number to be observed and interpreted; it has a predicted value derived from the frame length and the slot time, and a measurement far from it says the model is wrong for this link rather than that the link is unusual. That is the same discipline Chapter 21.3 §4 used for the length slope, and it is what separates a diagnostic from a dashboard.

Deliberately simplified: predicted_ppt uses the current frame's length where the measured ratio is over the whole population, so the comparison is only meaningful on fixed-size traffic — a real implementation predicts per bucket. The tolerance of 200 parts per thousand is a judgement. total_coll and total_late sum seven 32-bit counters combinationally. And loss_is_structural_zero is per-frame where the useful version is a property of the traffic mix.

Production implication: model_disagrees is the output that catches the implementation divergence Section 3 flagged. A MAC that retries late collisions rather than abandoning them produces the same late ratio and a completely different loss, so the ratio alone cannot distinguish them — but a link whose measured late ratio is near zero while carrying large frames has either no mismatch or a slot time this model does not know about, and at 1 Gb/s it is the second. One comparison, and it prevents a gigabit link being declared healthy because it was measured with a 100 Mb/s constant.


6. Why 95.8% of a Maximum-Size Frame Is Late

The slot time is five hundred and twelve bit times and it is a fixed number of bits. A frame is a variable number of bits. So the fraction of a frame that lies beyond the slot time, and therefore the fraction of collisions on it that are late, is a function of the frame's length. A sixty four octet frame is exactly five hundred and twelve bits, so nothing lies beyond the slot time and the late fraction is exactly zero. A one hundred and twenty eight octet frame is one thousand and twenty four bits, half of which is beyond it. Five hundred and twelve octets gives eighty seven and a half per cent. One thousand five hundred and eighteen octets, the maximum, is twelve thousand one hundred and forty four bits of which eleven thousand six hundred and thirty two lie beyond the slot time: ninety five point seven eight per cent. Nine thousand octet jumbo frames reach ninety nine point two nine. This is the same arithmetic as the throughput chapter's efficiency curve, a fixed overhead against a variable payload, and it produces the mirror image: there, large frames are efficient and small ones wasteful; here, large frames are doomed and small ones safe. Combined with the collision probability, which is one minus e to the minus the far end's utilisation, the frame loss at twenty five per cent load is twenty one point one nine per cent for maximum size frames and exactly zero for minimum size ones.512 bits, fixedthe slot time64 octets = 512bitslate fraction 0.00%128 octets50.00%512 octets87.50%1 518 octets95.78%P(collision) = 1- e^-uthe far end's loadLoss at 25% load0% at 64, 21.19% at15188.3's curve,mirroredsame arithmetic12
Figure 2 — a fixed 512 bits against a variable frame: zero at the minimum, 95.78% at the maximum.

The slot time is a fixed number of bits and a frame is a variable number of bits. Everything follows.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
late fraction = (8L − 512) / 8L,   for L ≥ 64 octets
Frame, octetsBitsBeyond the slot timeLate fraction
6451200.00%
1281 02451250.00%
2562 0481 53675.00%
5124 0963 58487.50%
1 0008 0007 48893.60%
1 51812 14411 63295.78%
9 00072 00071 48899.29%

The curve is the mirror image of Chapter 8.3 §2's efficiency curve and for the same reason: a fixed overhead against a variable payload. There, 38 octets of framing against the payload gave 54.8% efficiency at 46 octets and 97.5% at 1 500. Here, 512 bits of slot time against the frame gives 0% late at 64 octets and 95.78% at 1 518 — the same shape, the same arithmetic, and an outcome that is beneficial in one chapter and catastrophic in this one.

Chapter 8.3 §2this chapter
the fixed quantity38 octets of framing512 bits of slot time
big frames areefficient — 97.5%doomed — 95.78% late
small frames arewasteful — 54.8%safe — 0% late
the advice that followsuse large frameslarge frames are what you lose

Row four is the collision between two pieces of standard advice and it is worth being explicit about, because both are right in their own chapter. Everything about Ethernet performance says use larger frames; on a duplex-mismatched link the larger frames are precisely the ones that do not arrive.

Now combine with Section 4's collision probability.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
P(frame lost) = P(collision) × P(late | collision)
              = (1 − e^(−u)) × (8L − 512) / 8L
u64 octets1285121 5189 000
1%0.00%0.50%0.87%0.95%0.99%
5%0.00%2.44%4.27%4.67%4.84%
10%0.00%4.76%8.33%9.12%9.45%
25%0.00%11.06%19.35%21.19%21.96%
50%0.00%19.67%34.43%37.69%39.07%

Three readings of that table.

First, the left column is exactly zero everywhere. Not small — zero, and structurally so: there is no part of a 512-bit frame beyond a 512-bit slot time. No amount of load, no amount of time and no amount of simulation produces a late collision on minimum-size traffic.

Second, the right four columns are nearly identical. Once the frame is a few times the slot time, the late fraction is already above 90% and further growth buys little. The transition is between 64 and about 256 octets — the same region where Chapter 8.3 §2's efficiency curve is steep, and for the same reason.

Third, the loss is very nearly the utilisation, for any frame that is not minimum size. At 10% load a 1 518-octet frame loses 9.12%; the utilisation is 10%. So a rule of thumb that is accurate to within a tenth: on a duplex-mismatched link, large-frame loss equals the other end's load.

Frame loss ≈ the far end's utilisation, for every frame size except the smallest one, where it is exactly zero.


7. RTL 3 — The Size-Conditioned Loss Model

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// size_loss_model -- predict the loss from the load and the size mix,
// and compare it against what was measured.
//
// The block exists because the two inputs are things the NETWORK chose
// and the output is what the FAULT costs. Separating them is what lets
// a report say "this mismatch will cost 9% when the backup job starts"
// rather than "there are collisions".
// ---------------------------------------------------------------------
module size_loss_model
  import dupmis_pkg::*;
#(
  parameter int N_BUCKETS = 7
)(
  input  logic        clk,
  input  logic        rst_n,

  input  logic [15:0] far_end_util_ppt,      // the other end's load
  input  logic [31:0] c_tx_by_bucket [N_BUCKETS],
  input  logic [15:0] bucket_mid [N_BUCKETS],

  input  logic [31:0] c_frames_lost,
  input  logic [31:0] c_frames_tx,

  output logic [15:0] predicted_loss_ppt,
  output logic [15:0] measured_loss_ppt,
  output logic [15:0] loss_at_full_load_ppt,
  output logic        prediction_holds,
  output logic        min_size_traffic_only
);
  logic [31:0] weighted, total;

  always_comb begin
    weighted = 32'd0; total = 32'd0;
    for (int i = 0; i < N_BUCKETS; i++) begin
      total    += c_tx_by_bucket[i];
      weighted += c_tx_by_bucket[i] *
                  32'(late_fraction_ppt(int'(bucket_mid[i])));
    end

    // Section 6: loss = P(collision) x the traffic's mean late
    // fraction. The first term is approximated by the utilisation,
    // which Section 6 showed is accurate to about a tenth.
    predicted_loss_ppt = (total == 32'd0) ? 16'd0
      : 16'((32'(far_end_util_ppt) * (weighted / total)) / 32'd1000);

    measured_loss_ppt = (c_frames_tx == 32'd0) ? 16'd0
      : 16'((c_frames_lost * 32'd1000) / c_frames_tx);

    // What this link will cost when the far end gets busy. It is the
    // number a capacity planner needs and no counter reports.
    loss_at_full_load_ppt = (total == 32'd0) ? 16'd0
      : 16'((32'd632 * (weighted / total)) / 32'd1000);

    prediction_holds = (c_frames_tx > 32'd1000) &&
      ((measured_loss_ppt > predicted_loss_ppt)
        ? ((measured_loss_ppt - predicted_loss_ppt) < 16'd50)
        : ((predicted_loss_ppt - measured_loss_ppt) < 16'd50));

    // Section 6's structural zero: a link carrying only minimum-size
    // frames shows nothing, at any load, forever.
    min_size_traffic_only = (total != 32'd0) && ((weighted / total) < 32'd10);
  end
endmodule

Classification: a predictor, and the only block in Module 21 whose most useful output describes a load that has not happened yet.

What it teaches: that loss_at_full_load_ppt is the number that gets a mismatch fixed. A link losing 0.95% today, at one per cent load, will lose 60.5% when the far end saturates — 63.2% collision probability times a 95.78% late fraction — and the difference between those two numbers is entirely the load. A report that states today's loss describes the network's current quietness; a report that states the loss at full load describes the fault.

And it teaches that min_size_traffic_only is a statement about the evidence, not about the link. A link carrying only minimum-size frames has a mean late fraction of essentially zero, so it will show no loss whatever is wrong with it — and the correct response is not to conclude the link is healthy. It is to note that the instrument is blind on this traffic and to look at the collision count instead.

Deliberately simplified: the collision probability is approximated by the utilisation, which Section 6 showed is accurate to about a tenth and diverges above 50%: at full load the true figure is 63.2% and the linear approximation gives 100%. loss_at_full_load_ppt uses the correct 632 rather than 1 000, which makes it inconsistent with predicted_loss_ppt's approximation. bucket_mid is an input so the block trusts somebody else's histogram boundaries — Chapter 21.2 §18 showed those move with the VLAN configuration.

Production implication: the inconsistency between the two predictions is the block's own bug and it is instructive rather than shameful. A linear approximation is right to a tenth below half load and wrong by 58% at full load, so a model that uses it for today's figure and an exact form for the projection reports two numbers computed differently. The fix is one exponential or a small lookup table; the reason it matters is that the projection is the number somebody acts on, and a projection that is wrong by 58% in the pessimistic direction gets ignored the first time it is checked.


8. Ping Works and the File Transfer Does Not

Section 6's table has a left column of exact zeros, and that column is what every diagnostic tool in ordinary use sends.

ToolTypical frame sizeLate fractionLoss at 25% far-end load
a 56-byte ping98 octets on the wire34.7%7.67%
a 0-byte ping64 octets — padded0.00%0.00%
ARP64 octets — padded0.00%0.00%
a TCP acknowledgement64 octets — padded0.00%0.00%
a bulk transfer segment1 51895.78%21.19%

Rows two, three and four are exactly 64 octets because Chapter 5.6's padding rule pads everything shorter up to the minimum — and the minimum is the slot time. So the three most common small-frame exchanges on any network cannot suffer a late collision, are retried transparently by the MAC, and arrive.

Row five is the application, and it loses a fifth of its frames.

Every tool an operator reaches for first sends frames that are structurally immune to the fault. The application sends the frames that are not.

And the effect is amplified far beyond the raw loss figure by what sits above.

At 21.19% frame loss
raw goodput, if loss were independent78.8% of offered
what TCP doestreats loss as congestion and collapses the window
what the user seesa transfer that runs at a few per cent of the link
what the link's counters saythe link is 25% utilised

Row four is Chapter 8.3 §4's throughput-against-goodput distinction arriving as an operational trap. The link carries plenty of octets — most of them retransmissions — so a utilisation graph looks reasonable while the application gets almost nothing. Chapter 8.3 §13 called this "a link that is full and looks idle"; this is the mirror image: a link that is nearly idle and looks busy.

The asymmetry makes it worse, and it is the reason a bidirectional test is mandatory.

TestDirection measuredResult on a mismatched link
download from the serverfull-duplex → half-duplexfull rate, no errors
upload to the serverhalf-duplex → full-duplexcollapses
a one-directional benchmarkwhichever it chosehealthy, half the time

Section 2 established that the mismatch damages only the half-duplex end's transmissions. So a test that measures the other direction reports a perfectly healthy link, and reports it correctly — it measured a direction that is perfectly healthy.

And there is a second size effect on top of the first, which makes the asymmetry worse than the loss figures alone suggest.

The frames flowing in the two directions are not the same size. A download is large data frames one way and small acknowledgements the other; an upload is the reverse.

Large frames travelSmall frames travelWhich direction is damaged?
downloadFD → HD — safe directionHD → FDthe small ones, which are immune
uploadHD → FD — damaged directionFD → HDthe large ones, at 95.78% late

A download therefore escapes twice over: its large frames travel in the direction the mismatch does not touch, and its acknowledgements travel in the damaged direction at exactly the size that cannot suffer a late collision. The two effects compound, and a download across a badly mismatched link can run at full rate with no measurable loss at all.

An upload is hit twice for the same reason. Its data frames are large and travel in the damaged direction.

Observed throughput on a mismatched link
downloadline rate
uploadcollapses
a bidirectional testshows the asymmetry immediately
a one-directional testa coin flip

Which makes "test both directions" not merely good practice but the single cheapest discriminator in the chapter — it needs no counters, no far-end access and no knowledge of the frame sizes involved, and the asymmetry it exposes is produced by no other fault in Module 21.


9. RTL 4 — The Two-Ended Counter Correlator

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// two_end_counter_join -- put both ends' counters in one row.
//
// Section 3 showed the two counter sets do not intersect: four
// transmit counters at one end, three receive counters at the other,
// and nothing in common. So this is not a comparison -- it is a JOIN
// on a link, and the pattern it looks for is a correspondence between
// two different quantities.
// ---------------------------------------------------------------------
module two_end_counter_join
  import dupmis_pkg::*;
(
  input  logic        clk,
  input  logic        rst_n,

  // Our end, whichever it is.
  input  logic        we_are_half_duplex,
  input  logic [31:0] our_collisions,
  input  logic [31:0] our_late_collisions,
  input  logic [31:0] our_fcs_errors,
  input  logic [31:0] our_fragments,
  input  logic [31:0] our_frames_tx,

  // The far end, over a management path.
  input  logic        far_valid,
  input  logic [31:0] far_collisions,
  input  logic [31:0] far_late_collisions,
  input  logic [31:0] far_fcs_errors,
  input  logic [31:0] far_fragments,

  output logic        one_sided_collisions,
  output logic        cross_correspondence,
  output logic [15:0] correspondence_ppt,
  output logic        mismatch_confirmed,
  output logic        need_far_end
);
  logic [31:0] hd_late, fd_frag;

  always_comb begin
    // Chapter 11.4 Section 3: "collisions at one end only" is by
    // construction a statement about two ends. On a genuinely shared
    // segment BOTH ends collide.
    one_sided_collisions = far_valid &&
      (((our_collisions > 32'd0) && (far_collisions == 32'd0)) ||
       ((far_collisions > 32'd0) && (our_collisions == 32'd0)));

    // The correspondence: every frame the half-duplex end abandoned
    // arrives at the full-duplex end as a fragment. The two counts
    // should track, and they are different counters at different ends.
    hd_late = we_are_half_duplex ? our_late_collisions : far_late_collisions;
    fd_frag = we_are_half_duplex ? far_fragments       : our_fragments;

    correspondence_ppt = (hd_late == 32'd0) ? 16'd0
                       : 16'((fd_frag * 32'd1000) / hd_late);

    // Within 20% of one-to-one is a correspondence. Exactly one-to-one
    // it will not be: the far end also discards some fragments below
    // its own detection threshold.
    cross_correspondence = (hd_late > 32'd64) &&
                           (correspondence_ppt > 16'd800) &&
                           (correspondence_ppt < 16'd1200);

    mismatch_confirmed = one_sided_collisions && cross_correspondence &&
                         (hd_late > 32'd0);

    need_far_end = !far_valid;
  end
endmodule

Classification: a join across a link, and the only block in Module 21 whose two inputs come from two different machines.

What it teaches: that the confirmation is a correspondence between two different counters rather than an agreement between two copies of one. The half-duplex end's late_collisions and the full-duplex end's fragments are the same physical events counted from two sides — one end abandoned a frame, the other received its truncated remains — and they should track one-to-one. Neither counter alone says anything; the ratio between them is the diagnosis.

And it teaches why one_sided_collisions needs the far end by construction. Chapter 11.4 §3 made exactly this point: on a genuinely shared segment both ends collide, so a collision count at one end is ordinary and a collision count at one end while the other end has none is impossible under contention. The symptom is worth 1.81 bits and none of them is available unilaterally.

Deliberately simplified: the 20% tolerance is a judgement, and the true correspondence is below one-to-one because the far end discards some fragments before counting them — a runt shorter than its detection threshold is not counted anywhere. far_valid is an input so the block has no opinion about how the far end's counters were obtained or how stale they are. And the two ends' counters are assumed to cover the same window, which across a management path they do not — Chapter 4.5 §7's sample-age problem across two machines.

Production implication: the window-alignment problem is the practical obstacle to this block existing at all. Two switches' counters, read by a monitoring system at two different moments, over two different paths, are not a matched pair — and the correspondence test needs deltas over a common interval. The workable version reads both ends twice, a minute apart, and correlates the deltas; the ratio is robust enough that a few seconds of skew does not matter, which is the one respect in which this diagnosis is forgiving.


10. Two Ends, Two Different Faults

The half duplex end and the full duplex end of a mismatched link accumulate completely disjoint evidence. The half duplex end is transmitting and detecting collisions, so its counters are transmit side: collisions, late collisions, deferred transmissions and, rarely, excessive collisions. The full duplex end is receiving the truncated remains of frames the other end abandoned, so its counters are receive side: check sequence errors, fragments and undersize frames. Intersect the two sets and the result is empty. Consequently the two operators looking at the two ends describe two different faults. The half duplex end's operator sees collisions and concludes the link is a busy shared segment, which is what half duplex is for. The full duplex end's operator sees check sequence errors and fragments with a healthy frame count and concludes that something is corrupting frames on the cable, which is the textbook signature of a damaged medium. Neither is right and the fault is one configuration line. The second reading is the dangerous one because it dispatches a technician to a rack, and it is made convincing by the fragment counter's name: the error taxonomy chapter established that fragments no longer mean collision remnants on a switched link, and here, uniquely, they do.Half-duplex end4 transmit countersFull-duplex end3 receive counterscollisions, late,deferredclimbingfcs, fragments,undersizeclimbingIntersection:emptynot a comparisonA busy sharedsegmenttheir conclusionA damaged cabletheir conclusionOne configurationlineneither end's medium12
Figure 3 — seven counters, two ends, and no row with both columns non-zero.

The same physical event, counted at two ends, produces two counter sets with nothing in common.

Half-duplex endFull-duplex end
collisionsclimbingzero — the counter does not apply
late_collisionsclimbingzero
deferredclimbingzero
excessive_collisionsrarelyzero
fcs_errorszeroclimbing
fragmentszeroclimbing
frames_inhealthyhealthy

Seven counters, and no row has both columns non-zero. So the two operators looking at the two ends see disjoint evidence and describe different faults:

Says
the half-duplex end's operator"we are on a busy shared segment"
the full-duplex end's operator"something is corrupting frames on the cable"
the truthneither, and it is one configuration line

And the second one is the dangerous reading, because it is the one that sends a technician to a rack. fcs_errors and fragments climbing together with a healthy frames_in is the classic signature of a damaged medium — and Chapter 21.2 §17 spent a section on why fragments no longer means what its name says.

This chapter is the exception to that section.

Chapter 21.2 §17 said the fragment counter's original cause — a collision remnant — no longer exists on a switched full-duplex link. A duplex mismatch resurrects it: the fragments really are collision remnants, produced by collisions on a link where collisions should be impossible.

fragments, three eras
1985, shared mediuma collision remnant
Chapter 21.2 §17, switched full duplexa cut frame — cable, partner, or our own truncation
this chaptera collision remnant again, and it should be impossible

Which gives the fragment counter its fourth cause and the only one that is diagnosable from its companion counter rather than from itself. fragments alone is three causes; fragments with the far end reporting late collisions is one.


11. RTL 5 — The Fragment Provenance Detector

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// fragment_provenance -- which of Chapter 21.2 Section 17's causes
// produced these fragments?
//
// Three were known: a cut cable, a stopped partner, our own truncation.
// This chapter adds a fourth -- a far-end collision abort -- and it is
// the only one with a positive local signature.
// ---------------------------------------------------------------------
module fragment_provenance
  import dupmis_pkg::*;
(
  input  logic        clk,
  input  logic        rst_n,

  input  logic        frag_event,
  input  logic [13:0] frag_len,
  input  logic [31:0] c_self_inflicted,   // Chapter 21.2 Section 11
  input  logic [31:0] c_fragments,
  input  logic [31:0] c_frames_in,
  input  logic        far_late_collisions_seen,

  output logic [31:0] c_frag_at_slot,
  output logic [15:0] at_slot_ppt,
  output logic [2:0]  provenance,   // 0 unknown 1 cut 2 ours 3 collision
  output logic        collision_abort_likely,
  output logic        len_evidence_only
);
  // A frame abandoned on a collision stops at the moment of the
  // collision plus the jam. A frame cut by a cable stops anywhere.
  // So a CLUSTER of fragment lengths just past the slot time is the
  // signature of an abort rather than of a cut.
  localparam int SLOT_OCTETS = SLOT_BITS / 8;      // 64
  localparam int JAM_OCTETS  = 4;

  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) c_frag_at_slot <= '0;
    else if (frag_event &&
             (frag_len >= 14'(SLOT_OCTETS)) &&
             (frag_len <= 14'(SLOT_OCTETS + JAM_OCTETS + 8)))
      c_frag_at_slot <= c_frag_at_slot + 32'd1;
  end

  always_comb begin
    at_slot_ppt = (c_fragments == 32'd0) ? 16'd0
                : 16'((c_frag_at_slot * 32'd1000) / c_fragments);

    // A cut cable produces fragment lengths spread over the whole
    // range. An early collision abort produces them at the slot time.
    // A LATE collision abort produces them anywhere too -- which is
    // why the length evidence alone is not decisive.
    collision_abort_likely = (c_fragments > 32'd64) && (at_slot_ppt > 16'd300);
    len_evidence_only      = !far_late_collisions_seen;

    if      (far_late_collisions_seen)          provenance = 3'd3;
    else if (c_self_inflicted > (c_fragments >> 1)) provenance = 3'd2;
    else if (collision_abort_likely)            provenance = 3'd3;
    else if (c_fragments > 32'd0)               provenance = 3'd1;
    else                                        provenance = 3'd0;
  end
endmodule

Classification: a provenance estimator, and the first block in Module 21 to attribute a counter to a cause outside the local design.

What it teaches: that fragment lengths carry evidence that fragment counts do not. A frame abandoned on an early collision stops at the slot time plus the jam — about 68 octets, every time — so a cluster of fragments at that length is an abort rather than a cut. A cable that parts mid-frame produces fragment lengths spread over the whole range, and Chapter 19.5 §14's truncation produces them at the buffer's boundary.

And it teaches that the length evidence is only half the story, which len_evidence_only says out loud. A late collision abort stops wherever the collision happened, which is uniformly distributed over the frame — so exactly the collisions that cost frames are the ones whose lengths look like a cut cable. The clustered signature comes from the early collisions, which cost nothing; the decisive evidence is the far end's late_collisions counter, and provenance prefers it whenever it is available.

Deliberately simplified: the at-slot window is eight octets wide around 68, which is a judgement about jam timing and MAC abort latency. The block cannot see Chapter 21.2 §11's c_self_inflicted unless that optional counter exists — and it is one of the four Chapter 21.1 §19 priced at about 297 flops. And provenance returns a single value where the honest output is a set, which is Chapter 11.4 §15's class 48 in miniature.

Production implication: the fragment-length histogram is the instrument this block wants and no MAC has it. Chapter 19.7 §2's size histogram bins all frames, not fragments specifically, so a cluster of 68-octet fragments is invisible inside bucket 0's ordinary traffic. The fix is the same one Chapter 21.3 §19 argued for: log the length of each fragment as a field rather than binning it — a 14-bit value in a record the MAC already keeps — and the clustering test is free in software.


12. What 21.1's Method Says at Each End, and Why It Is Wrong at One

Run Chapter 21.1's candidate-mask procedure at the full-duplex end and watch it work exactly as specified.

The readings at that end:

ReadingValueWhy
c_crc_errorsmovingthe aborted frames fail their check
c_alignment_errorszerothe jam is a whole number of octets
c_undersize / fragmentsmovingthe aborted frames are short
c_oversizezeroan abort makes frames shorter, never longer
frames_inhealthythe port counted them at the delimiter

Now intersect, in Chapter 21.1 §5's order:

StepSurviving candidates
startall twelve
c_crc_errors movedchannel, PHY lanes, xMII, parser, CRC logic — 5
c_alignment_errors zeroparser, CRC logic — 2
c_undersize movedparser — 1
c_oversize zeronone — 0

The mask goes empty at the fourth step, and Chapter 21.1 §13's contradiction fires.

That is the correct behaviour and it is the best outcome available, because the fault is not at any of the twelve sites: it is at the far end's MAC, which is outside Chapter 21.1's space entirely. An empty mask is that method saying so.

But it depends on a register almost nobody reads.

Readings usedResultVerdict
crc, alignment, undersize, frames_inone candidate: the parserconfidently wrong
the same plus c_oversizeemptyhonestly refused

c_oversize is the least informative counter in Chapter 21.1 §6's table — 0.650 bits, joint lastand here it is the difference between a diagnosis that names an innocent block and one that admits the fault is elsewhere. A counter's average information content is not its worst-case value, and this is the case that pays for it.

And Chapter 21.3's slope test, run at the same end, refuses in a different way.

The FCS error rate at the full-duplex end is (1 − e^(−u)) × late_fraction(L)and the late fraction is a function of the frame's length, so the rate rises with size just as a channel fault's does.

BucketMidpointLate fractionError rate at 25% load
0640.00%0.000%
19633.33%7.373%
338383.29%18.424%
51 27194.96%21.006%

Bucket 0 is exactly zero, so Chapter 21.3 §5's estimator picks bucket 1 as its low bucket and computes:

Value
slope, bucket 5 over bucket 12.849
Chapter 21.3 §5's channel threshold≥ 5.00
its logic threshold≤ 2.00
verdictslope_ambiguous — no decision

A duplex mismatch lands squarely in Chapter 21.3's undecided band, and the ratio is load-independent — it is a pure ratio of late fractions, so it reads 2.849 at every utilisation. That chapter's method refuses to answer and is right to.

And the reading that would have named it is one neither chapter tests for.

A structural zero in bucket 0. A channel fault has errors in bucket 0 at a lower rate; a logic fault has them at the same rate. Only a duplex mismatch has none at all, and it is none rather than few.

FaultBucket 0 error rate
a channel faultnon-zero, and 19.86× below bucket 5
any logic faultnon-zero, and equal to bucket 5
a duplex mismatchexactly zero

One bucket, one comparison against zero, and it separates this chapter's fault from both of Chapter 21.3's categories — using a cross that chapter already built.

And the reason the zero is trustworthy is worth one more paragraph, because a zero is usually the weakest kind of evidence.

Chapter 21.1 §10 spent a section on why a zero reading is fragile: an unimplemented counter reads zero, a window too short reads zero, and an undersized addend can read zero. None of those applies here.

Ordinary reason a zero is untrustworthyDoes it apply to bucket 0?
the counter is not implementedno — it is the same counter as bucket 5
the window was too shortno — bucket 5 is full over the same window
the traffic never entered that bucketcheck it; c_frames_in_bucket[0] says
the fault is rareno — the other buckets are at 21%

Row three is the only one that has to be checked and it is one more counter, already present. The reading that matters is bucket 0 carrying frames and reporting no errors while bucket 5 carries frames and reports 21%a zero measured alongside a large number, over the same window, on the same counter. That is the strongest form a zero takes, and it is the form Chapter 21.1 §10's cautions were written to distinguish from the weak ones.


13. RTL 6 — The Load-Conditioned Alarm

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// load_conditioned_alarm -- report the fault's COST, not its symptom
// count, and report it at a load that has not happened yet.
//
// Section 7 derived the projection. This block is what turns it into
// an alarm that fires on a quiet link, which is the only time a
// mismatch is cheap to fix.
// ---------------------------------------------------------------------
module load_conditioned_alarm
  import dupmis_pkg::*;
(
  input  logic        clk,
  input  logic        rst_n,

  input  logic [15:0] far_end_util_ppt,
  input  logic [15:0] mean_late_fraction_ppt,
  input  logic [31:0] c_late_collisions,
  input  logic [31:0] c_frames_tx,
  input  logic        mismatch_confirmed,

  output logic [15:0] loss_now_ppt,
  output logic [15:0] loss_at_full_load_ppt,
  output logic [15:0] amplification,
  output logic        alarm,
  output logic        quiet_link_warning,
  output logic        evidence_below_floor
);
  // Section 4: the collision probability at full load is 1 - 1/e,
  // which is 632 parts per thousand. Not 1000.
  localparam int P_COLL_FULL_PPT = 632;

  always_comb begin
    loss_now_ppt = (c_frames_tx == 32'd0) ? 16'd0
                 : 16'((c_late_collisions * 32'd1000) / c_frames_tx);

    loss_at_full_load_ppt =
      16'((32'(P_COLL_FULL_PPT) * 32'(mean_late_fraction_ppt)) / 32'd1000);

    // How much worse this gets when the network gets busy. It is the
    // number that decides whether a mismatch is fixed this week.
    amplification = (loss_now_ppt == 16'd0) ? 16'd0
                  : 16'((32'(loss_at_full_load_ppt) * 32'd100) /
                        32'(loss_now_ppt));

    // Fire on the PROJECTION, not on today's loss.
    alarm = mismatch_confirmed && (loss_at_full_load_ppt > 16'd50);

    // The trap: a quiet link with a confirmed mismatch shows almost
    // nothing today and will show 60% when the backup job runs.
    quiet_link_warning = mismatch_confirmed &&
                         (far_end_util_ppt < 16'd50) &&
                         (loss_at_full_load_ppt > 16'd300);

    // Section 6's structural zero: minimum-size traffic produces no
    // evidence at all, so the absence of late collisions says nothing.
    evidence_below_floor = (mean_late_fraction_ppt < 16'd10);
  end
endmodule

Classification: a projector, and the only alarm in Module 21 that fires on a link that currently works.

What it teaches: that amplification is the number that changes a decision. A link losing 0.95% today has a 60.5% loss waiting at full load — an amplification of 6 400% — and the two numbers describe the same fault. Reporting today's figure gets the ticket deprioritised; reporting the projection gets it fixed while the network is quiet, which is the only time the fix is free.

And it teaches that evidence_below_floor must gate every negative conclusion. A link carrying only minimum-size frames has a mean late fraction of essentially zero, so c_late_collisions stays at zero however broken the configuration is — and Section 6 showed that is a structural zero rather than a small number. "No late collisions" is not evidence of no mismatch on such a link; it is an absence of instrument.

Deliberately simplified: P_COLL_FULL_PPT uses the correct 632 while Section 7's predicted_loss_ppt uses a linear approximation, so the two blocks disagree by 58% at full load — the same inconsistency Section 7 flagged, still unfixed here. alarm's threshold of 5% projected loss is a judgement. amplification divides by loss_now_ppt and returns zero when today's loss is zero, which is exactly the quiet-link case the block exists for — the projection is still right and the ratio is undefined.

Production implication: the undefined amplification on a perfectly quiet link is the case to design for rather than around. A mismatch on a link carrying nothing has a projected loss of 60% and a current loss of zero, and the ratio is infinite. The output that matters there is loss_at_full_load_ppt alone, and quiet_link_warning exists to say that the projection is the whole content of the report — because a mismatch discovered on a quiet Sunday is a configuration change, and the same mismatch discovered on a busy Monday is an outage.


14. What a Mismatch Diagnosis Must Never Do

Six prohibitions. Two are about the load, two about the two ends, and two about the frame size — and every one of them turns a present fault into an absent one.

NeverBecause
1conclude "no mismatch" from zero late collisionsSection 6 — minimum-size traffic makes it a structural zero
2report today's loss as the fault's costSection 13 — the amplification is up to 6 400%
3test one direction onlySection 8 — the mismatch damages one direction
4diagnose from one endChapter 11.4 §3 — the decisive symptoms need both
5add early and late collisions into one figureSection 3 — one costs time, the other costs the frame
6read fragments at the full-duplex end as a cable faultSection 10 — they are the far end's aborts

Row one is the prohibition that hides the fault for years. A link between two devices exchanging mostly acknowledgements and control frames carries almost nothing above 64 octets, so its late-collision counter reads zero forever. The mismatch is present, costly, and completely invisible — until somebody runs a backup across it. The test that does work on such a link is the collision counter at one end against zero at the other, which is Chapter 11.4 §3's 1.81-bit symptom and needs the far end.

Row six is the prohibition that dispatches a technician. fcs_errors and fragments climbing together with a healthy frames_in is the textbook signature of a damaged medium, and on a mismatched link it is produced by a perfectly good cable. Chapter 21.2 §17's archaeology is what makes it convincing: the fragment counter's name says "collision remnant" and here, uniquely on a switched link, that is exactly what it is — from collisions that should have been impossible.

And the two that look like presentation choices and are not:

Why it is a prohibition
row twothe fault's cost is a projection; its symptom is a measurement of the network's quietness
row fiveten thousand early collisions is zero frames lost; ten thousand late ones is ten thousand

Both report a number that describes the traffic rather than the fault, which is what all six share — and on this fault, more than on any other in Module 21, the traffic decides whether there is anything to see at all.

And two things a mismatch diagnosis should always do, stated positively.

AlwaysCosts
1compare both ends' resolved duplex before reading a countertwo management reads
2report the projected loss beside the measured oneone multiplication

Row one finds the fault; row two gets it fixed, and neither needs traffic, load or a particular frame size. Everything else in this chapter exists because those two are not always available — a far end on somebody else's management domain, a link whose configuration is opaque — and because the projection needs the size mix, which only the counters know.


15. RTL 7 — Mismatch Telemetry

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// dupmis_telemetry -- three groups, and the split is by WHO acts.
//
// Evidence: what was observed, at which end.
// Cost: what it is costing now and what it will cost.
// Blindness: whether this link's traffic can show the fault at all.
// ---------------------------------------------------------------------
module dupmis_telemetry
  import dupmis_pkg::*;
(
  input  logic        clk,
  input  logic        rst_n,

  input  logic        we_are_half_duplex,
  input  logic        one_sided_collisions,
  input  logic        cross_correspondence,
  input  logic        late_seen,
  input  logic [15:0] late_ratio_ppt,
  input  logic [15:0] predicted_ppt,
  input  logic [15:0] loss_now_ppt,
  input  logic [15:0] loss_at_full_load_ppt,
  input  logic [15:0] mean_late_fraction_ppt,
  input  logic [15:0] bucket0_err_ppt,
  input  logic        far_valid,

  // Evidence.
  output logic [2:0]  confidence,        // 0 none .. 4 proven
  output logic        proven_by_late,
  output logic        which_end_is_half,

  // Cost.
  output logic [15:0] cost_now_ppt,
  output logic [15:0] cost_projected_ppt,

  // Blindness.
  output logic        traffic_cannot_show_it,
  output logic        bucket0_is_zero,
  output logic        need_far_end
);
  // Chapter 9.1 Section 5: a conforming half-duplex segment cannot
  // produce a late collision. So one is proof, not evidence.
  assign proven_by_late = late_seen;
  assign which_end_is_half = we_are_half_duplex;

  always_comb begin
    if      (proven_by_late && cross_correspondence) confidence = 3'd4;
    else if (proven_by_late)                         confidence = 3'd3;
    else if (one_sided_collisions)                   confidence = 3'd2;
    else if (far_valid && cross_correspondence)      confidence = 3'd1;
    else                                             confidence = 3'd0;

    cost_now_ppt       = loss_now_ppt;
    cost_projected_ppt = loss_at_full_load_ppt;

    // Section 6's structural zero, reported as a property of the
    // traffic rather than of the link.
    traffic_cannot_show_it = (mean_late_fraction_ppt < 16'd10);

    // Section 12's free discriminator: a channel fault has errors in
    // bucket 0 and a mismatch has none at all.
    bucket0_is_zero = (bucket0_err_ppt == 16'd0);

    need_far_end = !far_valid && (confidence < 3'd3);
  end
endmodule

Classification: a reporting block whose third output group describes the instrument rather than the link.

What it teaches: that proven_by_late is a stronger word than anything else in Module 21 and it is earned. Chapter 9.1 §5 established that the slot time was sized so that a conforming half-duplex segment cannot produce a late collision — so one late collision is a proof of a configuration fault rather than evidence of one. Nothing in Chapter 21.1, Chapter 21.2 or Chapter 21.3 reaches that standard; all three produce candidate sets.

And it teaches that traffic_cannot_show_it outranks confidence of zero. A confidence of zero on a link whose traffic can show the fault is real evidence of no mismatch; the same zero on minimum-size traffic is no evidence at all. Reporting them as the same number is Section 14's first prohibition, and the two bits cost nothing to separate.

Deliberately simplified: confidence is a five-level ordinal with no meaning attached to the gaps. bucket0_is_zero is exported and not folded into confidence, where Section 12 argued it is a free discriminator worth having. cost_now_ppt and cost_projected_ppt are pass-throughs. And which_end_is_half is an input — the block cannot determine which end it is on from the counters, which is correct and worth noting: a MAC knows its own configured duplex and that is the one fact in this chapter nobody has to infer.

Production implication: the fact that a MAC knows its own duplex is the shortest path to this whole diagnosis and it is almost never used. A management system that collects duplex alongside link_up for every port can find every mismatch in a building by comparing the two ends of each cable — no counters, no load, no traffic, no waiting for somebody to notice a slow transfer. It is a configuration audit rather than a diagnosis, and it finds the fault before Section 13's alarm has anything to project.


16. RTL 8 — The Mismatch Conformance Monitor

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ---------------------------------------------------------------------
// dupmis_conformance_monitor -- six verdicts, and three of them are
// about whether the link's traffic can reveal the fault at all.
// ---------------------------------------------------------------------
module dupmis_conformance_monitor
  import dupmis_pkg::*;
(
  input  logic        clk,
  input  logic        rst_n,

  input  logic [31:0] c_frames_tx,
  input  logic [15:0] mean_late_fraction_ppt,
  input  logic [15:0] far_end_util_ppt,
  input  logic        far_valid,
  input  logic        late_seen,
  input  logic        one_sided_collisions,
  input  logic        model_disagrees,
  input  logic        bidirectional_tested,
  input  logic        collisions_summed,

  output logic        blind_traffic,
  output logic        load_too_low,
  output logic        one_ended_diagnosis,
  output logic        one_directional_test,
  output logic        counters_conflated,
  output logic        slot_time_wrong,
  output logic        diagnosis_sound
);
  // Section 6: minimum-size traffic makes the late-collision counter a
  // structural zero. No amount of running time changes it.
  assign blind_traffic = (mean_late_fraction_ppt < 16'd10);

  // Section 4: the collision probability is the far end's utilisation.
  // Below about 1% there is nothing to observe in any reasonable window.
  assign load_too_low = far_valid && (far_end_util_ppt < 16'd10);

  // Chapter 11.4 Section 3: the two decisive symptoms need both ends.
  assign one_ended_diagnosis = !far_valid && !late_seen;

  assign one_directional_test = !bidirectional_tested;
  assign counters_conflated   = collisions_summed;

  // Section 3: at 1 Gb/s the slot time is 4096 bit times, not 512.
  assign slot_time_wrong = model_disagrees;

  assign diagnosis_sound = !one_ended_diagnosis && !counters_conflated &&
                           !slot_time_wrong;

  always_ff @(posedge clk) begin
    if (rst_n && blind_traffic && (c_frames_tx > 32'd1000000))
      $display("[dupmis] this link's frame sizes cannot produce a late collision");
  end
endmodule

Classification: an auditor whose three loudest verdicts describe the traffic rather than the design.

What it teaches: that blind_traffic and load_too_low are deliberately not terms of diagnosis_sound. A diagnosis run on minimum-size traffic at one per cent load is correctly executed and cannot find anything — the instrument is blind and the engineer did nothing wrong. Folding a traffic property into a verdict about the investigation is the mistake Chapter 21.1 §16 avoided for instrumentation and this chapter avoids for load.

And it teaches that one_ended_diagnosis has an escape. It fires only when the far end is unavailable and no late collision has been seen — because a late collision is proof on its own and needs no correlation. Chapter 11.4 §3 said the decisive symptoms need both ends; one of the two does not, and the monitor encodes the exception rather than the rule.

Deliberately simplified: collisions_summed is an input describing how somebody else's dashboard is configured, which no hardware block can know. slot_time_wrong is model_disagrees renamed, so it conflates a gigabit slot time with a MAC that retries late collisions — two different causes of the same disagreement. And load_too_low's 1% threshold assumes a reasonable observation window rather than deriving one from the frame rate.

Production implication: the $display gated on a million transmitted frames is the block's most useful behaviour and the pattern is worth copying. A link that has sent a million frames without a single one being large enough to produce a late collision has proved something about itselfthat this diagnosis will never work here — and saying so once, after enough evidence, is more useful than a flag that is true from reset. The alternative instrument on such a link is the configuration audit of Section 15, which needs no traffic at all.


17. The Cost Curve, and Where the Ticket Gets Filed

The frame loss is the fault's direct cost. What an application experiences is much worse, and the gap is where the ticket comes from.

A loss-based congestion control reacts to a dropped segment by halving its window, so the throughput it achieves falls roughly as the inverse square root of the loss rate. Using the standard approximation, with a 1 460-octet segment:

Far-end loadFrame lossTCP throughput, 0.5 ms RTT1 ms10 ms
0.5%0.48%414 Mb/s20720.7
1%0.95%29314714.7
2%1.90%20810410.4
5%4.67%13266.26.6
10%9.12%94.847.44.7
25%21.19%62.231.13.1
50%37.69%46.623.32.3

Read the 1 ms column against a 100 Mb/s link.

Value
loss at which TCP falls below 100 Mb/s2.05%
far-end load that produces it2.16%
the link's own utilisation graph thena few per cent

A mismatched 100 Mb/s link stops delivering its line rate once the far end exceeds about two per cent utilisation, and at that point every counter on the link looks unremarkable: a small number of collisions at one end, a small number of fragments at the other, and a utilisation graph that says the link is almost idle.

And the gigabit case is worse by two orders of magnitude, for a reason that has nothing to do with the fault.

100 Mb/s1 Gb/s
loss at which TCP falls below line rate2.05%0.020%
far-end load that produces it2.16%0.02%

A faster link needs a larger congestion window to fill, and a larger window is harder to sustain under loss — so the loss rate a gigabit link tolerates before falling short of its rate is a hundredth of what a 100 Mb/s link tolerates. The fault is identical; the tolerance is not. This is Chapter 20.6 §8's observation in a different domain: the same absolute impairment is a different fraction at each rate.

Which gives the answer to where the ticket gets filed, and it is not where the counters are.

ObserverWhat they see at 2% far-end load
the link's countersa handful of collisions and fragments
the utilisation graph2% — idle
the monitoring thresholdnot crossed
the applicationa transfer at half speed
the user"the network is slow"

Rows one to three are all below any reasonable alarm and row five is a ticket. Chapter 11.4 §3 measured it is slow at 0.49 bits — the least informative symptom in its table — and this is why it is the one that arrives: it is the only observer whose threshold the fault crosses.

The fault is loud in the application and quiet in every instrument that watches the link, and the gap between them is a factor of the congestion control's square root rather than anything about Ethernet.

And there is a third observer whose reading is the most misleading of all, because it is the one a capacity planner uses.

On a mismatched 100 Mb/s link at 2% far-end load
octets on the wireincludes every retransmission
Chapter 8.3 §4's throughputwhat the wire carried
its goodputwhat arrived once
the differencethe retransmissions, which grow with the loss

Chapter 8.3 §5 built a separate goodput accumulator for exactly this reason, and almost no deployed system has one. A utilisation graph counts octets on the wire, so a link whose application traffic has collapsed to a tenth but which is retransmitting heavily can show a utilisation figure that is higher than the useful work would suggest, not lower.

LossUseful fraction of the octets carried
0%100%
2%about 98%
21%about 79%
37.7%about 62%

At the losses this chapter derives, up to 38% of the octets on the wire are frames that will be sent again — and Chapter 8.3 §4's distinction is the only vocabulary that separates them. A link is doing 38% more work than it is delivering, and every instrument that counts octets reports the work.


18. What the Diagnosis Assumes

Nine assumptions. Three are about the model, three about the counters and three about the configuration — and the first is false at gigabit.

AssumptionFromIf false
1the slot time is 512 bit timesChapter 9.1 §5at 1 Gb/s it is 4 096 — the safe size moves by 8×
2a late collision is not retried802.3 permits eitherloss becomes latency, and the far end cannot tell
3the far end's frame starts are Poissonconveniencebursty traffic raises the collision rate above 1 − e^(−u)
4both ends' counters cover one windowa management pathSection 9 — the correspondence test needs deltas
5the jam pattern is a whole number of octets802.3alignment errors appear and Section 12's mask changes
6the half-duplex end knows it is half-duplexits own configurationSection 15's audit is impossible
7the traffic contains frames above 64 octetsnothingSection 6's structural zero — the fault is invisible
8the size histogram's buckets are as publishedChapter 19.7 §2Section 7's weighting is wrong
9the link is point-to-pointmodern practiceon a real shared segment, both ends colliding is normal

Row one is the assumption that inverts the chapter's headline and it is worth the arithmetic. At 1 Gb/s, carrier extension makes the slot time 4 096 bit times, so the late fraction is:

FrameLate fraction at 512 bitsat 4 096 bits
64 octets0.00%0.00%
512 octets87.50%0.00%
1 000 octets93.60%48.80%
1 518 octets95.78%66.27%

The safe size moves from 64 octets to 512 — a factor of eight — and a diagnosis calibrated at 100 Mb/s reports a gigabit mismatch as healthy for every frame below 512 octets. The saving grace is that gigabit half-duplex is rare; the trap is that "rare" is not "absent", and the model is silently wrong rather than loudly inapplicable.

Row three is the assumption that makes the numbers optimistic. Real traffic is bursty, so the far end's frame starts cluster — and a cluster during our frame is more likely to overlap it than a Poisson process of the same mean rate. The measured collision rate on real traffic runs above 1 − e^(−u), which means Section 6's table is a floor rather than an estimate, and every projection in Section 13 is conservative.

Row nine is the assumption that would have been false for the first twenty years of Ethernet. On a genuinely shared segment both ends collide and that is correct behaviourChapter 11.4 §3's "collisions at one end only" is decisive precisely because shared segments no longer exist. The symptom's 1.81 bits are borrowed from the topology, not from the protocol, and on a hub they are worth nothing at all.

And three things deliberately not assumed:

Not assumedWhy not
that zero late collisions means no mismatchSection 6's structural zero
that the loss today is the fault's costSection 13 — up to 6 400% amplification
that one end's counters are a diagnosisChapter 11.4 §3, and Section 10's disjoint sets

Row three is the chapter's structural finding and it is stronger than the others. The two ends' counter sets do not intersect at all — four transmit counters against three receive counters — so "compare the two ends" is not a comparison and cannot be one. It is a join between two different quantities, and the pattern it looks for is a correspondence rather than an agreement.


19. The Cost, Accounted

A mismatch diagnosis is counters crossed with a size histogram, and the histogram already exists.

BlockFlopsNature
dupmis_pkg0a slot time and a ratio
collision_kind_split~161five counters and a sticky bit
late_collision_discriminator — 7 × 2 × 32~455collisions crossed with size
size_loss_model0combinational
two_end_counter_join0combinational
fragment_provenance~32one counter
load_conditioned_alarm0combinational
dupmis_telemetry0combinational
dupmis_conformance_monitor0combinational
total~648 flops

Five of the nine blocks are pure combinational logic and one block is 70% of the cost — the collision-by-size cross, which is the same shape as Chapter 21.3 §19's finding: the expensive part is always the one that bins something.

And the addition to a design is smaller than the total, because two of the counters are already required.

AdditionFlopsBuys
late_collisions, separately from collisionsalready required by RMONSection 3's decisive proof
collisions crossed with the size histogram~455the late ratio, and the prediction
fragment lengths logged rather than binned~0 — a fieldSection 11's provenance
the far end's duplex setting, collected~0 — a management readSection 15's audit, which needs no traffic

Row four is the cheapest and the most effective and it is not a hardware change at all. A MAC already knows its own duplex; a management system that collects it for both ends of every cable finds every mismatch in a building by comparison, before any traffic, before any counter moves, and before Section 13's alarm has anything to project.

Finds a mismatchNeeds
the configuration auditalwaysa management read at both ends
late collisionsonly above 64-octet traffictraffic, and load
the correspondence testonly with both ends' countersa management path, and load
the application's complainteventuallya user

Row one dominates rows two and three on every axis — it is cheaper, faster, and works on a link carrying nothing — and the reason the rest of the chapter exists is that the audit tells you a mismatch is present and nothing about what it is costing. Section 13's projection is the other half, and it is the half that gets the change scheduled.

And the audit has one blind spot that the counters do not, which is why neither replaces the other.

The audit seesThe counters see
a configured mismatchyesonly under the right traffic
a negotiated mismatchno — both ends report what they resolved toyes
a mismatch on a link carrying nothingyesno
the costnoyes, and only at the current load

Row two is the gap and it is Chapter 11.4 §2's cause 2. A lost link pulse can make one end negotiate a step down while both ends report themselves as auto-negotiating and both report a resolved duplexso the two configured settings agree and the two resolved settings do not. The audit has to compare resolved duplex rather than configured duplex, which most management interfaces expose as separate fields and most collectors gather only one of.

Module 21's running instrumentation bill, five chapters in:

ChapterFlops to addShare of the datapath
Chapter 21.1 §19~2972.1%
Chapter 21.2 §19~4263.0%
Chapter 21.3 §19, logged~7925.6%
Chapter 21.4 §19~710.5%
this chapter~4553.2%
total~2 04114.4%

Fourteen point four per cent, and this chapter's share buys the one fault in the module whose cost is a projection rather than a measurement — which is the only kind that can be fixed before it is felt.


20. Properties Worth Asserting, and One Worth Refusing

A conforming half duplex segment cannot produce a late collision, because the slot time was sized so that it cannot. So asserting that no late collision ever occurs is normative, correct and exactly the property to write. Its failure probability, however, is decided entirely by the verification environment. With sixty four octet frames the probability is exactly zero at any far end load, because no part of a five hundred and twelve bit frame lies beyond a five hundred and twelve bit slot time. With fifteen hundred and eighteen octet frames it is nought point nine five per cent at one per cent load, twenty one per cent at a quarter load and thirty seven point seven per cent at half load. The design is equally misconfigured in every one of those cases. What changed is the frame size the generator chose and the background load it offered. And the zero is structural rather than small, which is what distinguishes this from a rare event: running ten times as long finds a rare event ten times more often and finds this one exactly as often, which is never. The repair is to condition the property on the frame size that can violate it, to assert separately the structural fact that a minimum size frame is immune, to assert the configuration itself which needs no traffic at all, and to cover the generator ever having sent a frame large enough to matter.No latecollisionsnormative and correctGenerator sends64P(fail) = exactly 0Generator sends 1518P(fail) = 0.95% to37.7%Same brokenconfigin bothZero, not smalla longer run findsnothingCondition on thesizethe antecedent statesitAssert theconfigurationno traffic neededCover a largeframeor property 1 issilent too12
Figure 4 — a property whose failure probability the generator sets, and one setting makes it exactly zero.

Thirty-three properties and eight covers, in four groups: the slot time, the two ends, the loss model, and the blindness.

Group one — the slot time and the two collision kinds.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Chapter 9.1 Section 5's slot time as a classifier, and the two
// outcomes whose costs differ completely.
p_kind_by_slot:      assert property (@(posedge clk) disable iff (!rst_n)
                       (kind == COLL_LATE) |-> (bits_transmitted > 16'(SLOT_BITS)));

p_early_is_bounded:  assert property (@(posedge clk) disable iff (!rst_n)
                       (kind == COLL_EARLY) |-> (bits_transmitted <= 16'(SLOT_BITS)));

p_early_not_lost:    assert property (@(posedge clk) disable iff (!rst_n)
                       (kind == COLL_EARLY) |=>
                         (c_frames_lost == $past(c_frames_lost)));

p_late_is_lost:      assert property (@(posedge clk) disable iff (!rst_n)
                       (kind == COLL_LATE) |=>
                         (c_frames_lost == $past(c_frames_lost) + 32'd1));

p_min_frame_safe:    assert property (@(posedge clk) disable iff (!rst_n)
                       (wire_len == 14'(MIN_FRAME_OCTETS)) |-> (kind != COLL_LATE));

p_late_is_sticky:    assert property (@(posedge clk) disable iff (!rst_n)
                       late_seen |=> always late_seen);

p_kinds_exclusive:   assert property (@(posedge clk) disable iff (!rst_n)
                       kind_valid |-> ((kind == COLL_EARLY) != (kind == COLL_LATE)));

p_no_coll_when_idle: assert property (@(posedge clk) disable iff (!rst_n)
                       !tx_active |-> (kind == COLL_NONE));

Group two — the two ends, and the fact that their counter sets are disjoint.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
p_sets_disjoint:     assert property (@(posedge clk) disable iff (!rst_n)
                       ((HALF_DUPLEX_END & FULL_DUPLEX_END) == 7'd0));

p_hd_no_fcs:         assert property (@(posedge clk) disable iff (!rst_n)
                       we_are_half_duplex |-> (our_fcs_errors == 32'd0));

p_fd_no_collisions:  assert property (@(posedge clk) disable iff (!rst_n)
                       !we_are_half_duplex |-> (our_collisions == 32'd0));

p_one_sided_needs2:  assert property (@(posedge clk) disable iff (!rst_n)
                       one_sided_collisions |-> far_valid);

p_correspondence:    assert property (@(posedge clk) disable iff (!rst_n)
                       cross_correspondence |-> (hd_late > 32'd64));

p_confirm_needs_both:assert property (@(posedge clk) disable iff (!rst_n)
                       mismatch_confirmed |->
                         (one_sided_collisions && cross_correspondence));

p_far_end_flagged:   assert property (@(posedge clk) disable iff (!rst_n)
                       !far_valid |-> need_far_end);

p_late_is_proof:     assert property (@(posedge clk) disable iff (!rst_n)
                       proven_by_late |-> (confidence >= 3'd3));

Group three — the loss model, and its predicted values.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
p_late_frac_monotone:assert property (@(posedge clk) disable iff (!rst_n)
                       (wire_len > 14'(MIN_FRAME_OCTETS)) |->
                         (late_fraction_ppt(int'(wire_len)) > 0));

p_late_frac_bounded: assert property (@(posedge clk) disable iff (!rst_n)
                       late_fraction_ppt(int'(wire_len)) < 1000);

p_min_frac_zero:     assert property (@(posedge clk) disable iff (!rst_n)
                       (wire_len <= 14'(MIN_FRAME_OCTETS)) |->
                         (late_fraction_ppt(int'(wire_len)) == 0));

p_ratio_bounded:     assert property (@(posedge clk) disable iff (!rst_n)
                       late_ratio_ppt <= 16'd1000);

p_prediction_checked:assert property (@(posedge clk) disable iff (!rst_n)
                       prediction_holds |-> (c_frames_tx > 32'd1000));

p_projection_ge_now: assert property (@(posedge clk) disable iff (!rst_n)
                       (far_end_util_ppt < 16'd632) |->
                         (loss_at_full_load_ppt >= loss_now_ppt));

p_alarm_on_forecast: assert property (@(posedge clk) disable iff (!rst_n)
                       alarm |-> (loss_at_full_load_ppt > 16'd50));

p_quiet_needs_low:   assert property (@(posedge clk) disable iff (!rst_n)
                       quiet_link_warning |-> (far_end_util_ppt < 16'd50));

p_model_disagreement:assert property (@(posedge clk) disable iff (!rst_n)
                       model_disagrees |-> (total_coll > 32'd64));

Group four — the blindness, which is the group that exists because of Section 20's refused property.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
p_blind_is_traffic:  assert property (@(posedge clk) disable iff (!rst_n)
                       blind_traffic |-> (mean_late_fraction_ppt < 16'd10));

p_blind_not_unsound: assert property (@(posedge clk) disable iff (!rst_n)
                       blind_traffic |-> (diagnosis_sound || one_ended_diagnosis));

p_zero_needs_qual:   assert property (@(posedge clk) disable iff (!rst_n)
                       ((c_late_collisions == 32'd0) && (confidence == 3'd0))
                         |-> (traffic_cannot_show_it || !blind_traffic));

p_bucket0_zero:      assert property (@(posedge clk) disable iff (!rst_n)
                       (mismatch_confirmed && bucket0_is_zero) |-> 1'b1);

p_load_floor:        assert property (@(posedge clk) disable iff (!rst_n)
                       load_too_low |-> (far_end_util_ppt < 16'd10));

p_bidirectional:     assert property (@(posedge clk) disable iff (!rst_n)
                       !bidirectional_tested |-> one_directional_test);

p_conflation_flag:   assert property (@(posedge clk) disable iff (!rst_n)
                       collisions_summed |-> counters_conflated);

p_sound_excludes:    assert property (@(posedge clk) disable iff (!rst_n)
                       diagnosis_sound |->
                         (!one_ended_diagnosis && !counters_conflated));

p_gig_slot:          assert property (@(posedge clk) disable iff (!rst_n)
                       slot_time_wrong |-> model_disagrees);

And eight covers, because six of these states need a traffic mix a default regression does not generate.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
c_late_collision:  cover property (@(posedge clk) kind == COLL_LATE);
c_early_only:      cover property (@(posedge clk) (c_early > 32'd1000) && (c_late == 32'd0));
c_min_size_only:   cover property (@(posedge clk) blind_traffic);
c_both_ends:       cover property (@(posedge clk) mismatch_confirmed);
c_one_sided:       cover property (@(posedge clk) one_sided_collisions);
c_quiet_link:      cover property (@(posedge clk) quiet_link_warning);
c_bucket0_zero:    cover property (@(posedge clk) bucket0_is_zero && (c_late > 32'd0));
c_frag_at_slot:    cover property (@(posedge clk) collision_abort_likely);

21. Verification Scenarios

Fifty-eight scenarios, plus a five-run directed test whose variable is the generator's frame size — because that is what decides whether the fault is observable at all.

The slot time and collision kinds — 11 scenarios.

#ScenarioExpected
1collision at bit 100 of a 1 518-octet frameCOLL_EARLY; the frame is retried
2collision at bit 600 of the sameCOLL_LATE; the frame is lost
3collision at bit 512 exactlyearly — the boundary is inclusive
4collision at bit 513late
5any collision on a 64-octet frameearly, always
6ten thousand early collisionsc_frames_lost = 0
7ten thousand late collisionsc_frames_lost = 10 000
8the RMON collisions counter on both10 000 in both cases
9one late collision, everlate_seen sticky — proof
10a collision with tx_active lowCOLL_NONE
11at a 4 096-bit slot time, a 512-octet frameearly, always — Section 18's row one

The loss model — 12 scenarios.

#ScenarioExpected
12u = 1%, 1 518-octet framesloss 0.95%
13u = 10%, same9.12%
14u = 25%, same21.19%
15u = 50%, same37.69%
16u = 50%, 64-octet frames0.00%
17u = 50%, 128-octet frames19.67%
18late fraction at 1 51895.78%
19late fraction at 640.00%
20late fraction at 9 00099.29%
21expected attempts at u = 50%, min size1.649
22P(sixteen collisions) at u = 50%3.3 × 10⁻⁷
23projected loss at full load, 1 51860.5%

The two ends — 10 scenarios.

#ScenarioExpected
24half-duplex end's fcs_errorszero
25full-duplex end's collisionszero
26the two counter sets intersectedempty
27collisions at one end, zero at the otherone_sided_collisions
28both ends colliding — a real shared segmentnot one-sided; correct behaviour
29HD late collisions against FD fragmentsratio near 1 000 ppt
30the ratio at 1 200 pptoutside tolerance; no correspondence
31far end unavailableneed_far_end
32far end unavailable, one late collision seenconfidence 3 anyway — it is proof
33two ends read a minute apartdeltas correlate; absolute counts do not

What the other chapters' methods say — 9 scenarios.

#ScenarioExpected
34Chapter 21.1's mask at the FD end, four readingsconverges on the parser — wrong
35the same plus c_oversizeempty mask; contradiction
36Chapter 21.3's slope, buckets 1 and 52.849
37against its thresholdsslope_ambiguous — no verdict
38the slope at u = 5% instead of 25%still 2.849 — load-independent
39bucket 0's error rateexactly zero
40a channel fault's bucket 0non-zero, 19.86× below bucket 5
41a logic fault's bucket 0non-zero, equal to bucket 5
42the bucket-0 testseparates all three in one comparison

Blindness and load — 8 scenarios.

#ScenarioExpected
43a link carrying only 64-octet framesblind_traffic; zero late collisions forever
44that link, run for a yearstill zero
45that link, far end at 90% loadstill zero
46evidence_below_floor on itasserts
47far end at 0.5% load, 1 518-octet traffic0.48% loss — below most thresholds
48quiet_link_warning on itasserts — the projection is 60.5%
49amplification on itabout 6 400%
50a one-directional download testfull rate; healthy — and wrong

Fragments and provenance — 8 scenarios.

#ScenarioExpected
51fragment lengths after early collisionsclustered near 68 octets
52fragment lengths after late collisionsspread across the frame
53fragment lengths after a cut cablespread
54collision_abort_likely on a clusterasserts
55the same with far-end late collisions knownprovenance 3 regardless of lengths
56Chapter 21.2 §17's three causes plus this onefour, and only this one has a companion counter
57c_self_inflicted above half the fragmentsprovenance 2 — our own truncation
58fragments with no far-end data and no clusterprovenance 1 — a cut, by elimination

And the directed test, because random stimulus will not produce it.

The case: one misconfigured link, five generator settings, and the fault is found in two of them.

The variable is not in the design and not on the wire. It is the frame size the generator chose — and Section 6 showed that at one setting the failure probability is exactly zero. A constrained-random generator with a default size distribution weighted towards minimum size, which is what most environments use because it maximises frame rate, will not find this fault in any run of any length.

RunGenerator's frame sizeFar-end loadP(late collision per frame)
A64 octets50%0.000
B64 octets90%0.000
C128 octets10%0.048
D1 518 octets1%0.010
E1 518 octets50%0.377

The oracle is four-part and runs A and B are the controls that matter.

PartABCDE
p_no_late_collisions failsneverneveroftensometimesconstantly
the design's configurationbrokenbrokenbrokenbrokenbroken
blind_trafficassertedassertedlowlowlow
loss0%0%4.76%0.95%37.69%

Row two is the control and it is the whole test. The link is identically misconfigured in all five runs — the same duplex mismatch, the same two devices, the same cable. Rows one and four move from "never" to "constantly" and from 0% to 37.7%, and none of that movement is about the design.

Runs A and B together are the important pair. Raising the far-end load from 50% to 90% — nearly doubling the collision probability — changes the failure count from zero to zero, because the frame size is what makes it structurally impossible. No amount of load, no amount of time, no seed. That is the distinction between this class and a rare event, and it is why Section 20 refuses the unconditioned property.

Run D is the one that is most misleading in practice. A one per cent loss at one per cent load passes most monitoring thresholds and is a 60.5% loss waiting for a busy afternoon — Section 13's projection — and the run that finds it is the run nobody schedules, because a 1% loss in a regression looks like noise.


22. Debugging a Duplex Mismatch

Six complaints.

Complaint 1 — "ping is fine so the link is fine."

CheckIf yesMeaning
what size are the pings?64 octets, paddedSection 8 — structurally immune
does a large ping fail?oftentry 1 400 bytes of payload
is the loss size-dependent?yesand that is the signature
did anybody test the other direction?nothe mismatch is unidirectional

A default ping sends a frame that cannot suffer a late collision, and ARP and TCP acknowledgements are the same 64 octets by Chapter 5.6's padding rule. Every small exchange works perfectly and the application does not, which is the report that arrives and the observation that is dismissed.

Complaint 2 — "there are collisions but it is a switched link, so the counter is broken."

CheckIf yesMeaning
is our end half-duplex?yesthen it runs CSMA/CD
is the far end full-duplex?check itthat is the fault
are there late collisions?yesproof — Chapter 9.1 §5
does the far end report collisions?noone_sided_collisions

The counter is not broken and the link is not shared. A half-duplex MAC runs CSMA/CD whatever is at the other end, and a full-duplex partner transmitting into it produces exactly the collisions the counter is for. Rows three and four are the two decisive symptoms Chapter 11.4 §3 measured at 1.81 bits each.

Complaint 3 — "the FCS errors say the cable is bad and we replaced it."

CheckIf yesMeaning
which end sees the FCS errors?the full-duplex oneSection 10
does the other end see collisions?yesit is aborting frames
do fragment and late-collision counts track?yescross_correspondence
is bucket 0's error rate zero?yesno channel fault has that

Row four is the free discriminator and it needs no far-end access. A channel fault damages minimum-size frames too, at a rate 19.86× below the maximum-size rate but not at zero. A duplex mismatch damages none of them at allChapter 21.3's size cross already has the data, and one comparison against zero separates this fault from both of that chapter's categories.

Complaint 4 — "the monitoring system says the link is 3% utilised and the users say it is slow."

CheckIf yesMeaning
is there a duplex mismatch?check both ends' settingsSection 15's audit
what is the frame loss?about 2%Section 17
what does TCP do at 2% loss?falls below 100 Mb/sthe inverse square root
what is the link's utilisation?3%and it is not wrong

Both numbers are correct. The link really is 3% utilised because TCP has collapsed its window and is not offering more, and the loss that caused the collapse is 2% — below every sensible alarm. Chapter 8.3 §4's throughput-against-goodput distinction is the vocabulary; the operational fact is that a utilisation graph cannot show this fault by construction.

Complaint 5 — "we fixed the duplex and the collisions stopped but throughput is still poor."

CheckIf yesMeaning
are late collisions zero now?yesthe mismatch is fixed
are FCS errors zero at the far end?yesconfirmed from both ends
is TCP still slow?sometimes, for a whilecongestion state persists
is there a second fault?check the conservation identityChapter 21.1 §17

Row three is usually the answer and it is not a network fault. A connection that has spent hours at a collapsed window recovers over its own timescale, and a benchmark run immediately after the fix measures the recovery rather than the link. Row four is the check that costs six register reads and distinguishes "still recovering" from "a second fault was masked by the first."

Complaint 6 — "our gigabit link has a duplex mismatch and none of these numbers match."

CheckIf yesMeaning
what is the slot time?4 096 bit timesSection 18's row one
what is the safe frame size?512 octets, not 64eight times larger
model_disagrees?yesthe model is calibrated at 100 Mb/s
is gigabit half-duplex even configured?rarely, and checkit is unusual, not impossible

Carrier extension moves the boundary by a factor of eight, so every frame below 512 octets is immune and the late fraction at 1 518 octets falls from 95.78% to 66.27%. The chapter's arithmetic is right and its constant is wrong for this link, which model_disagrees catches and a reader who trusts the table does not.

Complaint 7 — "both ends are set to auto-negotiate, so there cannot be a mismatch."

CheckIf yesMeaning
are both ends really auto?check, do not assumeone is usually forced
does one end report a forced setting?yesChapter 11.4 §2's cause 7
what does the auto end detect?parallel detectionChapter 11.1 §8
what duplex does parallel detection choose?halfand the forced end is full

This is the commonest way a mismatch is created and it involves no fault at all. A forced end sends no negotiation bursts; the auto end falls back to Chapter 11.1 §8's parallel detection, which can determine the speed from the signalling and cannot determine the duplex — so it chooses half, per the standard. The forced end is full duplex because somebody configured it that way. Two correctly-behaving devices, one mismatch, and Chapter 11.1 §9 says exactly what parallel detection can and cannot determine.

And the three symptoms this chapter is systematically blamed for:

SymptomBlamed onUsually is
FCS errors at one endthe cablethe other end aborting frames
collisions on a switched linka broken countera half-duplex MAC doing its job
slow transfers on an idle linkthe application2% loss and an inverse square root

23. Misconceptions

Misconception 1 — "a duplex mismatch shows up as errors."

The wrong model: a misconfigured link produces error counts, so the counters will find it.

What it costs: it produces error counts only on frames larger than the slot time. A link carrying acknowledgements, ARP and control traffic — all 64 octets by Chapter 5.6's padding rule — shows zero late collisions forever, at any load, for any length of time. The fault is present, costly the moment anybody sends a large frame, and completely invisible until then.

The corrected model: the counters are conditional on the traffic. The unconditional instrument is the configuration: both ends know their own duplex, and comparing them finds every mismatch in a building with no traffic at all. Section 19 prices it at zero hardware.

Misconception 2 — "collisions mean a shared segment."

The wrong model: collisions are a CSMA/CD phenomenon and CSMA/CD implies a shared medium.

What it costs: a half-duplex MAC runs CSMA/CD whatever is at the other end, and a full-duplex partner transmitting into it produces genuine collisions on a point-to-point link. The counter is correct and the conclusion is not. An engineer who dismisses the counter as broken has dismissed the 1.81-bit symptom Chapter 11.4 §3 identified as one of only two decisive ones.

The corrected model: collisions at one end only are impossible under contention — on a shared segment both ends collide. One-sided collisions are the fault's signature, and a late collision is stronger still: Chapter 9.1 §5 sized the slot time so that a conforming segment cannot produce one.

Misconception 3 — "larger frames are always better."

The wrong model: Chapter 8.3 §2's efficiency curve says use large frames, so use large frames.

What it costs: on a mismatched link the large frames are precisely the ones that do not arrive. The late fraction at 1 518 octets is 95.78% and at 64 octets is zero — the mirror image of the efficiency curve, from the same fixed-quantity-against-variable-payload arithmetic, with the opposite conclusion. Both chapters are right in their own context.

The corrected model: the advice is conditional on the link being correctly configured, which is true of almost all performance advice and is almost never stated. On a mismatched link the efficient frame size and the surviving frame size are at opposite ends of the range.

Misconception 4 — "the loss we measure is what the fault costs."

The wrong model: the frame loss is 0.95%, so the fault costs 0.95%.

What it costs: 0.95% is what it costs at the far end's current one per cent utilisation. At full load the same fault costs 60.5% — an amplification of about 6 400% — and the difference is entirely the network's quietness. A ticket that reports today's figure gets deprioritised; the same ticket reporting the projection gets fixed on the quiet afternoon when the fix is free.

The corrected model: report two numbers. The measurement describes the traffic; the projection describes the fault, and only the second one is a property of the link. Section 13's amplification is the ratio between them.

Misconception 5 — "a healthy utilisation graph means a healthy link."

The wrong model: the link is 3% utilised, so it has plenty of headroom.

What it costs: at 2% frame loss a loss-based congestion control collapses its window, so the link is 3% utilised because nothing is offering more — and most of those octets are retransmissions. Chapter 8.3 §4's throughput-against-goodput distinction is exactly this, and a utilisation graph measures the wrong one of the two by construction.

The corrected model: a link whose utilisation is low and whose users complain is not a contradiction; it is the signature. The loss rate that produces it — about 2% on a 100 Mb/s link, 0.02% at gigabit — is below every ordinary alarm threshold, and the threshold is not the problem: the inverse square root is.

Misconception 6 — "we tested it and it ran at line rate."

The wrong model: a throughput test passed, so the link is fine.

What it costs: the mismatch damages one direction only — the half-duplex end's transmissions — so a test that measured the other direction reports full rate, correctly. A download from a server across a mismatched link is unaffected; the upload collapses, and which one a benchmark chose is a coin flip.

The corrected model: test both directions, always, and on this fault more than on any other in Module 21, because it is the only one in the module whose effect is unidirectional by construction rather than by accident.


24. Interview Questions

Question 1 — "Why does ping work and the file transfer fail on a duplex-mismatched link?"

What the answer should establish: the slot time is 512 bit times and a minimum frame is 512 bits. A collision on a 64-octet frame can never be late, and a collision that is not late is retried by the MAC and succeeds. A strong answer gives the other end of the curve: a 1 518-octet frame is 12 144 bits, of which 95.78% lie beyond the slot time, and a late collision is not retried. The strongest answer notes that ARP and TCP acknowledgements are padded to 64 octets too, so almost everything small is immune.

Question 2 — "How much does a duplex mismatch cost?"

What the answer should establish: that the question needs two parameters — the far end's load and the frame size — and the fault contributes neither. Loss is about (1 − e^(−u)) times the late fraction, so at 10% load with maximum-size frames it is 9.12% and at any load with minimum-size frames it is exactly zero. A strong answer gives the projection: 60.5% at full load, and notes that the number worth reporting is the projection rather than today's measurement.

Question 3 — "The two ends of a mismatched cable report different faults. Which is right?"

What the answer should establish: both, and their counter sets do not intersect. The half-duplex end sees collisions, late collisions and deferrals — four transmit counters; the full-duplex end sees FCS errors, fragments and undersize — three receive counters. A strong answer names the join: the half-duplex end's late-collision count and the full-duplex end's fragment count are the same events counted from two sides and should track one-to-one.

Question 4 — "You are at the full-duplex end and see FCS errors and fragments. What does the standard method conclude?"

What the answer should establish: an empty candidate mask, if the oversize counter is read. Chapter 21.1's intersection eliminates the channel, PHY and xMII on the zero alignment count, narrows to the parser on the undersize count, and then eliminates the parser on the zero oversize count — a contradiction, which is the correct answer because the fault is outside its twelve sites. A strong answer notes what happens without that one register: a confident, wrong diagnosis of the frame parser.

Question 5 — "What single free observation separates this from a channel fault?"

What the answer should establish: the error rate in the smallest size bucket, against zero. A channel fault damages minimum-size frames at a rate 19.86× below the maximum-size rate — non-zero. A logic fault damages them at the same rate as everything else — non-zero. A duplex mismatch damages none of them at all. A strong answer notes that Chapter 21.3's size cross already has the data, and that its slope test lands at 2.849 — inside its own ambiguous band — so it correctly refuses rather than answering wrongly.

Question 6 — "How would you find every duplex mismatch in a building?"

What the answer should establish: not with counters. Every MAC knows its own configured duplex; a management system that collects it for both ends of every cable finds every mismatch by comparison — no traffic, no load, no waiting for a frame large enough to produce evidence. A strong answer contrasts it with the counter-based route: that one works only above 64-octet traffic, only under load, and only with both ends' counters, and it tells you the cost, which the audit does not.


25. Questions and Answers


26. What's Next

Module 21 has four chapters left, and this one has established the pattern the next three follow: a fault whose visibility is a function of the traffic rather than of the fault.

ChapterTakesWhat makes it invisible
this chaptera duplex mismatchthe frame size — a structural zero at 64 octets
Chapter 21.6Chapter 21.1 §4's class Gfive sites with no counter between them
Chapter 21.7Chapter 19.6's descriptorsa fault no frame can produce
Chapter 21.8a link that is slow and correctno error counter moves at all

Chapter 21.6 is the batch's hardest and it inherits this chapter's most useful instrument. Section 12 showed that Chapter 19.7 §2's size histogram is the only thing in a MAC conditioned on size, and that a structural zero in bucket 0 named this fault for free. An MTU mismatch drops only frames above a threshold — the same shape, a different threshold — and that is the one member of class G a size-conditioned instrument can reach. Which of the other four it cannot reach is the question that chapter has to answer honestly.

Chapter 21.7 takes the fault Chapter 20.5 §12 proved no frame can produce. A consumer stall long enough to overflow Chapter 19.5's buffer is not reachable from the wire at any rate, in any pattern — so it arrives in that chapter as the thing being diagnosed rather than injected, and the descriptor-ownership space around it is Chapter 19.6's outstanding count read as evidence.

And the series is now ninety-eight classes long. Chapter 21.4 §20's class 97 was a property silenced by the fault; class 98 is a property silenced by the generator, and the two are the same shape with different agency. Together with Chapter 20.4 §20's class 91 — a metric the environment can improve by shrinking a denominator — they form a family about who controls a property's evaluation count, which is a ninth group and is a different axis entirely from Chapter 21.2 §26's eighth. Chapter 21.8 is where it will have to be settled, because a chapter about a link with no errors at all is a chapter about properties that never evaluate.


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.