Skip to content
VLSI Mentor

Ethernet · Module 9

100 Mbps — Fast Ethernet and the Switch Transition

4B/5B and MLT-3 got ten times the data through about three times the spectrum — but the switch was the larger change, because a collision domain of one made full duplex possible and left CSMA/CD unreached.

Chapter 9.1 built the original: Manchester coding, a shared coax, and a MAC whose every mechanism existed to arbitrate access to one conductor.

Fast Ethernet is remembered for being ten times faster. That was the smaller change.

The rate increase was real and it was engineered well — a new code got ten times the data through about three times the spectrum, which is the kind of result that looks impossible until you see the arithmetic. And it changed almost nothing about how Ethernet works.

The change that mattered happened at the same time and is usually described as a deployment detail: hubs were replaced by switches.

A hub is a repeater — Chapter 9.1's shared medium, in a box. A switch gives every station its own collision domain, and a collision domain with one station in it has no collisions. Which means the station can transmit and receive simultaneously, which means full duplex, which means CSMA/CD — carrier sense, collision detection, jam, backoff, slot time — is not used at all.

Everything Chapter 9.1 implemented became dead code on a switched port, and the frame format it produced did not change by a single bit.

1. Scope — What This Chapter Owns

Chapter 3.5 owns 4B/5B — the code, its DC balance, its control symbols. This chapter uses it and does not re-derive it; what it adds is the spectral consequence of pairing it with MLT-3.

Chapter 10.1 owns MII as an interface. This chapter mentions it only as the boundary that appeared.

Chapter 9.1 owns the shared-medium MAC, whose mechanisms this chapter shows becoming unused.

This chapter owns the transition: what the coding change bought, why the switch mattered more, how autonegotiation works and what it cannot guarantee, and the duplex mismatch that is its defining failure.

It does not own switching architecture — forwarding, learning and buffering are a switching subject. It owns the consequence of switching for the MAC, which is that half of the MAC stopped being used.

The question this chapter answers that its neighbours do not: what actually changed between 10 and 100 Mb/s, and why is the answer not "the speed"?

2. Ten Times the Data for Three Times the Spectrum

One hundred megabits per second of data is encoded by four bit to five bit block coding into one hundred and twenty five megabaud, a twenty five percent overhead compared with Manchester's one hundred percent. Those symbols are then transmitted using multi level transmit three, which cycles through three voltage levels so that a full electrical cycle takes four symbol periods. The fundamental frequency is therefore one hundred and twenty five divided by four, or thirty one point two five megahertz, against ten megahertz for ten megabit Manchester.100 Mb/s dataten times 10BASE-T4B/5B125 Mbaud — 25% overheadMLT-3three levels, 4 symbolsper cycle31.25 MHzthe fundamentalManchester at 10Mb/s10 MHz fundamental10× data, 3.1×spectrumthe whole result12
Figure 1 — two coding decisions in series: 4B/5B costs 25% instead of Manchester's 100%, and MLT-3 then divides the fundamental by four.

Two decisions in series, and each one does part of the work.

4B/5B replaces Manchester's factor of two with a factor of 1.25. Five symbols carry four bits, so 100 Mb/s of data becomes 125 Mbaud — and Chapter 3.5 established what the spare code space buys: enough transitions for clock recovery, plus control symbols that are not data.

MLT-3 then divides the frequency by four. Instead of two levels it uses three, and it advances through them in a cycle — so a run of ones walks +, 0, −, 0, +, … and a full electrical cycle takes four symbol periods rather than two.

Which gives the arithmetic:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
100 Mb/s data
  / (4/5)   -> 125 Mbaud
  / 4       -> 31.25 MHz fundamental

Against 10BASE-T's 10 MHz for 10 Mb/s. Ten times the data through 3.125 times the spectrum.

And that ratio is why 100BASE-TX ran on the cabling that was already installed. A tenfold spectrum increase would have needed better cable; a threefold one fitted inside what Category 5 already provided.

3. The Switch, and What It Made Unnecessary

A hub is a repeater. It takes a signal arriving on one port and reproduces it on every other, which makes every attached station part of one collision domain — Chapter 9.1's shared coax with a different physical arrangement and identical semantics.

