Skip to content
VLSI Mentor

Ethernet · Module 1

Why Ethernet Won

Ethernet offered weaker guarantees than token passing on every axis compared at the time. It won because failure was local rather than global, because two vendors had almost nothing to disagree about, and because a media-independent interface let one MAC outlive every physical layer it was attached to.

Module 1 has built the case against Ethernet. Its access method is probabilistic where alternatives were deterministic. It wastes channel time on collisions. It offers no delay bound, no fairness guarantee, and no delivery guarantee. Chapter 1.2 showed a station that can fail sixteen times and discard the frame.

Contemporary alternatives fixed all of that. Token-passing schemes gave bounded access delay, provable fairness, and no collisions at all — by construction, not by probability.

Ethernet won anyway, comprehensively enough that "networking" and "Ethernet" are now near-synonyms in most contexts.

Why did the design with weaker guarantees win, and what did its dominance lock in for the engineers who build silicon against it?

The answer is not that the guarantees did not matter. It is that they were bought at a price that turned out to be the wrong price, and this chapter puts numbers on it.

1. What the Alternatives Actually Offered

Take the competition seriously, because a chapter that dismisses it explains nothing.

A token-passing network circulates a distinguished pattern — a token — among stations in a defined order. A station may transmit only while holding it, then passes it on. From that one rule, real guarantees follow:

No collisions, structurally. Exactly one station may transmit, so contention cannot produce a collision. Not "rarely" — never.

A bounded access delay. With N stations and a bounded holding time, the worst-case wait for the token is bounded. A station can be told when it will get to send, which Chapter 1.2's backoff can never do.

Provable fairness. Every station gets the token once per rotation. There is no capture effect, no station that loses repeatedly, and no statistical argument required.

Graceful degradation under load. As load rises, a token network approaches full utilisation. Chapter 1.1 §8 showed the opposite for CSMA/CD: collisions consume channel time and retransmissions add load, so throughput degrades rather than saturating.

Every one of those is a real advantage, and each is exactly what a control network or an industrial system wants. It is why deterministic mechanisms have been added back to Ethernet ever since — Module 17 is that project.

2. The Cost, Made Explicit

The guarantees rest on one thing: the token exists, and exactly one exists. That is a distributed invariant, and every cost below is the cost of maintaining it.

What if the token is lost? A station holding it fails, or a corrupted frame destroys it. Every station now waits forever. So there must be a timer at each station, a rule about who regenerates it, and a way to ensure two stations do not regenerate simultaneously.

What if there are two tokens? A regeneration race, or a corruption that duplicates it. Two stations now believe they may transmit, so collisions occur — on a network with no collision detection, because it was designed not to need any.

What if a station joins or leaves? The logical order must be updated at every station. That needs a protocol, and the protocol must work while the order is inconsistent.

What if a station fails while holding the token? The failure must be detected, the token regenerated, and the ring order repaired — all while other stations may be timing out on the same event.

None of this is optional. It is not gold-plating that a lean implementation could omit; the guarantees are worthless without it. A station that skipped token recovery would deadlock the entire network the first time a token was lost.

Two rows. In the Ethernet row, a failing station affects only its own frame; the other stations are unaffected. In the token row, a failing station that holds the token stalls every other station until recovery completes.Ethernet station failsstops transmittingone frame lostreported to its own clientother stationsunaffected: they depended onnothingToken station failswhile holding the tokeninvariant brokenthe token no longer existsother stationsall stalled until recoverycompletes12
Figure 1 — the same fault, and how far its consequences reach.

3. RTL 1 — The Two MACs, Side by Side

The argument so far is prose. Here it is as two state machines against the same interface, which is the form an engineer can check.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ILLUSTRATIVE. Ethernet's transmit access, as states. Chapter 1.2's
// controller with the datapath removed so only the shape remains.
module eth_access_shape (
  input  logic clk, rst_n,
  input  logic tx_req, carrier_sense, collision_detect, tx_done,
  input  logic retry_grant, retry_abandon,
  output logic may_transmit,
  output logic frame_lost          // the ONLY failure this MAC can produce
);
  typedef enum logic [2:0] {
    E_IDLE, E_DEFER, E_TX, E_JAM, E_BACKOFF
  } e_state_e;
  e_state_e st_q, st_d;
 
  always_comb begin
    st_d = st_q;
    case (st_q)
      E_IDLE:    if (tx_req) st_d = carrier_sense ? E_DEFER : E_TX;
      E_DEFER:   if (!carrier_sense) st_d = E_TX;
      E_TX:      if (collision_detect) st_d = E_JAM;
                 else if (tx_done)     st_d = E_IDLE;
      E_JAM:     st_d = E_BACKOFF;
      E_BACKOFF: if (retry_abandon) st_d = E_IDLE;
                 else if (retry_grant) st_d = E_DEFER;
      default:   st_d = E_IDLE;
    endcase
  end
 
  always_ff @(posedge clk or negedge rst_n)
    if (!rst_n) st_q <= E_IDLE; else st_q <= st_d;
 
  assign may_transmit = (st_q == E_TX);
  // Note what this MAC's failure output IS: one frame. There is no state
  // here whose loss affects any other station, because there is no state
  // here that any other station depends on.
  assign frame_lost   = (st_q == E_BACKOFF) && retry_abandon;