A switch is not. It receives a frame, decides where it goes (Chapter 2.7's forwarding), and transmits it only there. Each port is its own collision domain, containing exactly one station.

And a collision domain with one station has no collisions. Not "few" — none, structurally, because a collision requires two transmitters and there is one.

From which everything follows:

MechanismOn a hub portOn a switch port
carrier senserequired before transmittingunnecessary
collision detectionrequired throughoutnothing to detect
jam and backoffrequired on collisionnever invoked
slot timeconstrains the segment's lengthconstrains nothing
the 64-octet floorneeded for detectabilitystill enforced (Chapter 5.6)
simultaneous transmit and receiveimpossiblepossible — full duplex

Read the last two rows together, because they are the chapter's argument in miniature. The mechanism that produced the frame floor became unnecessary; the floor stayed. Chapter 5.6 §3 gave the reasons — frames cross links that do not share the property, and every receiver already enforces it — and this is the moment the divergence began.

And full duplex is the change that was worth having. A station that can transmit and receive simultaneously has, in effect, twice the capacity and no contention — and it never defers, never collides, and never backs off.

So the tenfold rate increase multiplied a link's capacity by ten, and the switch multiplied it again while removing the mechanism that had bounded a network's physical size since 1980. Chapter 1.2's slot time stopped constraining anything, and a segment's length became a question about signals rather than about round trips.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SYNTHESIZABLE.
//
// Autonegotiation's arbitration: exchange capabilities in a fast link
// pulse burst and resolve them by priority.
//
// The FLP burst is Chapter 9.1's link pulse, multiplied:
//
//   33 pulse positions per burst
//   17 CLOCK positions, at 125 us spacing (+/- 14 us)
//   16 DATA positions, midway between clock pulses
//   a pulse present in a data position is a 1; absent is a 0
//   bursts repeat every 16 +/- 8 ms -- the same rate as a link pulse
//
// So a 10BASE-T partner sees pulses at the expected rate and brings its
// link up. It never learns what they encoded, and it does not need to.
package autoneg_pkg;
 
  localparam int unsigned FLP_POSITIONS   = 33;
  localparam int unsigned FLP_DATA_BITS   = 16;
  localparam int unsigned CLOCK_SPACING_US = 125;
  localparam int unsigned BURST_PERIOD_MS  = 16;
 
  // Technology bits within the 16-bit link code word, in priority order:
  // higher speed wins, and at equal speed FULL duplex beats half.
  typedef enum logic [2:0] {
    TECH_10T_HALF,
    TECH_10T_FULL,
    TECH_100TX_HALF,
    TECH_100TX_FULL,
    TECH_NONE
  } tech_e;
 
endpackage
 
module autoneg_arbitrator
  import autoneg_pkg::*;
#(
  parameter int unsigned CNT_W = 16
) (
  input  logic clk,
  input  logic rst_n,
 
  // This end's advertised abilities, one bit per technology.
  input  logic [3:0] local_abilities,
 
  // The partner's link code word, once a burst has been received.
  input  logic        partner_valid,
  input  logic [15:0] partner_code_word,
 
  // Parallel detection: the partner sent no FLP bursts at all, so its
  // abilities are unknown and only its signalling can be observed.
  input  logic        parallel_detect_valid,
  input  logic [1:0]  parallel_detect_tech,   // speed only
 
  output logic        resolved,
  output tech_e       resolution,
  // TRUE when the resolution came from parallel detection, which cannot
  // determine duplex. The single most important output of this module.
  output logic        duplex_assumed,
 
  output logic [CNT_W-1:0] c_negotiations,
  output logic [CNT_W-1:0] c_parallel_detects
);
 
  // The partner's technology bits occupy a fixed field of the code word.
  wire [3:0] partner_abilities = partner_code_word[8:5];
  wire [3:0] common = local_abilities & partner_abilities;
 
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      resolved <= 1'b0; resolution <= TECH_NONE; duplex_assumed <= 1'b0;
      c_negotiations <= '0; c_parallel_detects <= '0;
    end else begin
      resolved <= 1'b0;
 
      if (partner_valid) begin
        // PRIORITY RESOLUTION. Highest common ability wins, and at equal
        // speed full duplex outranks half -- because a full-duplex link
        // is strictly better and both ends resolve the same table.
        if      (common[TECH_100TX_FULL]) resolution <= TECH_100TX_FULL;
        else if (common[TECH_100TX_HALF]) resolution <= TECH_100TX_HALF;
        else if (common[TECH_10T_FULL])   resolution <= TECH_10T_FULL;
        else if (common[TECH_10T_HALF])   resolution <= TECH_10T_HALF;
        else                              resolution <= TECH_NONE;
 
        duplex_assumed <= 1'b0;
        resolved       <= 1'b1;
        if (!(&c_negotiations)) c_negotiations <= c_negotiations + 1'b1;
 
      end else if (parallel_detect_valid) begin
        // PARALLEL DETECTION. The partner does not negotiate, so its
        // duplex capability is UNKNOWABLE -- nothing in the signalling
        // carries it. The standard's answer is to assume HALF, which is
        // the safe choice against a partner that might collide.
        //
        // And that assumption is exactly how a duplex mismatch is born:
        // a partner FORCED to full duplex sends no bursts, is parallel
        // detected, and this end selects half.
        resolution     <= (parallel_detect_tech == 2'd1) ? TECH_100TX_HALF
                                                         : TECH_10T_HALF;
        duplex_assumed <= 1'b1;
        resolved       <= 1'b1;
        if (!(&c_parallel_detects)) c_parallel_detects <= c_parallel_detects + 1'b1;
      end
    end
  end
 
endmodule

Classification: synthesizable.

What it teaches: that duplex_assumed is the output that matters and the one designs omit. A resolution reached by negotiation is an agreement; a resolution reached by parallel detection is a guess about duplex with the speed known — and the two are indistinguishable from resolution alone. A port whose duplex was assumed is a port one configuration away from a mismatch, and nothing else says so.

Deliberately simplified: four technologies and no next pages. Real autonegotiation carries an extensible next-page mechanism, which is how gigabit's master/slave preference (Chapter 9.3) is exchanged.

Production implication: the priority table must be identical at both ends, and nothing checks that it is. Each end resolves independently and there is no acknowledgement of the outcome — the protocol exchanges capabilities and never confirms conclusions. Two implementations with different priority tables will negotiate successfully and disagree, which is the same class of failure as Chapter 6.2's conventions: a shared mechanism with an unshared table.

5. The FLP Burst, and Why It Is Backward Compatible

A fast link pulse burst consists of thirty three pulse positions. Seventeen of them are clock positions spaced one hundred and twenty five microseconds apart. Between each pair of clock pulses is a data position: a pulse present there is a one and a pulse absent is a zero, giving a sixteen bit link code word. Bursts repeat every sixteen milliseconds, the same rate as a ten base T link integrity pulse, so a partner that understands only single pulses sees pulses at the expected rate and brings its link up without decoding anything.33 positionsone burst17 clock pulses125 µs apart16 data positionspresent = 1, absent = 016-bit code wordthe advertised abilitiesEvery 16 ± 8 msa link pulse's own rateA 10BASE-T partnersees pulses; link comes up12
Figure 2 — a negotiation carried inside a signal an older device already understands and never has to decode.

The mechanism is a burst of pulses where 10BASE-T sent one, and the encoding is presence and absence.

Seventeen clock pulses, at 125 µs spacing with a ±14 µs tolerance, establish the timing. Sixteen data positions sit midway between consecutive clock pulses — at +62.5 µs — and a pulse present in a data position is a one while its absence is a zero.

Which gives a 16-bit link code word carrying a selector field, the technology abilities, a remote-fault indication, an acknowledge bit and a next-page bit.

And the whole thing repeats every 16 ± 8 ms — exactly the rate of a 10BASE-T link integrity pulse.

That last fact is the design. A 10BASE-T station attached to an autonegotiating partner sees pulses arriving at the rate it expects, concludes the link is up, and operates. It never decodes the burst, never knows a negotiation was attempted, and needs no changes whatsoever.

A new protocol, carried inside a signal the old device already understands, using only the fact that the old device counts pulses rather than interpreting them.

6. RTL 2 — Detecting a Duplex Mismatch

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SYNTHESIZABLE DIAGNOSTIC.
//
// Identifies a duplex mismatch from its signature, because nothing in
// the protocol reports one.
//
// The signature is ASYMMETRIC and that is what makes it identifiable:
//
//   THE HALF-DUPLEX END defers, senses carrier, and collides -- because
//     the full-duplex partner transmits whenever it likes, including
//     while this end is transmitting. It sees collisions, and crucially
//     LATE collisions (Chapter 9.1 §5), because the partner's frame can
//     arrive at any point.
//
//   THE FULL-DUPLEX END never collides, because it never looks. It sees
//     the half-duplex end's jam and truncated transmissions as FCS
//     errors and runts.
//
// So one end reports collisions and the other reports CRC errors, on the
// same link, at the same time. Neither symptom says "duplex" and both
// look like cabling.
module duplex_mismatch_detector
#(
  parameter int unsigned CNT_W = 16,
  parameter int unsigned WINDOW_BITS = 22
) (
  input  logic clk,
  input  logic rst_n,
  input  logic clear,
 
  // This end's configuration.
  input  logic is_full_duplex,
  input  logic duplex_assumed,       // from Section 4: parallel detected
 
  // Local error events.
  input  logic collision,
  input  logic late_collision,
  input  logic fcs_error,
  input  logic runt_received,
  input  logic frame_done,
 
  output logic             mismatch_suspected,
  output logic [1:0]       suspected_role,     // which end we are
  output logic [CNT_W-1:0] c_suspicions,
 
  output logic [CNT_W-1:0] win_collisions,
  output logic [CNT_W-1:0] win_fcs_errors,
  output logic [CNT_W-1:0] win_frames,
  output logic             evidence_valid,
  output logic             mismatch_ever_suspected
);
 
  localparam logic [1:0] ROLE_UNKNOWN   = 2'd0;
  localparam logic [1:0] ROLE_HALF_END  = 2'd1;
  localparam logic [1:0] ROLE_FULL_END  = 2'd2;
 
  logic [WINDOW_BITS-1:0] win_q;
  logic [CNT_W-1:0] col_q, late_q, fcs_q, runt_q, frm_q;
 
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      win_q <= '0; col_q <= '0; late_q <= '0; fcs_q <= '0;
      runt_q <= '0; frm_q <= '0;
      mismatch_suspected <= 1'b0; suspected_role <= ROLE_UNKNOWN;
      c_suspicions <= '0; win_collisions <= '0; win_fcs_errors <= '0;
      win_frames <= '0; evidence_valid <= 1'b0;
      mismatch_ever_suspected <= 1'b0;
    end else begin
      mismatch_suspected <= 1'b0;
      evidence_valid     <= 1'b0;
 
      if (clear) begin
        col_q <= '0; late_q <= '0; fcs_q <= '0; runt_q <= '0; frm_q <= '0;
        c_suspicions <= '0;
        // mismatch_ever_suspected deliberately survives.
      end else begin
        if (collision)      col_q  <= col_q  + 1'b1;
        if (late_collision) late_q <= late_q + 1'b1;
        if (fcs_error)      fcs_q  <= fcs_q  + 1'b1;
        if (runt_received)  runt_q <= runt_q + 1'b1;
        if (frame_done)     frm_q  <= frm_q  + 1'b1;
      end
 
      if (&win_q) begin
        win_collisions <= col_q;
        win_fcs_errors <= fcs_q;
        win_frames     <= frm_q;
        evidence_valid <= 1'b1;
 
        // THE HALF-DUPLEX END'S SIGNATURE. Late collisions are the key:
        // ordinary contention produces collisions inside the slot time,
        // and a full-duplex partner transmitting at will produces them
        // at any point -- including after it.
        if (!is_full_duplex && (late_q != '0) && (frm_q != '0)) begin
          mismatch_suspected      <= 1'b1;
          suspected_role          <= ROLE_HALF_END;
          mismatch_ever_suspected <= 1'b1;
          if (!(&c_suspicions)) c_suspicions <= c_suspicions + 1'b1;
        end
 
        // THE FULL-DUPLEX END'S SIGNATURE. This end never collides, so
        // any collision indication is impossible -- and the partner's
        // jam arrives as check-sequence errors and runts together.
        // The COMBINATION is what distinguishes it from a bad cable,
        // which produces check errors without runts in that proportion.
        else if (is_full_duplex && (fcs_q != '0) && (runt_q != '0) &&
                 (fcs_q > (frm_q >> 6))) begin
          mismatch_suspected      <= 1'b1;
          suspected_role          <= ROLE_FULL_END;
          mismatch_ever_suspected <= 1'b1;
          if (!(&c_suspicions)) c_suspicions <= c_suspicions + 1'b1;
        end
 
        col_q <= '0; late_q <= '0; fcs_q <= '0; runt_q <= '0; frm_q <= '0;
        win_q <= '0;
      end else begin
        win_q <= win_q + 1'b1;
      end
    end
  end
 
endmodule

Classification: synthesizable diagnostic.

What it teaches: that the diagnosis needs evidence from both ends and each end can only see half of it. The half-duplex end sees collisions and cannot tell whether they are ordinary contention or a mismatch; the full-duplex end sees check-sequence errors and cannot tell whether they are a bad cable. Neither symptom names the cause, and the cause is obvious the moment the two are put side by side — which is why the module exports its window counts rather than only its verdict.

Deliberately simplified: fixed thresholds. A real detector correlates with load, because a mismatch's error rate rises with traffic in a way a cable fault's does not.

Production implication: late collisions are the strongest single indicator, and they are the reason Chapter 9.1 §5 separated them from ordinary ones. A full-duplex partner transmits whenever it wishes, including in the middle of this end's frame — so collisions arrive after the slot time, which cannot happen from ordinary contention on a conforming segment. A design that counts all collisions together throws away the one number that distinguishes a duplex mismatch from a busy segment.

7. RTL 3 — A Port That Can Behave As Either

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SYNTHESIZABLE.
//
// Models a port's behaviour under the two topologies, so a design can
// demonstrate to itself what changes.
//
// The point of writing both is that the MAC's code is IDENTICAL and only
// its enables differ:
//
//   REPEATER (hub) port  -- carrier sense active, collision detect
//        active, half duplex, one collision domain shared with every
//        other port.
//   SWITCH port          -- carrier sense and collision detect INERT,
//        full duplex permitted, a collision domain of one.
//
// Nothing in the frame format, the CRC, the addressing or the padding
// changes between them. Half of Chapter 9.1's MAC simply stops being
// reached.
module hub_switch_port_model
  import autoneg_pkg::*;