endmodule
 
 
// ILLUSTRATIVE SKETCH of a token-passing MAC's shape. NOT a standard, and
// not complete — the point is which states EXIST and why.
module token_access_shape #(
  parameter int unsigned HOLD_LIMIT   = 64,   // illustrative
  parameter int unsigned TOKEN_TIMEOUT = 512  // illustrative
) (
  input  logic clk, rst_n,
  input  logic tx_req, tx_done,
  input  logic token_arrived,      // the shared state, arriving
  input  logic token_seen,         // someone else has it: proof it exists
  input  logic tick,
  output logic may_transmit,
  output logic token_pass,
  output logic token_claim,        // regenerating a token nobody has
  output logic frame_lost,
  output logic network_stalled,    // THE failure Ethernet cannot produce
  output logic [7:0] recovery_cnt
);
  typedef enum logic [2:0] {
    T_IDLE,      // no token here; waiting for it to arrive
    T_HOLD,      // holding the token, not transmitting
    T_TX,        // holding and transmitting
    T_PASS,      // handing it on
    T_TIMEOUT,   // token not seen for too long — is it lost?
    T_CLAIM      // regenerating, and racing every other station doing the same
  } t_state_e;
 
  t_state_e         st_q, st_d;
  logic [15:0]      idle_q;    // how long since the token was last seen
  logic [15:0]      hold_q;    // how long this station has held it
  logic [7:0]       rec_q;
 
  // TIMER 1 — the token has not been seen for too long. This timer exists in
  // EVERY station and is the network's only defence against a lost token.
  wire token_lost = (idle_q >= 16'(TOKEN_TIMEOUT));
  // TIMER 2 — this station has held the token too long. Without it, one
  // station's fault becomes an indefinite stall for everyone else.
  wire hold_expired = (hold_q >= 16'(HOLD_LIMIT));
 
  always_comb begin
    st_d = st_q;
    case (st_q)
      T_IDLE:    if (token_arrived)  st_d = tx_req ? T_TX : T_PASS;
                 else if (token_lost) st_d = T_TIMEOUT;
      T_HOLD:    st_d = T_PASS;
      T_TX:      if (tx_done || hold_expired) st_d = T_PASS;
      T_PASS:    st_d = T_IDLE;
      // Recovery. Neither of these states has any counterpart in the
      // Ethernet machine above, and together they are most of the cost.
      T_TIMEOUT: st_d = T_CLAIM;
      // The race: every station that timed out is claiming at once. Whatever
      // resolves it — a priority, a random delay, an address comparison — is
      // an additional protocol that must be right, and it must be right
      // during the one condition in which the network is already broken.
      T_CLAIM:   if (token_seen) st_d = T_IDLE;   // someone else won
                 else            st_d = T_HOLD;   // we did
      default:   st_d = T_IDLE;
    endcase
  end
 
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      st_q <= T_IDLE; idle_q <= '0; hold_q <= '0; rec_q <= '0;
    end else begin
      st_q <= st_d;
      if (token_arrived || token_seen) idle_q <= '0;
      else if (tick && !token_lost)    idle_q <= idle_q + 1'b1;
 
      if (st_q == T_IDLE)              hold_q <= '0;
      else if (tick)                   hold_q <= hold_q + 1'b1;
 
      if (st_d == T_CLAIM && st_q != T_CLAIM && rec_q != 8'hFF)
        rec_q <= rec_q + 1'b1;
    end
  end
 
  assign may_transmit    = (st_q == T_TX);
  assign token_pass      = (st_q == T_PASS);
  assign token_claim     = (st_q == T_CLAIM);
  assign frame_lost      = 1'b0;                  // it does not drop frames
  // And here is what it CAN do instead. Every station is stalled while the
  // token is missing, including stations with nothing wrong with them.
  assign network_stalled = (st_q == T_TIMEOUT) || (st_q == T_CLAIM);
  assign recovery_cnt    = rec_q;
endmodule
A six-state machine. IDLE waits for the token and moves to TX when it arrives with a frame pending, or to PASS with nothing to send. TX moves to PASS when done or when the holding timer expires. PASS returns to IDLE. If the token is not seen for too long, IDLE moves to TIMEOUT and then to CLAIM. CLAIM returns to IDLE if another station claimed first, or to HOLD if this one won.IDLETXPASSTIMEOUTCLAIMHOLDtoken · requesttoken · requestdone · hold limitdone · hold limithanded onhanded ontoken not seentoken notseenpresume lostpresume lostwe won the racewe won the racehand it onhand it on
Figure 2 — the token machine; the two lower states exist only for recovery.

Classification: both illustrative; synthesizable but neither is a design.

What it teaches: the comparison is not about line count, it is about what each machine's outputs can be. The Ethernet machine's worst output is frame_lost — one frame, one station, reported. The token machine cannot lose a frame and can instead assert network_stalled, which is every station, including the ones that are working perfectly.

Count the timers, not the states. The Ethernet machine has none of its own; its one timing dependency, backoff, lives in a separate block that can fail without affecting anyone else. The token machine needs two timers in every station, and both are part of a distributed agreement: if stations disagree about TOKEN_TIMEOUT — different vendors, different firmware versions — then the station with the shortest timeout claims first, every time, and the fairness guarantee that justified the whole design quietly stops holding.

T_CLAIM is where the real cost is. Recovery runs during the one condition in which the network is already broken, several stations may enter it simultaneously, and whatever resolves the race is an additional protocol that has to be correct under exactly the circumstances that are hardest to test. Ethernet has no equivalent state, because it has no shared invariant to repair.

Deliberately simplified: no ring-order maintenance, no station insertion or removal, no priority scheme, no monitor station, no frame stripping. Each of those is real and each adds more of the same kind of state.

Production implication: every recovery mechanism above needs its own verification, its own interoperability testing against other vendors' timeout values, and its own failure analysis — and all of it has to work during a network fault. That is the engineering bill the guarantees were bought with.

4. Counting the Difference

Numbers make the shape concrete. These are counts from the two models above, not from any product, and they are illustrative of structure rather than of area.

eth_access_shapetoken_access_shape
States56
States that exist only for recovery02 (T_TIMEOUT, T_CLAIM)
Timers in this block02
Values that must match at other stations02 (both timeouts)
Worst failure outputframe_lost — one framenetwork_stalled — every station
Correctness depends on state held elsewherenoyes: the token

The state counts are nearly equal, and that is the point. The difference is not size. Five states against six is nothing. The difference is in the last three rows: what must be agreed with strangers, what happens when the mechanism fails, and whether correctness is local.

"Values that must match at other stations" is the row that predicts field cost. Every such value is an interoperability negotiation, a specification argument, and eventually a bug found at a customer site when two vendors chose differently within the letter of a standard. Ethernet has essentially none at this layer — two stations need to agree on the frame format and the timing constants, and those are fixed numbers rather than tunable policy.

And the failure row predicts operational cost. A network whose worst case is a lost frame is debugged by looking at one station. A network whose worst case is a stall is debugged by looking at all of them, during an outage.

5. The Second Argument — Interface Stability

Simplicity explains why Ethernet survived its own era. It does not explain why the frame format of a 1980s coax network is still what crosses an 800 Gb/s optical link.

That is the media-independent interface, and it is worth stating precisely what it does.

The MAC is defined without reference to the medium. Framing, addressing, error detection, and the transmit access rules are specified in terms of bits and bit times — never in terms of voltages, wavelengths, modulation or connectors. Chapter 1.2's parameters are in bit times for exactly this reason.

The physical layer is defined without reference to the MAC. It carries bits at a rate and reports whether it can. It does not know what a frame is, what an address means, or why anything is happening.

Between them sits a defined interface — the xMII family, which Module 10 covers in detail. It is the contract, and the contract is what has held.

6. RTL 2 — One MAC, Three Physical Layers

Interface stability is a claim about a boundary. Here it is as a compile-time fact: one MAC source, three configurations, differing only in what the interface is told.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SYNTHESIZABLE. A MAC whose logic is expressed in BIT TIMES and knows
// nothing about the medium. The same source serves every rate below.
//
// NOT an xMII implementation. Module 10 owns the real interfaces.
module media_independent_mac #(
  // Everything the MAC needs is a count of bit times. Nothing here names a
  // voltage, a wavelength, a connector or a modulation scheme — and that
  // absence is the entire point of the module.
  parameter int unsigned IFG_BITS       = 96,   // NORMATIVE, every rate
  parameter int unsigned MIN_FRAME_BITS = 512,  // NORMATIVE, every rate
  parameter int unsigned DATA_W         = 8     // interface width, not a rate
) (
  input  logic clk,
  input  logic rst_n,
 
  // The ONLY rate-dependent input. Everything above is a count of these.
  input  logic bit_tick,
 
  input  logic              tx_req,
  input  logic [DATA_W-1:0] tx_data,
  input  logic              tx_last,
  output logic              tx_accept,
 
  // Toward the reconciliation sublayer and whatever PHY is attached today.
  output logic              xmit_en,
  output logic [DATA_W-1:0] xmit_data,
  output logic              pad_active,   // frame below the minimum
  output logic              ifg_active
);
 
  localparam int unsigned MIN_BEATS = MIN_FRAME_BITS / DATA_W;
  localparam int unsigned CNT_W     = $clog2(
    (MIN_BEATS > IFG_BITS ? MIN_BEATS : IFG_BITS) + 1);
 
  typedef enum logic [1:0] { M_IDLE, M_SEND, M_PAD, M_IFG } m_state_e;
  m_state_e         st_q, st_d;
  logic [CNT_W-1:0] beats_q, gap_q;
 
  always_comb begin
    st_d = st_q;
    case (st_q)
      M_IDLE: if (tx_req) st_d = M_SEND;
      // Padding to the minimum frame size, expressed in beats derived from a
      // bit count. At any rate, on any medium, the same arithmetic.
      M_SEND: if (tx_last) st_d = (beats_q + 1 < CNT_W'(MIN_BEATS)) ? M_PAD : M_IFG;
      M_PAD:  if (beats_q >= CNT_W'(MIN_BEATS) - 1) st_d = M_IFG;
      M_IFG:  if (gap_q >= CNT_W'(IFG_BITS) - 1 && bit_tick) st_d = M_IDLE;
      default: st_d = M_IDLE;
    endcase
  end
 
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      st_q <= M_IDLE; beats_q <= '0; gap_q <= '0;
    end else begin
      st_q <= st_d;
      if (st_q == M_IDLE)                         beats_q <= '0;
      else if ((st_q == M_SEND || st_q == M_PAD)) beats_q <= beats_q + 1'b1;
      if (st_d == M_IFG && st_q != M_IFG)         gap_q <= '0;
      else if (st_q == M_IFG && bit_tick)         gap_q <= gap_q + 1'b1;
    end
  end
 
  assign tx_accept  = (st_q == M_IDLE) || (st_q == M_SEND);
  assign xmit_en    = (st_q == M_SEND) || (st_q == M_PAD);
  assign xmit_data  = (st_q == M_PAD) ? '0 : tx_data;
  assign pad_active = (st_q == M_PAD);
  assign ifg_active = (st_q == M_IFG);
 
endmodule
 
 
// THE DEMONSTRATION. Three physical layers, three decades apart, three
// completely different media. ONE MAC SOURCE, and the only differences are
// the interface width and where bit_tick comes from.
module mac_across_three_phys (
  input logic clk, rst_n,
  input logic tick_10m, tick_1g, tick_10g,
  input logic tx_req_a, tx_req_b, tx_req_c,
  input logic tx_last_a, tx_last_b, tx_last_c,
  input logic [7:0]  data_a,
  input logic [7:0]  data_b,
  input logic [31:0] data_c
);
  // 10 Mb/s over coax, 1985. Manchester coded, shared medium, half duplex.
  media_independent_mac #(.DATA_W(8)) u_10m (
    .clk, .rst_n, .bit_tick(tick_10m),
    .tx_req(tx_req_a), .tx_data(data_a), .tx_last(tx_last_a),
    .tx_accept(), .xmit_en(), .xmit_data(), .pad_active(), .ifg_active());
 
  // 1 Gb/s over four-pair copper. Different coding, different topology,
  // full duplex, switched. SAME SOURCE.
  media_independent_mac #(.DATA_W(8)) u_1g (
    .clk, .rst_n, .bit_tick(tick_1g),
    .tx_req(tx_req_b), .tx_data(data_b), .tx_last(tx_last_b),
    .tx_accept(), .xmit_en(), .xmit_data(), .pad_active(), .ifg_active());
 
  // 10 Gb/s over fibre. Different physics entirely — optical, 64B/66B coded,
  // no half-duplex mode in the standard at all. SAME SOURCE, wider interface.
  media_independent_mac #(.DATA_W(32)) u_10g (
    .clk, .rst_n, .bit_tick(tick_10g),
    .tx_req(tx_req_c), .tx_data(data_c), .tx_last(tx_last_c),
    .tx_accept(), .xmit_en(), .xmit_data(), .pad_active(), .ifg_active());
endmodule

Classification: synthesizable.

What it teaches: that interface stability is a structural property with a testable form. The MAC contains no parameter naming a voltage, a wavelength, a connector, a modulation or a topology. Its entire rate dependence is one input, bit_tick, and its entire medium dependence is zero. That is why the same source elaborates against a coax link from 1985 and a fibre link from thirty years later.

What differs between the three instantiations is worth listing, because it is so short: the tick source, and the interface width. Nothing else. The padding arithmetic, the gap arithmetic, the state machine and the normative constants are identical, because they were expressed in bit times rather than in seconds.

And the counterfactual is the argument. A MAC with parameter int RATE_MBPS, or a hard-coded gap in nanoseconds, or a half_duplex assumption baked into its state machine, would need modification for each new physical layer. Modification means re-verification, and re-verification for every generation is the cost the interface avoided — thirty years of it, compounding.

Deliberately simplified: no real xMII signalling, no reconciliation sublayer, no clock-domain crossing between the MAC and the interface, no receive path, and a padding model that ignores the FCS.

Production implication: a real MAC keeps the same discipline for a harder reason — it must support several rates at run time, from one silicon instance, with the rate selected by auto-negotiation. Every parameter expressed in bit times becomes a register field; every one expressed in seconds becomes a table indexed by rate, and tables are where rate-dependent bugs live.

7. The Third Argument — What a Station Costs to Attach

Simplicity and interface stability are architectural arguments. There is a third that is purely economic, and it decided more purchasing decisions than either.

What an Ethernet station needs to attach: a transceiver and a MAC. It taps the medium, listens, and transmits. If it is powered off, unplugged or broken, it stops doing those things and nothing else in the network is affected — it is simply absent.

What a ring station needs to attach: everything above, plus a way to not break the ring when it is not participating. A ring is a closed path through every station. A station that powers down is a gap in that path, and a gap in a closed path stops all traffic.

So a ring station needs a bypass — a relay or switch that closes the ring around it when it is not active. That is a physical component, in every station, whose only job is to make the station's absence survivable.

RequirementEthernet stationRing station
Medium interfacetransceivertransceiver, two directions
Access logicMACMAC plus token state and two timers
Behaviour when powered offabsentmust actively bypass
Extra hardware for absencenonebypass relay and its control
Effect of getting it wrongthis station does not workthe network does not work

The last row is the third argument in one line. On Ethernet a station's failure mode is that the station fails. On a ring, a station's failure mode can be that the network fails — so every station carries hardware whose purpose is to prevent its own absence from being catastrophic, and that hardware is on the bill of materials of every unit shipped.

8. RTL 3 — The Bypass Relay, and What It Must Never Get Wrong

The bypass is worth building, because its control logic has a property that is unusual and instructive: it must behave correctly while the station it lives in is failing.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SYNTHESIZABLE. Decides when this station is inserted into the ring and
// when the ring is closed around it.
//
// NOT a ring standard. The relay is physical; this is its control. Every
// parameter is illustrative.
module ring_bypass_control #(
  parameter int unsigned WATCHDOG_LIMIT = 1024,  // illustrative
  parameter int unsigned INSERT_SETTLE  = 64     // illustrative
) (
  input  logic clk,
  input  logic rst_n,
  input  logic tick,
 
  input  logic station_ready,     // this station wants to participate
  input  logic mac_heartbeat,     // the MAC is alive and progressing
  input  logic ring_signal_ok,    // the upstream side is carrying signal
 
  // Drives the physical relay. ASSERTED means INSERTED; deasserted means the
  // ring is closed around this station.
  output logic insert_ring,
  output logic bypassed,
  output logic watchdog_tripped,
  output logic [7:0] bypass_events
);
 
  typedef enum logic [1:0] {
    R_BYPASS,   // out of the ring; the ring is closed around us
    R_SETTLE,   // relay operated; waiting for the ring to stabilise
    R_INSERTED  // participating
  } r_state_e;
 
  r_state_e         st_q, st_d;
  logic [15:0]      wdog_q;
  logic [15:0]      settle_q;
  logic [7:0]       events_q;
 
  // The watchdog is the whole design. If the MAC stops progressing — hung,
  // reset, powered down mid-operation — nothing else in the network can tell
  // the difference between that and a slow station, so THIS station must
  // remove itself. A station that cannot detect its own failure is a station
  // that takes the ring down with it.
  wire wdog_expired = (wdog_q >= 16'(WATCHDOG_LIMIT));
 
  always_comb begin
    st_d = st_q;
    case (st_q)
      R_BYPASS:   if (station_ready && ring_signal_ok) st_d = R_SETTLE;
      R_SETTLE:   if (settle_q >= 16'(INSERT_SETTLE))  st_d = R_INSERTED;
      // Three ways out, and all of them must work while the station is in
      // trouble. This is the opposite of the usual design assumption.
      R_INSERTED: if (!station_ready || wdog_expired || !ring_signal_ok)
                    st_d = R_BYPASS;
      default:    st_d = R_BYPASS;
    endcase
  end
 
  always_ff @(posedge clk or negedge rst_n) begin
    // RESET GOES TO BYPASS, not to inserted. A station coming out of reset
    // has no idea what state the ring is in, and inserting into a ring that
    // is mid-recovery makes the recovery worse. The safe default for a
    // shared invariant is always "do not participate".
    if (!rst_n) begin
      st_q <= R_BYPASS; wdog_q <= '0; settle_q <= '0; events_q <= '0;
    end else begin
      st_q <= st_d;
 
      // The watchdog counts UP unless the MAC proves it is alive. An
      // absent heartbeat is indistinguishable from a dead station, and
      // treating it as alive is the failure this block exists to prevent.
      if (mac_heartbeat)                wdog_q <= '0;
      else if (tick && !wdog_expired)   wdog_q <= wdog_q + 1'b1;
 
      if (st_d == R_SETTLE && st_q != R_SETTLE) settle_q <= '0;
      else if (st_q == R_SETTLE && tick)        settle_q <= settle_q + 1'b1;
 
      if (st_d == R_BYPASS && st_q == R_INSERTED && events_q != 8'hFF)
        events_q <= events_q + 1'b1;
    end
  end
 
  assign insert_ring      = (st_q == R_INSERTED) || (st_q == R_SETTLE);
  assign bypassed         = (st_q == R_BYPASS);
  assign watchdog_tripped = wdog_expired;
  assign bypass_events    = events_q;
 
endmodule

Classification: synthesizable.

What it teaches: a design requirement that has no Ethernet counterpart — logic whose correctness matters most when the surrounding station is broken. The watchdog must fire when the MAC is hung. The relay must operate when the station is losing power. Reset must land in bypass rather than inserted. Every one of those is a "works while failing" requirement, and they are the hardest kind to verify because the failure conditions are the ones a bench does not naturally produce.

Reset defaulting to R_BYPASS is the line to argue about. A station that reset into the ring would insert itself with no knowledge of the ring's state — possibly during a recovery that its insertion then disturbs. For any shared invariant, the safe default is non-participation, and that principle generalises far past rings.

Ethernet's equivalent is nothing at all. A station that resets, hangs or loses power simply stops transmitting. No other station is affected, so there is no watchdog, no relay, and no "works while failing" requirement. That absence is the third argument's hardware form.

Deliberately simplified: one relay rather than the dual-path arrangement a real ring uses; mac_heartbeat abstracts whatever liveness evidence exists; no insertion protocol, which a real ring needs so other stations expect the disturbance; no distinction between a graceful removal and a fault.

Production implication: the relay must be fail-safe in the physical sense — de-energised means bypassed, so a station losing power closes the ring without needing any logic to run. Any design in which the powered-down state is "inserted" has inverted the requirement, and no amount of correct logic compensates for it.

9. What Dominance Locked In

Winning has consequences, and they are not all benefits. Four things became permanent because Ethernet won, and an engineer building silicon today works inside all of them.

The frame format is frozen. Addressing, the length/type field, the minimum and maximum sizes and the check value cannot change, because every receiver in existence validates against them. Chapter 1.5 showed the minimum frame size surviving the disappearance of its entire justification — that is what "frozen" means in practice. Chapter 5.6 carries both the derivation and the rule for exactly this reason.

Best-effort is the contract, permanently. Nothing above the MAC may assume delivery. Every application, every protocol stack and every hardware offload is built on that assumption, and it cannot be strengthened without breaking the compatibility that produced the dominance.

Determinism must be added on top, never built in. Module 17's time-sensitive networking is a suite of additions — time-aware shaping, frame preemption, synchronised clocks — layered onto a best-effort network. Each is more complex than it would have been in a network designed for determinism from the start. That complexity is the interest payment on the original decision, and it is being paid now by the automotive and industrial engineers who need guarantees.

The MAC/PHY boundary is where the industry's cost lives. Because the interface held, PHY work is where every generation's engineering goes: signal integrity, coding, equalisation, forward error correction. Modules 3 and 4 are large for this reason. A stable interface does not remove work; it concentrates it on one side.

10. What Ethernet Did Not Win

A chapter arguing that one technology won owes an honest account of where it did not, and the exceptions are informative rather than merely fair.

Hard real-time control kept its fieldbuses for decades. CAN, and industrial buses generally, persisted in vehicles and factories long after Ethernet had won everywhere else — because a bounded worst-case delay is not negotiable when the consequence of missing it is physical. Ethernet arrived in those domains only once Module 17's deterministic mechanisms existed, and Chapter 22.1 shows automotive requiring a purpose-built physical layer on top of that.

High-performance computing kept InfiniBand. For tightly coupled clusters where latency dominates and the fabric is engineered as one system, lossless operation and very low latency mattered more than ubiquity. Chapter 24.2 covers the comparison, and the interesting part is that Ethernet has been closing the gap by adopting the same properties — lossless configuration via Module 14's priority flow control — rather than by being better as it was.

Storage kept Fibre Channel far longer than expected, for the same reason: guarantees that a best-effort network did not offer.

And on-chip, Ethernet never competed at all. Module 24's comparison with PCIe and with on-chip fabrics is not close, because a load/store fabric inside a package is solving a different problem with different physics.

11. Waveform — Local Failure Against Global Failure

The same event — one station failing while holding the medium — in both designs.

One station's failure, two network designs

10 cycles
Ten clock cycles. Station A is active until it fails at cycle 3. In the Ethernet network, station B transmits normally from cycle 4 with no interruption. In the token network, station B is stalled from cycle 3 until the token timeout expires at cycle 7 and recovery completes at cycle 9.A fails, holding the tokenA fails, holding the tokentimeout: token presumed losttimeout: token presumedlostrecovery done, six cycles laterecovery done, six cycleslateclka_aliveeth_b_txeth_stalltok_held_atok_b_txtok_timer0001234TT0tok_claimtok_stallt0t1t2t3t4t5t6t7t8t9
Figure 3 — station A fails; only the token network takes everyone else down with it.

eth_stall is low for the entire trace. Station A's failure is invisible to station B, which transmits from cycle 4 as though nothing happened — because nothing that B depends on has changed. B never depended on A for anything.

tok_stall is high from cycle 3 to cycle 9. Six cycles in which station B, which is working perfectly, may not transmit — because the shared invariant is broken and B cannot proceed without it. The stall is not proportional to how much traffic B had; it is fixed by the timeout, which had to be conservative enough not to trigger on a slow-but-healthy station.

And notice tok_claim at cycle 8. In this trace one station claims. With several stations timing out together — the normal case, since they all observed the same absence — several claim at once, and the resolution protocol runs during a fault. That is the state Ethernet never has to enter, and Section 3's T_CLAIM is where it lives.

12. Assertions

Invariants of these models. Only the interframe gap and minimum frame size are normative.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SVA over the modules in this chapter.
 
// SAFETY — P1: the Ethernet access machine's worst output is one lost frame.
// Stated as an absence: it has no output that reports a network-wide
// condition, because it maintains no network-wide state.
property p_eth_failure_is_local;
  @(posedge clk) disable iff (!rst_n)
  frame_lost |-> (st_q == E_BACKOFF);
endproperty
a_eth_local : assert property (p_eth_failure_is_local);
 
// SAFETY — P2: the token machine can stall the network, and the model must
// not hide it. A cover rather than an assert: if this never fires, the bench
// never exercised the failure the whole comparison is about.
property p_token_can_stall;
  @(posedge clk) disable iff (!rst_n) network_stalled;
endproperty
c_token_stall : cover property (p_token_can_stall);
 
// SAFETY — P3: at most one station may transmit in the token model. The
// invariant the design exists to maintain; a failure means the claim race
// produced two tokens, which is the failure mode with no recovery because
// the network has no collision detection.
property p_token_mutual_exclusion;
  @(posedge clk) disable iff (!rst_n)
  $countones({sta_may_transmit, stb_may_transmit, stc_may_transmit}) <= 1;
endproperty
a_token_exclusive : assert property (p_token_mutual_exclusion);
 
// CAUSATION — P4: a claim only follows a timeout. Catches a station that
// regenerates a token opportunistically, which duplicates it.
property p_claim_needs_timeout;
  @(posedge clk) disable iff (!rst_n)
  $rose(token_claim) |-> $past(st_q == T_TIMEOUT);
endproperty
a_claim_needs_timeout : assert property (p_claim_needs_timeout);
 
// SAFETY — P5: the holding timer bounds one station's occupancy. Without it
// a faulty station holds the medium indefinitely and the bounded access
// delay — the design's headline guarantee — does not hold.
property p_hold_bounded;
  @(posedge clk) disable iff (!rst_n)
  (st_q == T_TX) |-> (hold_q <= HOLD_LIMIT);
endproperty
a_hold_bounded : assert property (p_hold_bounded);
 
// SAFETY — P6: the media-independent MAC pads below the minimum frame size.
// Normative behaviour, and the property that must hold identically at every
// rate — which is the interface-stability claim in checkable form.
property p_pad_to_minimum;
  @(posedge clk) disable iff (!rst_n)
  $fell(xmit_en) |-> ($past(beats_q) >= MIN_BEATS - 1);
endproperty
a_pad_to_minimum : assert property (p_pad_to_minimum);
 
// SAFETY — P7: the interframe gap is the full normative length, at every
// rate. Catches a gap derived from clock cycles instead of bit times, which
// passes at the rate it was written for and fails at every other.
property p_gap_full_length;
  @(posedge clk) disable iff (!rst_n)
  $fell(ifg_active) |-> ($past(gap_q) >= IFG_BITS - 1);
endproperty
a_gap_full : assert property (p_gap_full_length);
 
// SAFETY — P8: the MAC's behaviour does not depend on the tick RATE, only on
// tick COUNTS. The property that makes one source serve three physical
// layers; a failure means something rate-dependent leaked in.
property p_rate_independent;
  @(posedge clk) disable iff (!rst_n)
  (u_10m.st_q == u_1g.st_q) |-> (u_10m.beats_q == u_1g.beats_q);
endproperty
a_rate_independent : assert property (p_rate_independent);
 
// LIVENESS — P9: an Ethernet frame request is eventually resolved, one way
// or the other. ASSUMPTION, stated: the medium eventually goes idle and the
// retry policy eventually responds.
assume property (@(posedge clk) s_eventually (!carrier_sense));
property p_eth_request_resolves;
  @(posedge clk) disable iff (!rst_n)
  (st_q == E_DEFER) |-> s_eventually (may_transmit || frame_lost);
endproperty
a_eth_resolves : assert property (p_eth_request_resolves);

The property that must not be written

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// FALSE for a correct design. Included as a warning, not as a check.
// property p_token_network_never_stalls;
//   @(posedge clk) disable iff (!rst_n)
//   !network_stalled;
// endproperty

It reads like the guarantee a token network offers, and it is the opposite of what the design actually promises.

A token network guarantees bounded access delay while the token exists. It does not guarantee that the token always exists — that is why T_TIMEOUT and T_CLAIM are in the design at all. Asserting that a stall never happens asserts that recovery is never needed, which contradicts the presence of the recovery mechanism.

The correct properties are P3 and P5: at most one station transmits, and no station holds beyond its limit. Those are true, they are what the guarantees actually rest on, and they catch the failures that matter — a duplicated token, and a station that stalls the network by never letting go.

The instructive part is what writing the wrong version reveals. An engineer who believes a token network cannot stall has not understood that its guarantees are conditional on an invariant being maintained, and that maintaining it is the entire cost. That belief is exactly the one this chapter argues lost the industry a generation of complexity — and P2 exists as a cover rather than an assert to make the stall a thing the bench must demonstrate rather than a thing it must forbid.

13. Verification

Monitors observe: both state registers; the Ethernet machine's frame_lost; the token machine's timers, token_claim, network_stalled and recovery count; and, for the media-independent MAC, the beat and gap counters against xmit_en, pad_active and ifg_active in every elaboration.

The scoreboard independently predicts the padded frame length and the gap length from the normative constants, not from the design's parameters. A checker parameterised from the same source as the design agrees with it about a wrong constant.

Scenarios

  1. Ethernet, clean transmission. No collision. Verify a single pass through the states and no frame_lost.
  2. Ethernet, station failure. Stop one station mid-transmission. Verify every other station is unaffected — the trace in Section 8. The chapter's central measurement.
  3. Token, clean rotation. Token circulates, each station transmits in turn. Verify mutual exclusion (P3) throughout.
  4. Token, holder fails. Kill the station holding the token. Verify every other station stalls, the timeout fires, and recovery completes — and measure how long they were stalled.
  5. Token, simultaneous claims. Two or more stations time out together. Verify exactly one ends up holding (P3) and that the race resolves at all. The hardest scenario and the most important.
  6. Token, mismatched timeouts. Give stations different TOKEN_TIMEOUT values, which is what different vendors produce. Verify the shortest-timeout station claims every time — the fairness guarantee failing without any station being defective.
  7. Token, holder exceeds its limit. Verify the holding timer forces a pass (P5) and that a faulty holder cannot stall indefinitely.
  8. Token, opportunistic claim. Attempt a claim without a preceding timeout. Verify P4 rejects it — this is the path that duplicates a token.
  9. MAC, frame exactly at the minimum. Verify no padding is added.
  10. MAC, frame one beat below the minimum. Verify exactly one pad beat (P6). The off-by-one that ships.
  11. MAC, frame far below the minimum. Verify the pad count is correct and the gap still follows.
  12. MAC, back-to-back frames. Verify a full gap between every pair (P7).
  13. MAC, all three elaborations, identical stimulus in bit-tick terms. Verify the state sequences and counter values are identical (P8). The interface-stability claim, tested.
  14. MAC, reset in each state. Verify no stale beat count, no stale gap, no partial frame.

Coverage

Cross the token machine's state against the two timers at their boundaries. Cover simultaneous claims at two and at three stations. Cover frame lengths at 1 beat, MIN_BEATS-1, MIN_BEATS and MIN_BEATS+1 in every elaboration. Cover the cross of elaboration against state, so scenario 13 is exercised for every state rather than in aggregate.

A directed stimulus for the claim race

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// NON-SYNTHESIZABLE — directed stimulus. Kills the token holder and forces
// two stations to time out in the same cycle, which randomisation reaches
// rarely and which is the only condition where the invariant can break.
task automatic simultaneous_claim_race();
  // Give both observers identical timeouts so they expire together. This is
  // the WORST case, and it is also what a single-vendor network produces.
  force sta_b.TOKEN_TIMEOUT = 16'd64;
  force sta_c.TOKEN_TIMEOUT = 16'd64;
 
  // Kill the holder while it holds.
  wait (sta_a.st_q == sta_a.T_TX);
  sta_a_alive <= 1'b0;
 
  // Both observers must time out in the same cycle.
  wait (sta_b.st_q == sta_b.T_TIMEOUT);
  assert (sta_c.st_q == sta_c.T_TIMEOUT)
    else $error("observers did not time out together; the race was not exercised");
 
  // THE ASSERTION THE TASK EXISTS FOR. Two tokens is the unrecoverable
  // failure: the network has no collision detection because it was designed
  // never to need any.
  repeat (32) @(posedge clk) begin
    assert ($countones({sta_a.may_transmit, sta_b.may_transmit, sta_c.may_transmit}) <= 1)
      else $error("two stations hold the token: the invariant is broken and nothing can detect it");
  end
 
  // And the cost, measured rather than asserted.
  $display("network stalled for %0d cycles while one station failed", stall_cycles);
endtask

The $display is deliberate and is not debug output. The stall duration is the chapter's quantitative claim, and it belongs in a report rather than in a pass or fail — because the number is what a designer compares against the Ethernet case, where the equivalent measurement is zero.

14. Debugging — When Two Correct Implementations Disagree

This chapter's failure class is unusual and worth a method, because nothing is broken and the normal debugging instincts do not apply.

SymptomWhat it usually isFirst check
One vendor's station consistently wins a shared resourceA tunable value differs within specificationCompare the timing constants at each end, not the code
A feature works with one vendor and not anotherAn optional behaviour one side assumes and the other omitsWhich parts of the specification are "may" rather than "shall"
A network works until a station is addedA per-station cost or invariant nobody accounted forWhat the new station requires the others to do
A fault appears only after a component failsRecovery logic exercised for the first timeWhether recovery was ever tested, rather than whether it exists
Intermittent unfairness with no errors anywhereA distributed agreement holding looselyMeasure the distribution, since no counter will move

The last row is the hardest and is this chapter's Section 13 scenario 6. Two conforming stations with slightly different timeouts produce a permanent bias in who recovers first, and there is no error to find because there is no error. The only evidence is statistical: measure per-station throughput over a long run and look for a bias that correlates with vendor rather than with load.

The general method has three steps, and it applies well beyond networking.

Compare constants before comparing behaviour. When two implementations disagree, the cause is far more often a differently-chosen value inside a permitted range than a logic error. Reading both specifications' tolerances is faster than reading either implementation.

Identify what the specification leaves open. Every "may", every range, and every unspecified ordering is a place two correct implementations can differ. The set of those is the candidate list, and it is usually short.

Ask what each side assumed the other would do. Distributed invariants fail at the seams, and the seam is always an assumption that was never written down — which is why Section 2's interoperability argument is about the number of things that must be agreed rather than about their difficulty.

And the Ethernet contrast is the point of the section. This entire failure class is small on Ethernet because the list of things two stations must agree on is short and consists of fixed constants rather than tunable policy. Fewer agreements means fewer seams, and fewer seams is a debugging property as much as an architectural one.

15. Common Misconceptions

"Ethernet won because it was technically better."

The wrong model: the superior design prevailed on merit.

What it costs: the actual lesson is missed. An engineer who believes better designs win will keep optimising guarantees and be repeatedly surprised when simpler systems displace them — and will underestimate the cost of the recovery mechanisms their guarantees require.

The corrected model: Ethernet offered weaker guarantees than token passing on every axis that was compared at the time: no bounded delay, no fairness proof, no collision-free operation, worse behaviour under heavy load. It won because failure was cheap, interoperability was easy, and the interface stayed still — and it has spent thirty years re-adding the guarantees it declined.

"Simplicity always wins."

The wrong model: the takeaway is that simpler designs beat complex ones.

What it costs: real requirements get dismissed. Determinism, bounded latency and guaranteed fairness are genuine needs in industrial, automotive and audio systems, and "simplicity wins" is used to argue against providing them — which is how a project ends up rebuilding those guarantees badly, on top of a network that does not offer them.

The corrected model: the deciding factor was where the cost of failure lands, not the amount of logic. Section 4's comparison shows nearly equal state counts. Ethernet's advantage is that its failures are local and its interoperability surface is tiny, not that it has fewer gates. Where guarantees are genuinely required, Module 17 shows the industry building them — at a cost that is higher than it would have been if they had been designed in.

"The frame format is stable because nobody has needed to change it."

The wrong model: stability is an accident of adequacy.

What it costs: the constraint is not respected in design. An engineer who thinks the format could change if there were a reason will propose changes — and be confused by the resistance, or worse, build something that assumes a modified frame will interoperate.

The corrected model: it is stable because it cannot change. Every receiver in existence validates against it, so a modification is not an upgrade but a new incompatible protocol. Chapter 1.5 showed the minimum frame size outliving its entire justification for exactly this reason. Extensions have to be backwards-compatible — VLAN tags inserted in a way old receivers tolerate, jumbo frames as a negotiated deviation — and that constraint shapes every addition since.

"Interface stability means the interface never changed."

The wrong model: one interface, unchanged since the beginning.

What it costs: Module 10's six xMII variants look like a failure of the principle rather than an expression of it, and the actual invariant is missed.

The corrected model: the interface has been revised repeatedly — MII, RMII, GMII, RGMII, SGMII, XGMII — each with different widths, pin counts and clocking. What stayed stable is the contract: the MAC deals in frames and bit times, the PHY deals in bits and physics, and neither knows the other's business. Section 6's MAC is unchanged across three physical layers not because the wires between them are the same, but because that division of responsibility never moved.

16. Interview Reasoning

Because the cost of being wrong was lower, not because the design was better on the axes being compared.

The chain a strong answer walks:

  • Token passing offered genuinely stronger guarantees: no collisions by construction, bounded access delay, provable fairness, and graceful behaviour under heavy load. Ethernet offered none of those.
  • Those guarantees rest on a distributed invariant — exactly one token exists — and maintaining it requires timeouts in every station, a regeneration rule, a race resolution when several stations regenerate at once, and ring-order maintenance as stations come and go.
  • When that machinery fails, it fails globally: a lost token stalls every station, a duplicated one produces collisions on a network with no collision detection. Ethernet's worst case is one dropped frame at one station.
  • The interoperability surface follows the same shape. Two Ethernet stations must agree on a frame format and some fixed constants. Two token stations must agree on timeout values, holding times and recovery priorities closely enough that a disagreement does not deadlock the network — and a few percent difference in a timeout silently destroys the fairness guarantee.
  • The second half is interface stability: the MAC is specified in bit times and knows nothing about the medium, so one MAC design outlived every physical layer from coax to 800 Gb/s optics, and each new PHY inherited the whole existing ecosystem for free.

What separates a good answer from a complete one: saying what the win cost. Best-effort is now permanent, the frame format is frozen, and determinism has to be added on top — which is what Module 17's time-sensitive networking is, decades later and more complex than it would have been if designed in.

The follow-up to be ready for: is the lesson that simplicity wins? No. The lesson is that the cost of a mechanism includes the cost of it failing, of two vendors implementing it differently, and of testing it under the conditions where it matters — and those costs are systematically underestimated when designs are compared on their guarantees.

17. Understanding Check

18. What's Next

Module 1 is complete. A shared medium made access a distributed timing problem; slot time solved it; packet switching explained why sharing was worth doing at all; switching dismantled the sharing; full duplex deleted the machinery it had required; and this chapter argued that the whole sequence was survivable because Ethernet's failures were cheap and its interface stood still.

What remains is what was never about contention. Framing, addressing, error detection, and the boundary between the MAC and the physical layer were untouched by everything in Module 1 — and they are what Ethernet actually is.

Chapter 2.1 — Ethernet System Architecture lays out the complete picture: the client, the MAC, the reconciliation sublayer, the PCS, the PMA, the PMD and the medium, and the contract that joins each pair. Chapter 2.2 then traces one frame down that stack and back up the other side, which is the mental model the rest of the track extends.

The full path is on the Ethernet curriculum index.

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.