(
  input  logic clk,
  input  logic rst_n,
 
  // 1 = this port is a switch port (own collision domain).
  input  logic is_switch_port,
  input  logic full_duplex_negotiated,
 
  input  logic tx_request,
  input  logic medium_busy,          // carrier from the medium
  input  logic medium_collision,
 
  output logic csma_enabled,
  output logic full_duplex_active,
  output logic tx_permitted,
  output logic collision_possible,
 
  // The count of mechanisms that are present in the RTL and never
  // exercised on this port. Reported so the difference is visible rather
  // than theoretical.
  output logic [3:0] dormant_mechanisms
);
 
  // Full duplex requires BOTH a switch port and a successful
  // negotiation. A switch port with a half-duplex partner is still half
  // duplex, and this is the conjunction designs get wrong by assuming a
  // switch port implies full duplex.
  assign full_duplex_active = is_switch_port && full_duplex_negotiated;
 
  // CSMA/CD applies exactly when the port is NOT full duplex.
  assign csma_enabled       = !full_duplex_active;
  assign collision_possible = csma_enabled;
 
  // A full-duplex port transmits whenever it wants. A half-duplex port
  // must defer -- which is Chapter 9.1's front end, still present and
  // now conditional.
  assign tx_permitted = tx_request && (full_duplex_active || !medium_busy);
 
  always_comb begin
    dormant_mechanisms = 4'd0;
    if (full_duplex_active) begin
      // Carrier sense, collision detect, jam/backoff, and the slot-time
      // constraint. All four are in the RTL and none is reachable.
      dormant_mechanisms = 4'd4;
    end
  end
 
  // A collision on a full-duplex port is not a rare event, it is an
  // impossible one -- so its occurrence means the two ends disagree
  // about duplex (Section 6), not that a collision happened.
  // synopsys translate_off
  always_ff @(posedge clk) begin
    if (rst_n && full_duplex_active && medium_collision)
      $error("collision indicated on a full-duplex port -- the partner is half duplex");
  end
  // synopsys translate_on
 
endmodule

Classification: synthesizable.

What it teaches: that full_duplex_active is a conjunction and treating a switch port as implying full duplex is wrong. A switch port whose partner negotiated half duplex — or was parallel detected — is half duplex, and CSMA/CD is live on it. The port type permits full duplex; the negotiation decides it.

Deliberately simplified: the two topologies are modelled by enables rather than by separate designs, which is exactly the historical situation — the same MAC silicon served both, with mechanisms that stopped being reached.

Production implication: dormant_mechanisms makes a fact visible that is otherwise invisible: on a full-duplex port, four mechanisms are present in the netlist and unreachable. They cost area and they are never exercised — so they are also never verified in deployment, and a port that later negotiates half duplex activates logic that has not run since bring-up. A design that reports its dormant mechanisms knows which of its own paths are cold.

8. RTL 4 — Switching Duplex Safely

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SYNTHESIZABLE.
//
// Changes a port between half and full duplex, and the interlock is the
// module.
//
// A duplex change alters whether the MAC defers, whether it detects
// collisions, and whether it may transmit while receiving. Changing it
// mid-frame produces a frame that was half-duplex when it started and
// full-duplex when it ended -- which is not a frame either mode would
// have produced.
//
// So the change is deferred to a quiescent point, and the module refuses
// rather than queues if quiescence never arrives.
module duplex_mode_switch
(
  input  logic clk,
  input  logic rst_n,
 
  input  logic       req_valid,
  input  logic       req_full_duplex,
 
  input  logic       tx_active,
  input  logic       rx_active,
  input  logic       collision_active,
 
  output logic       full_duplex,
  output logic       change_applied,
  output logic       change_pending,
  // The request could not be applied within the bound. Reported rather
  // than held indefinitely, because a pending change nobody knows about
  // is worse than a refused one.
  output logic       change_timed_out,
  output logic [15:0] c_changes,
  output logic [15:0] c_timeouts
);
 
  logic        pending_q;
  logic        target_q;
  logic [15:0] wait_q;
 
  localparam int unsigned QUIESCE_TIMEOUT = 16'd50_000;
 
  assign change_pending = pending_q;
 
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      full_duplex <= 1'b0; pending_q <= 1'b0; target_q <= 1'b0;
      wait_q <= '0; change_applied <= 1'b0; change_timed_out <= 1'b0;
      c_changes <= '0; c_timeouts <= '0;
    end else begin
      change_applied   <= 1'b0;
      change_timed_out <= 1'b0;
 
      if (req_valid && !pending_q) begin
        pending_q <= 1'b1;
        target_q  <= req_full_duplex;
        wait_q    <= '0;
      end else if (pending_q) begin
        // THE INTERLOCK. Quiescent means no frame in either direction and
        // no collision in progress. A duplex change mid-frame produces a
        // frame that is neither mode's.
        if (!tx_active && !rx_active && !collision_active) begin
          full_duplex    <= target_q;
          pending_q      <= 1'b0;
          change_applied <= 1'b1;
          if (!(&c_changes)) c_changes <= c_changes + 1'b1;
        end else if (wait_q == QUIESCE_TIMEOUT) begin
          // Refuse rather than hold. A pending change that never applies
          // leaves the port in a state nobody asked for and nothing
          // reports.
          pending_q        <= 1'b0;
          change_timed_out <= 1'b1;
          if (!(&c_timeouts)) c_timeouts <= c_timeouts + 1'b1;
        end else begin
          wait_q <= wait_q + 1'b1;
        end
      end
    end
  end
 
endmodule

Classification: synthesizable.

What it teaches: that a refused change is better than an indefinitely pending one. A port with a duplex change waiting forever is in the old mode while management believes it is in the new one — and nothing reports the discrepancy, because the request was accepted. change_timed_out converts a silent divergence into a visible failure.

Deliberately simplified: a single quiescence condition. A real port also has queued frames and a link state to consider, and the correct point is usually a link-down transition rather than a gap between frames.

Production implication: the interlock exists because a duplex change alters whether the MAC defers — and a frame that started under deferral and finished without it is not a frame either mode produces. On a link that is already mismatched, the natural remedy is to change duplex, and doing so while traffic flows produces one more malformed frame at exactly the moment somebody is watching the counters.

9. RTL 5 — Handling a Partner That Does Not Negotiate

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// SYNTHESIZABLE.
//
// Parallel detection: determine what a non-negotiating partner is, from
// its signalling alone.
//
// What is observable and what is not:
//
//   OBSERVABLE  -- the speed. A 10BASE-T partner sends link pulses; a
//        100BASE-TX partner sends idle symbols continuously. The two are
//        entirely different signals.
//   NOT OBSERVABLE -- the duplex. Nothing in either idle signalling says
//        how the partner intends to behave when it transmits.
//
// So this module reports the speed with confidence and the duplex as an
// ASSUMPTION, and the distinction is carried in a separate output rather
// than folded into the result.
module parallel_detection_handler
  import autoneg_pkg::*;
#(
  parameter int unsigned DETECT_MS     = 100,
  parameter int unsigned CYCLES_PER_MS = 25_000,
  parameter int unsigned CNT_W = 16
) (
  input  logic clk,
  input  logic rst_n,
 
  input  logic flp_burst_seen,       // partner negotiates
  input  logic link_pulse_seen,      // 10BASE-T signalling
  input  logic idle_symbols_seen,    // 100BASE-TX signalling
 
  output logic       detect_valid,
  output logic [1:0] detected_speed,   // 0 = 10, 1 = 100
  output logic       duplex_is_assumed,
  output logic       partner_negotiates,
 
  output logic [CNT_W-1:0] c_parallel_detections,
  // Sticky: a port that has EVER parallel detected is a port whose
  // duplex was never agreed, and that fact outlives the link.
  output logic             ever_parallel_detected
);
 
  logic [31:0] timer_q;
 
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      timer_q <= '0; detect_valid <= 1'b0; detected_speed <= 2'd0;
      duplex_is_assumed <= 1'b0; partner_negotiates <= 1'b0;
      c_parallel_detections <= '0; ever_parallel_detected <= 1'b0;
    end else begin
      detect_valid <= 1'b0;
 
      if (flp_burst_seen) begin
        // The partner negotiates. Parallel detection is not used, and
        // the duplex will be AGREED rather than assumed.
        partner_negotiates <= 1'b1;
        duplex_is_assumed  <= 1'b0;
        timer_q            <= '0;
      end else if (link_pulse_seen || idle_symbols_seen) begin
        if (timer_q >= 32'(DETECT_MS * CYCLES_PER_MS)) begin
          // Long enough with signalling and no bursts: the partner does
          // not negotiate.
          detect_valid       <= 1'b1;
          detected_speed     <= idle_symbols_seen ? 2'd1 : 2'd0;
          // THE ASSUMPTION. Half duplex, because duplex is unobservable
          // and half is the choice that is safe against a partner which
          // might collide.
          duplex_is_assumed  <= 1'b1;
          partner_negotiates <= 1'b0;
          ever_parallel_detected <= 1'b1;
          if (!(&c_parallel_detections))
            c_parallel_detections <= c_parallel_detections + 1'b1;
          timer_q <= '0;
        end else begin
          timer_q <= timer_q + 1'b1;
        end
      end else begin
        timer_q <= '0;
      end
    end
  end
 
endmodule

Classification: synthesizable.

What it teaches: that the detector's confidence differs between its two outputs and the interface says so. detected_speed is a measurement — the two signallings are entirely different and distinguishing them is easy. duplex_is_assumed is a default, chosen for safety, with no evidence behind it at all. Folding them into one result would present a guess and a measurement as the same kind of thing.

Deliberately simplified: a fixed detection window. Real parallel detection interacts with the autonegotiation state machine's own timers, and the interaction is where a partner that negotiates slowly gets misdetected as one that does not.

Production implication: ever_parallel_detected is sticky because a port whose duplex was never agreed is permanently a mismatch candidate, and that remains true after the link bounces and comes up looking normal. The most useful thing a design can report about a working link is that its duplex was assumed rather than negotiated — because the link works, the counters are clean, and the mismatch appears only under load.

10. The Mismatch, End to End

A duplex mismatch produces asymmetric symptoms. The half duplex end defers, senses carrier and collides, reporting collisions and in particular late collisions because the full duplex partner transmits at any moment. The full duplex end never collides because it never looks, and instead sees the half duplex end's jam signals and truncated frames as check sequence errors and runts. Each end's symptoms resemble a cabling fault, and only putting the two side by side identifies the cause.Half-duplex enddefers, senses, collidesCollisions, LATEonespartner transmits at willFull-duplex endnever defers, never looksFCS errors and runtsthe partner's jamEach looks likecablingneither names the causeTogether:unmistakablecollisions at one end only12
Figure 3 — one fault, two completely different error signatures, and neither end can name the cause alone.

Follow one frame through a mismatched link and the asymmetry appears immediately.

The half-duplex end begins transmitting. Partway through, the full-duplex partner starts a frame of its own — it has no reason not to; it never senses carrier. The half-duplex end detects the incoming energy as a collision, jams, and backs off.

And the collision arrives at an arbitrary point, which means it frequently arrives after the slot time — a late collision, which Chapter 9.1 §5 established cannot happen from ordinary contention on a conforming segment.

The full-duplex end sees none of this. It never collides, because it never looks. What it sees is the half-duplex end's frame stopping partway through and being replaced by a jam — which arrives as a truncated frame with a bad check sequence, or as a runt.

EndReportsResembles
half duplexcollisions, late collisions, deferralsa busy or over-length segment
full duplexFCS errors, runts, no collisions at alla bad cable

Neither symptom says "duplex", and each has a plausible wrong explanation.

The tells are two, and both need the pair. First, collisions at one end and none at the other — on a genuinely shared segment both ends collide. Second, late collisions, which point at a physical impossibility that a mismatch explains and contention does not.

And the failure is load-dependent, which is why it survives commissioning. At low traffic the two ends rarely transmit simultaneously, so the link tests clean, passes acceptance, and degrades under production load — appearing weeks later as an intermittent performance problem with error counters that point at the cable.

11. Properties Worth Asserting, and One Worth Refusing

The properties below split into three groups, and the split is the lesson. Some are structural — they follow from the resolution table or the enable logic and hold unconditionally. Some are interlocks — they say a change happened only where it was safe. And a few are honesty properties, which assert that the design reports what it does not know.

Autonegotiation resolution

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// P1. Resolution is a pulse. A resolution that stays asserted turns one
// negotiation into a stream of them downstream.
property p_resolved_is_pulse;
  @(posedge clk) disable iff (!rst_n)
  resolved |=> !resolved;
endproperty
a_resolved_is_pulse: assert property (p_resolved_is_pulse);
 
// P2. Resolution requires evidence. Neither source of evidence, no
// resolution -- the arbiter never invents a technology.
property p_resolution_needs_evidence;
  @(posedge clk) disable iff (!rst_n)
  resolved |-> $past(partner_valid) || $past(parallel_detect_valid);
endproperty
a_resolution_needs_evidence: assert property (p_resolution_needs_evidence);
 
// P3. Priority: if both ends can do 100 full, that is what is selected.
// This is the whole resolution table, in the one case that matters.
property p_priority_100_full;
  @(posedge clk) disable iff (!rst_n)
  (partner_valid && local_abilities[TECH_100TX_FULL] &&
   partner_code_word[8:5][TECH_100TX_FULL])
    |=> (resolution == TECH_100TX_FULL);
endproperty
a_priority_100_full: assert property (p_priority_100_full);
 
// P4. THE HONESTY PROPERTY. Parallel detection can never yield a
// resolution that claims full duplex, because duplex is not observable.
// A design that parallel detects into a full-duplex result has inferred
// something from nothing.
property p_parallel_detect_never_full;
  @(posedge clk) disable iff (!rst_n)
  (resolved && duplex_assumed)
    |-> (resolution == TECH_100TX_HALF) || (resolution == TECH_10T_HALF);
endproperty
a_parallel_detect_never_full: assert property (p_parallel_detect_never_full);
 
// P5. And the converse: a negotiated resolution is never marked assumed.
property p_negotiated_not_assumed;
  @(posedge clk) disable iff (!rst_n)
  (resolved && $past(partner_valid)) |-> !duplex_assumed;
endproperty
a_negotiated_not_assumed: assert property (p_negotiated_not_assumed);

P4 is the property this chapter exists to state. It does not say the resolution is correct — it says the design does not claim to know something it cannot observe. A parallel-detected link that comes up full duplex has not made a lucky guess; it has made an unfounded one.

The port model

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// P6. Full duplex requires BOTH conditions. The conjunction, asserted,
// because assuming a switch port implies full duplex is the common bug.
property p_full_duplex_conjunction;
  @(posedge clk) disable iff (!rst_n)
  full_duplex_active == (is_switch_port && full_duplex_negotiated);
endproperty
a_full_duplex_conjunction: assert property (p_full_duplex_conjunction);
 
// P7. CSMA/CD is exactly the complement. There is no third mode: a port
// either arbitrates for a shared medium or it does not.
property p_csma_is_complement;
  @(posedge clk) disable iff (!rst_n)
  csma_enabled == !full_duplex_active;
endproperty
a_csma_is_complement: assert property (p_csma_is_complement);
 
// P8. A full-duplex port transmits on request, unconditionally. No
// deferral, ever -- which is the mechanism's entire absence, in one line.
property p_full_duplex_never_defers;
  @(posedge clk) disable iff (!rst_n)
  (full_duplex_active && tx_request) |-> tx_permitted;
endproperty
a_full_duplex_never_defers: assert property (p_full_duplex_never_defers);
 
// P9. A half-duplex port defers to carrier. Chapter 9.1's rule, still
// enforced, on the ports that still reach it.
property p_half_duplex_defers;
  @(posedge clk) disable iff (!rst_n)
  (!full_duplex_active && medium_busy) |-> !tx_permitted;
endproperty
a_half_duplex_defers: assert property (p_half_duplex_defers);

The duplex switch interlock

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// P10. THE INTERLOCK. A duplex change only ever lands in a quiescent
// cycle. A mid-frame change produces a frame that is neither mode's.
property p_change_only_when_quiet;
  @(posedge clk) disable iff (!rst_n)
  change_applied |-> (!tx_active && !rx_active && !collision_active);
endproperty
a_change_only_when_quiet: assert property (p_change_only_when_quiet);
 
// P11. Duplex is stable except at an applied change. Nothing else may
// move it -- a duplex that changes without a change event is a decode
// bug that will be diagnosed as a link problem.
property p_duplex_stable_between_changes;
  @(posedge clk) disable iff (!rst_n)
  !change_applied |=> $stable(full_duplex);
endproperty
a_duplex_stable: assert property (p_duplex_stable_between_changes);
 
// P12. Every request terminates: applied or timed out, never neither.
// This is the property that makes "pending" a bounded state.
property p_request_terminates;
  @(posedge clk) disable iff (!rst_n)
  (req_valid && !change_pending)
    |=> ##[1:$] (change_applied || change_timed_out);
endproperty
a_request_terminates: assert property (p_request_terminates);
 
// P13. Applied and timed out are mutually exclusive -- one outcome per
// request, so the counters partition rather than overlap.
property p_outcomes_exclusive;
  @(posedge clk) disable iff (!rst_n)
  !(change_applied && change_timed_out);
endproperty
a_outcomes_exclusive: assert property (p_outcomes_exclusive);

Parallel detection and mismatch evidence

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// P14. An FLP burst suppresses parallel detection entirely. A partner
// that negotiates is never guessed about.
property p_flp_suppresses_detection;
  @(posedge clk) disable iff (!rst_n)
  flp_burst_seen |=> !detect_valid;
endproperty
a_flp_suppresses_detection: assert property (p_flp_suppresses_detection);
 
// P15. Detection always assumes duplex. There is no path by which this
// module reports a detected duplex, because there is no such signal.
property p_detection_always_assumes;
  @(posedge clk) disable iff (!rst_n)
  detect_valid |-> duplex_is_assumed;
endproperty
a_detection_always_assumes: assert property (p_detection_always_assumes);
 
// P16. The sticky flag survives. A port that ever parallel detected
// stays flagged across link bounces -- the fact outlives the link.
property p_sticky_survives;
  @(posedge clk) disable iff (!rst_n)
  ever_parallel_detected |=> ever_parallel_detected;
endproperty
a_sticky_survives: assert property (p_sticky_survives);
 
// P17. A suspicion is always backed by a full window of evidence. A
// mismatch called on three frames is noise given a name.
property p_suspicion_has_evidence;
  @(posedge clk) disable iff (!rst_n)
  mismatch_suspected |-> evidence_valid;
endproperty
a_suspicion_has_evidence: assert property (p_suspicion_has_evidence);

12. Verification Scenarios

Group the scenarios by what they are trying to break, because a duplex bug hides in the cases nobody generates.

Negotiation and resolution

  1. Both ends 100 full capable — resolution is TECH_100TX_FULL, duplex_assumed low, c_negotiations increments once.
  2. Both ends 10 half only — resolution is TECH_10T_HALF, reached by negotiation, duplex_assumed low. Confirms that half duplex negotiated is not the same as half duplex assumed.
  3. No common ability — resolution is TECH_NONE, resolved still pulses. The arbiter reports a failed negotiation rather than staying silent.
  4. Local advertises 100 full, partner advertises 100 half — resolution is TECH_100TX_HALF. The speed matches, the duplex is the lower of the two, and CSMA/CD is live on a 100 Mbps link.
  5. Partner code word changes between bursts — the resolution follows the most recent burst. A partner that is reconfiguring produces a sequence of resolutions, and each is a legitimate one.
  6. partner_valid and parallel_detect_valid asserted in the same cycle — negotiation wins, duplex_assumed stays low. Evidence beats assumption whenever both exist.
  7. resolved pulse width — exactly one cycle under back-to-back partner_valid. P1 under load.

Parallel detection

  1. Partner sends link pulses only, for the full detection windowdetect_valid, speed 10, duplex_is_assumed high.
  2. Partner sends 100BASE-TX idle symbols onlydetect_valid, speed 100, duplex_is_assumed high. The speed is a measurement; the duplex is not.
  3. An FLP burst arrives at cycle DETECT_MS × CYCLES_PER_MS − 1 — detection is suppressed. The boundary case where a slow negotiator is one cycle from being misjudged.
  4. Signalling drops mid-window and returns — the timer restarts. Partial evidence does not accumulate across a gap.
  5. Link bounces after a parallel detectionever_parallel_detected stays high. The port remains flagged although the link now looks new.
  6. Alternating link pulses and idle symbols — the module must not oscillate between speeds within one window.

Port model and duplex switching

  1. Switch port, half-duplex negotiatedfull_duplex_active low, csma_enabled high, dormant_mechanisms zero. The case that disproves "switch port means full duplex."
  2. Repeater port, full-duplex negotiatedfull_duplex_active low. The port type vetoes the negotiation.
  3. Full-duplex port, tx_request while medium_busytx_permitted high. No deferral.
  4. Half-duplex port, tx_request while medium_busytx_permitted low. Deferral, exactly as Chapter 9.1.
  5. Duplex change requested mid-framechange_pending holds, change_applied stays low until tx_active and rx_active both fall.
  6. Duplex change requested during a collision — held. A collision is a busy medium even though no frame is completing.
  7. Traffic that never quiesces for QUIESCE_TIMEOUT cycleschange_timed_out pulses once, change_pending clears, c_timeouts increments. The refusal path.
  8. Second request while one is pending — ignored, not queued. One outstanding change at a time.
  9. Request for the duplex already in force — applies at the next quiescent point and counts. A no-op change is still a change event, and suppressing it would make the counter lie.

Mismatch evidence

  1. Half-duplex end under mismatch — collisions and late collisions accumulate, fcs_error does not, suspected_role reports the half-duplex side.
  2. Full-duplex end under mismatchfcs_error and runt_received accumulate, collisions stay at zero, suspected_role reports the full-duplex side.
  3. Evidence window closes with three frames in itevidence_valid low and mismatch_suspected stays low. A rate computed over three frames is not a rate.
  4. clear asserted while a suspicion stands — the window counters clear, mismatch_ever_suspected survives. The sticky flag is what a later reader needs.
  5. A genuinely shared half-duplex segment under heavy load — collisions at both ends, no late collisions, no suspicion raised. The false-positive case that separates contention from mismatch.

13. The Cable Was the Constraint

Section 2 established that 100BASE-TX needs a 31.25 MHz fundamental. That number is why Fast Ethernet could not simply be deployed on the cable already in the walls.

Category 3 cable is characterised to 16 MHz. Category 5 is characterised to 100 MHz.

Cat 3Cat 5
characterised bandwidth16 MHz100 MHz
10BASE-T (10 MHz fundamental)worksworks
100BASE-TX (31.25 MHz fundamental)outside the ratingworks

So MLT-3 and 4B/5B together — the compression that took ten times the data into 3.125 times the spectrum — still landed roughly twice above what Cat 3 is specified to carry. The line code was not a way to avoid recabling; it was what made 100 Mbps reachable on a cable category that could be manufactured at all.

And the committee did try to avoid the recabling, which is the part worth knowing. 100BASE-T4 ran Fast Ethernet over four pairs of Cat 3, using 8B6T ternary coding: eight bits map to six ternary symbols, three pairs carry data in the transmit direction at

100 Mb/s ÷ 3 pairs = 33.33 Mb/s per pair, and 33.33 × 6/8 = 25 Mbaud per pair

25 Mbaud, comfortably inside Cat 3's rating.

And it is not the variant anyone deployed, for a structural reason. T4 uses three pairs in whichever direction is transmitting, which means the direction has to be switched — so T4 is half duplex only. It solved the cabling problem and forfeited the change that mattered.

14. Debugging: Reading the Two Signatures

A duplex mismatch is diagnosed by comparing two ends, and almost every wrong diagnosis comes from looking at one.

ObservationLikely causeThe distinguishing check
collisions at one end, none at the otherduplex mismatchthe definitive tell; a shared segment collides at both ends
collisions at both ends, no late collisionsordinary contention on a half-duplex segmentload correlates; performance degrades gracefully
late collisions on a conforming segmentduplex mismatch, or a segment over the round-trip budgetcheck the partner's collision count — zero means mismatch
FCS errors and runts, zero collisions, full duplexthe partner is half duplex and jammingcheck the partner for collisions
FCS errors at both ends, no collisionsgenuine cabling or connector faultsymmetric, and unrelated to load
clean at low load, degrades under loadmismatch, near-certainlythe symptom is simultaneity, which only load produces
link up, speed correct, throughput a fraction of itmismatchlook for ever_parallel_detected before looking at the cable

Three habits make this tractable.

First, always read both ends. A duplex mismatch is the canonical fault where each end's evidence is individually misleading and the pair is unambiguous.

Second, treat a late collision as a claim about physics. Chapter 9.1 §5 established that a late collision cannot arise from contention on a conforming segment. When one appears, either the segment violates its round-trip budget or the partner is not doing CSMA/CD at all — and the second is far more common on a switched link.

Third, look for the assumption before looking for the fault. ever_parallel_detected and duplex_assumed are one register read, and they identify a mismatch candidate before any traffic has run. A link whose duplex was never negotiated is a link nobody agreed about.

15. Common Misconceptions

"Fast Ethernet was a tenfold speed increase."

The wrong model: the same Ethernet, ten times faster.

What it costs: you cannot explain why full duplex arrived at the same moment, why CSMA/CD stopped mattering, or why a network's maximum physical size stopped being a function of its bit rate.

The corrected model: two independent changes shipped together and the smaller one got the name. The rate went up ten times. Simultaneously, hubs were replaced by switches — and a switch port is a collision domain of one, which makes full duplex possible and leaves Chapter 1.2's entire arbitration mechanism present in the silicon and never reached.

"A switch port is full duplex."

The wrong model: switch port implies full duplex.

What it costs: Section 7's full_duplex_active is a conjunction, and treating it as one term is exactly the bug. A switch port whose partner negotiated half — or was parallel detected — is half duplex, with CSMA/CD live on it.

The corrected model: the port type permits full duplex; the negotiation decides it. And the most common way a switch port ends up half duplex is a partner that does not negotiate at all, which the port then assumes about.

"Autonegotiation determines the duplex."

The wrong model: both ends negotiate, so both ends know the duplex.

What it costs: the entire duplex-mismatch failure becomes inexplicable — if the protocol determines duplex, mismatches should not exist.

The corrected model: autonegotiation determines duplex only when both ends negotiate. When one end is forced, it sends no bursts, the other end parallel detects, and parallel detection cannot observe duplex — nothing in either signalling carries it. So it assumes half, and a link comes up at the right speed with opposite duplex at each end.

"A duplex mismatch shows up as a broken link."

The wrong model: a serious configuration error produces a serious, obvious symptom.

What it costs: the fault passes commissioning cleanly and appears weeks later as an intermittent performance problem whose error counters point at the cable.

The corrected model: both ends report link up, at the correct speed, with clean counters at low load. The symptom requires simultaneous transmission, which requires load — and the symptoms that then appear are asymmetric, so each end alone tells a plausible and wrong physical-layer story.

"MLT-3 is how Fast Ethernet gets its speed."

The wrong model: one clever line code did all the work.

What it costs: you conflate two separate decisions and cannot reason about later generations, where the same two decisions are made independently again.

The corrected model: 4B/5B and MLT-3 solve different problems. 4B/5B is a block code guaranteeing transition density and control symbols, at 25% overhead — hence 125 Mbaud. MLT-3 is a modulation that cycles through three levels so a full electrical cycle spans four symbol periods, putting the fundamental at 31.25 MHz. Coding and modulation are independent choices, and Section 13 shows what happens when you vary them: 100BASE-T4 chose differently and got Cat 3 compatibility at the price of full duplex.

16. Interview Reasoning

"What was the most important change in Fast Ethernet?"

The weak answer is the tenfold rate. The answer that ends the topic is that the rate was the smaller change and the switch was the larger one: a switch port is a collision domain of one, which makes full duplex possible — and a full-duplex station never defers, never collides, and never backs off, so Chapter 1.2's arbitration is present in the design and unreachable. The rate multiplied a link's capacity by ten; the switch multiplied it again and removed the constraint that had bounded a network's physical extent since 1980. The extra credit is what did not change: the frame format, the 64-octet floor, and the interframe gap, none of which had a reason left.

"How does 100BASE-TX get 100 Mbps through about 31 MHz?"

Two independent steps, and the strong answer separates them. 4B/5B maps four data bits to five line bits, so 100 Mb/s becomes 125 Mbaud — 25% overhead, against Manchester's 100%, in exchange for a receiver that must hold timing across several bit times. MLT-3 then cycles through three levels, so a complete electrical cycle takes four symbol periods: 125 ÷ 4 = 31.25 MHz fundamental. Ten times the data for 3.125 times the spectrum — and the finishing observation is that the two decisions are separable, which is why 100BASE-T4 could pick a different pair and land inside Cat 3's rating.

"What is a duplex mismatch and how would you diagnose it?"

One end full duplex, one end half, both reporting link up at the same speed. The strong answer gives the mechanism: it arises when one end is forced — a forced port sends no FLP bursts — so the other end parallel detects, which resolves speed by observation and duplex by assumption, and the assumption is half. The diagnosis is the asymmetry: the half-duplex end reports collisions, including late collisions; the full-duplex end reports FCS errors and runts and zero collisions. Collisions at one end and none at the other is the tell, and it needs both ends — each alone looks like a cabling fault. The finishing point: it is load-dependent, so it passes acceptance and fails in production.

"Would you assert that both ends of a link agree on duplex?"

No, and the reason is stronger than "it is hard to observe." No mechanism in the protocol establishes it. Autonegotiation exchanges capabilities, each end resolves its own priority table independently, and there is no acknowledgement of the conclusion — and when one end does not negotiate, the other assumes. So the property has no cause, not merely no witness: it is false on a correctly built link with a forced partner. Assert instead that the design reports duplex as assumed whenever it is assumed — a property of this device, unconditionally true, and the one that catches every mismatch in the chapter.

17. Understanding Check

Because the rate made a link faster and the switch changed what a link is.

A hub is a repeater. Every port's traffic reaches every other port, so all ports share one collision domain — and every station must arbitrate for it, exactly as Chapter 1.2 describes. Ten times the rate makes that arbitration faster; it does not remove it.

A switch forwards. Each port is its own collision domain, containing exactly two devices — and with only one possible transmitter at each end of a dedicated pair, there is nothing to collide with. Which makes full duplex possible: both ends transmit whenever they like.

And a full-duplex station never defers, never senses carrier, never collides and never backs off. CSMA/CD is still in the silicon and is never reached — which is why Section 7 reports dormant_mechanisms, and why Chapter 5.6's frame floor outlived its own justification.

The arithmetic: the rate multiplied a link's capacity by ten. The switch multiplied it again — and removed the slot time's constraint on a network's physical size, which had bounded Ethernet since 1980.

18. What's Next

The claim this chapter defended: the tenfold rate increase was the smaller of Fast Ethernet's two changes.

The rate was engineered well — 4B/5B took 100 Mb/s to 125 Mbaud at 25% overhead, and MLT-3's four-symbol electrical cycle put the fundamental at 31.25 MHz, so ten times the data crossed about three times the spectrum. And it changed nothing about how Ethernet works.

The switch did. A switch port is a collision domain of one, which makes full duplex possible — and a full-duplex station never defers, never senses carrier, never collides and never backs off. CSMA/CD stayed in the silicon and stopped being reached, which is why the frame floor and the interframe gap now outlive the reasons that produced them.

Autonegotiation made the transition survivable by hiding a new protocol inside a signal older devices already counted. And it paid for that compatibility in the one dimension its trick could not carry: a partner that does not negotiate cannot be asked what duplex it intends, so the other end assumes — which is the duplex mismatch, a fault that reports link up at the correct speed, tests clean at commissioning, and presents each end with a plausible and wrong physical-layer story.

Chapter 9.3 — 1 Gigabit: Four Pairs, Echo Cancellation and GMII takes the next step, and its argument is that gigabit stopped trying to make the channel clean and started cancelling what it could not avoid.

1000BASE-T uses all four pairs simultaneously, in both directions at once — which means each receiver hears its own transmitter's echo and its neighbours' crosstalk, continuously, and must subtract them. The chapter covers the adaptive loops that do it, the master/slave timing relationship that makes the subtraction possible, the PAM-5 signalling that carries two bits per pair per symbol, and why asserting that an adaptive loop converges is the wrong property to write.

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.