Skip to content

UCIe · Module 23

UCIe vs PCIe

Why two interconnects that share protocol semantics are not interchangeable links — normalising both stacks before comparing them, what PCIe-over-UCIe actually means and why it is not PCIe signalling between dies, where latency really comes from, and the RTL layering mistake that makes a protocol engine impossible to move to a different transport.

Module 23 compares UCIe with the rest of the high-bandwidth interconnect family. Every chapter starts the same way: by making sure the two things being compared occupy the same architectural layer.

1. The One-Sentence Model

PCIe connects components across a platform. UCIe connects dies inside a package. They can carry related protocol semantics and they solve different physical problems at different scopes — which is why "UCIe is faster PCIe" is not a simplification but a category error.

The interesting part is the duality. The two are most similar at the top of the stack, where a transaction has a meaning, and most different at the bottom, where a channel has a length. Comparisons go wrong when a reader takes a fact from one end and applies it to the other.

2. The Module 23 Principle

A fair interconnect comparison starts by making sure the two things occupy the same architectural layer.

Four comparisons that are invalid on their face, and you will meet all of them:

Invalid comparisonWhy
a UCIe PHY figure vs a complete PCIe system capabilityPHY vs whole stack
PCIe transaction semantics vs UCIe physical scopesemantics vs physics
a raw line rate vs a delivered payload ratedifferent quantities
one generation of A vs a different generation of Bno common baseline

So every chapter in this module does layer normalisation before any table — §5 is this chapter's.

3. What This Chapter Owns

QuestionWhere
The UCIe stack — Protocol Layer, D2D Adapter, PHY, FDI/RDI19.1 — Link Architecture
Protocol mapping — native, Streaming, Raw Mode19.2 — Protocol Engines
Latency anatomy · bandwidth · package performance15.2 · 15.1 · 15.4
Error detection, recovery, epochs14.1 · 14.2
Verification environments and compliance20.2 · 20.7
Open standard vs proprietary D2D23.2 (next)

Three things are new here:

Layer normalisation as a method (§5–§6), reusable for every remaining comparison.

PCIe-over-UCIe (§8–§9) — the fact that dissolves most of the confusion, and the distinction it forces between PCIe as a protocol and PCIe as an electrical link.

And the layering failure in RTL (§14–§16): a protocol engine that reaches into transport state cannot be moved to a different transport, and the bug is invisible until you try.

4. Sourcing and Evidence Asymmetry

5. Normalising the Two Stacks

A side-by-side layered diagram of two interconnect stacks aligned by responsibility. The left column shows PCIe: transaction semantics at the top, then the data link layer providing reliability and flow control, then the physical layer, then a board or system channel at the bottom. The right column shows UCIe: a protocol layer at the top carrying natively mapped protocols, then the die-to-die adapter providing optional CRC and retry, then the physical layer, then a package channel at the bottom. A centre column labels each row by the shared responsibility: semantics, reliability, physical layer, and physical scope. The bottom row is highlighted as where the two architectures genuinely diverge.PCIe Transactiontransaction semanticsSEMANTICSwhat a request meansUCIe Protocolnatively mapped protosPCIe Data Linkdelivery, flow controlRELIABILITYwho guarantees deliveryD2D AdapterCRC + retry (optional)PCIe PHYserial signallingPHYSICAL LAYERbits on the mediumUCIe PHYdie-to-die signallingBoard channelplatform reachSCOPE — DIVERGESthe real differencePackage channelin-package reach12
The two stacks placed side by side at equivalent responsibilities. Comparison is only meaningful across a row: semantics against semantics, reliability against reliability, physical layer against physical layer, and channel against channel. The rows are aligned by responsibility, not by name, and the bottom row is where the two architectures genuinely diverge.

Three things to read.

The rows are aligned by responsibility, not by name. PCIe's Data Link Layer and UCIe's D2D Adapter are not the same thing; they occupy the same row because both answer "who guarantees delivery?" — and that is the only basis on which they can be discussed together.

Comparison is valid across a row and invalid down a column. Every bad comparison in §2 is a diagonal.

And the bottom row is where the architectures genuinely diverge — one reaches across a platform, the other across a package. Every physical difference in §10 follows from that row, and no protocol difference does.

6. What Each Layer Owns

RowPCIeUCIe
semanticstransaction meaning, ordering, completioncarries a protocol — PCIe and CXL natively mapped
reliabilityData Link Layer: correct, in-order delivery; flow control; acknowledgementD2D Adapter: CRC + link-level retry, described as optional
physicalserial signalling over a platform channeldie-to-die signalling over a package channel
scopecomponent to componentdie to die

Two properties worth pausing on.

Row 2's asymmetry is real and is stated in the sources. PCIe's Data Link Layer is described as responsible for correct in-order delivery; UCIe's Adapter guarantee is described as optional (19.3). That is an architectural difference at an equivalent layer — the most legitimate kind of comparison this chapter can make.

And row 1 is where they touch rather than compete. UCIe does not define transaction semantics of its own for a natively mapped protocol; it carries PCIe's. §8.

7. What Each Deliberately Does Not Define

Half of an architecture is what it leaves to someone else — and this table is where most "A vs B" arguments quietly dissolve.

Not defined by PCIeNot defined by UCIe
what is inside a devicethe semantics of the protocol it carries
how a die is partitioned internallyCPU cache coherence (22.2 §15)
package constructionthe software/device model above it (§12)
management, power sequencing, security (22.5 §5)

And the right-hand column is why UCIe cannot "replace" PCIe in any general sense (§9): it does not define what a transaction means. For a natively mapped protocol, something else does — and for PCIe-over-UCIe, that something else is PCIe.

8. PCIe Over UCIe

The single fact that resolves most confusion in this chapter.

Official UCIe material describes PCIe as a natively mapped protocol. So a PCIe transaction can cross a UCIe die-to-die boundary — and when it does, it is not using a board-level PCIe PHY between the dies.

The distinction the whole chapter turns on:

PCIe as a protocolPCIe as an electrical link
what it istransaction semantics, ordering, completionserial signalling over a platform channel
where it can liveabove any transport that preserves its contracton a PCIe PHY
in a packageyes — natively mapped over UCIenot the point of a D2D link
software seesthe same device model

Four readings.

"Carrying PCIe" and "being PCIe" are different claims. A UCIe link carrying PCIe transactions runs a UCIe PHY over a package channel22.2 §11's layering argument with a specific protocol named.

This is the reason the two are so often confused. They genuinely share the top row of §5. The confusion is not ignorance — it is a real architectural overlap being over-extended.

It also explains why the swap is attractive. Software above a natively mapped protocol need not change: the semantics are preserved and only the transport underneath moved (§14's whole point).

And it bounds the claim. PCIe-over-UCIe says nothing about PCIe outside the package, where a board-level link is doing a job a die-to-die link cannot do at all (§10).

9. The Wrong Mental Model

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
WRONG:   "UCIe replaces PCIe."
 
BETTER:  UCIe may replace a PROPRIETARY DIE-TO-DIE TRANSPORT beneath a
         protocol, while PCIe semantics continue above it unchanged.
 
         PCIe remains the thing that connects components across a platform.
         A die-to-die link does not reach across a platform, and is not
         trying to.

Three properties.

The replaced thing is a transport, not a protocol — and frequently a proprietary one (23.2), which is the comparison that actually makes sense.

PCIe's platform role is untouched by any of this. Devices, slots, add-in cards, and the reach they need are outside a package by definition.

And the "replacement" framing hides the interesting question, which is 22.2 §11's: which layers move? A design can adopt a standard PHY and keep everything above it — and a press sentence saying "supports UCIe" does not say which.

10. Physical Scope Drives Everything Below the Protocol

ConsequencePlatform linkIn-package link
channelconnectors, board traces, longer reachshort, controlled, co-designed
PHY complexityequalisation and recovery for a hostile channelless channel compensation needed
energy per bitdominated by driving that channellower — that is the point of moving in-package
widthserial, few lanes, high ratevery wide, lower rate per wire
hot-plug / removabilitya design requirementnot applicable
topologytrees, switches, a device ecosystema fixed graph, fixed at design time
failure modela device can be absent, removed, or fail alonedies fail with the package

Two readings.

Every row follows from the bottom row of §5, not from any protocol decision — which is why they are architectural differences rather than quality differences.

And rows 5–7 are the ones that make "replacement" incoherent. A die-to-die link has no hot-plug story, no device-absence story and no switch topology, because it never needed one. Those are not deficiencies; they are scope.

11. Where Latency Actually Comes From

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
ILLUSTRATIVE symbolic decomposition. No numeric value for either technology
appears in this chapter (§4).
 
  end_to_end  =  t_protocol_processing     (build/parse the transaction)
              +  t_queue                   (arbitration, buffering)
              +  t_serialize               (payload / link width)
              +  t_phy                     (transmit + receive path)
              +  t_flight                  (channel length)
              +  t_reliability             (CRC check, retry state)
              +  t_bridge                  (any translation on the path)
              +  ...the same terms on the return path
 
  A SHORTER CHANNEL reduces  t_flight  and can reduce  t_phy.
  A WIDER LINK    reduces    t_serialize.
 
  It does NOT reduce:
    t_protocol_processing, t_queue, t_reliability, t_bridge

Four readings, and the third is the one people skip.

Moving in-package removes some terms and not others. 15.2's anatomy: protocol processing and queueing are the same work wherever the wire is.

A bridge is a term, and bridges are common. Translating between a protocol and a transport adds latency on both sides — so a design that moves a boundary in-package and inserts two bridges may not improve end-to-end latency at all.

Queueing frequently dominates under load, and it is a function of provisioning and flow control (13.1), not distance. A congested short link is slower than an idle long one.

And latency improvement does not imply system improvement (22.4 §8): a workload with enough independent work hides latency; one on a dependent chain cannot hide any of it. Which one you have decides whether the change is worth anything.

12. Physical Boundary Is Not Software Boundary

Platform deviceIn-package die
discoveryexplicit, host-visible enumeration and configurationmay be invisible — the package presents one device
identity in softwarea device with configuration statepossibly none
removabilitymodellednot applicable
fault reportingto the platform's error architecturemay be contained inside the package (22.4 §18)

Three properties.

A die-to-die boundary can be completely invisible to software. Two dies can present a single device model, and nothing above needs to know there are two.

Which means the physical partitioning and the software model are independent choices — and a product can change its partitioning across generations without changing its software model at all, which is a large part of chiplets' commercial appeal.

And it inverts a common assumption. "There is a standard link there, so software must see something standard" is false: the link is a transport, and the software model is an entirely separate agreement (22.5 §5).

13. Why This Chapter Has No Bandwidth Table

A numeric comparison is only meaningful when every one of these is pinned:

ConditionWhy
both numbers measure comparable quantitiesaggregate vs per-lane vs per-direction
generation / revision stated for bothotherwise it is two eras
physical topology and scope statedone link vs a whole system
units match
raw line rate vs delivered payload made explicitencoding and framing overhead differ
both from reliable sources at a comparable level§4's asymmetry rule

From Level B material I cannot pin the last four for both sides simultaneously, so this chapter states no figure for either (§4).

And the omission is the lesson. 21.5 §42's denominator discipline applies to comparison exactly as it applies to measurement: a number without its scope, generation and definition is not a measurement, and putting two of them in a table does not make them comparable.

14. Illustrative — Protocol Above Transport

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ILLUSTRATIVE ONLY. A protocol-layer request expressed WITHOUT reference to
// any transport. This is the object §8 says survives a transport change.
typedef enum logic [2:0] {
  SEM_READ, SEM_WRITE, SEM_COMPLETION, SEM_MESSAGE
} sem_kind_e;
 
typedef struct packed {
  logic [SEM_W-1:0]   sem_id;        // the SEMANTIC operation identity
  logic [GEN_W-1:0]   generation;    // which USE of that id (22.4 §12)
  sem_kind_e          kind;
  logic [ADDR_W-1:0]  addr_token;    // opaque; NOT an architectural address
  logic [LEN_W-1:0]   length;
  logic [DOM_W-1:0]   order_domain;  // ordering scope (21.6 §16)
  logic               requires_completion;
} sem_req_t;
 
// The transport-agnostic contract. A transport implements THIS and nothing
// above it may know which transport is behind it.
//
//   sem_valid / sem_ready      -- acceptance, not offering (21.5 §20)
//   sem_req                    -- the object above
//   sem_delivered              -- the transport confirms SEMANTIC delivery
//   sem_delivered_id/gen       -- which object, unambiguously
//
// Note what is ABSENT and must stay absent: lane counts, training state,
// retry counters, PHY status, link width. §15 is what happens when they leak.

Architecture. One semantic object and one narrow contract, so the protocol layer can be paired with either transport of §16 without modification.

State. None here — the object is carried; the transports hold the state.

Cycle/event behaviour. sem_valid && sem_ready is the acceptance event; sem_delivered is a separate, later event carrying the identity. Two events, because acceptance and delivery are different facts and conflating them is 21.4 §5's arrow-2/arrow-9 distinction.

Contract. The transport must confirm semantic delivery, not physical transmission. A transport that signals delivery on transmit has told the protocol layer something false, and §17 is the failure.

Failure. Adding a single transport-specific field here — a lane index, a retry count — couples the layers permanently, and §15 shows what that costs.

DV/debug. This boundary is exactly where a monitor sits (20.2): observing it gives a transport-independent transaction stream, which is what makes one scoreboard work against two transports.

15. Wrong RTL — Transport Leaking Into the Protocol Layer

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// WRONG — the protocol engine reads transport internals directly. Every line
// here is individually reasonable and the combination is a layering failure.
always_comb begin
  // Reason 1: sizing a burst from the PHY's width.
  max_burst = phy_lane_count * BYTES_PER_LANE;
 
  // Reason 2: not issuing while the link is retraining.
  can_issue = (phy_train_state == PHY_ACTIVE);
 
  // Reason 3: treating transport retry as protocol back-pressure.
  throttle  = (transport_retry_count > RETRY_THRESHOLD);
 
  // Reason 4: deriving a timeout from the transport's own recovery timer.
  sem_timeout = transport_recovery_timer + FIXED_MARGIN;
end

What each line costs, precisely:

LineThe couplingWhat breaks on a transport change
max_burstprotocol sizing depends on PHY widtha different width silently changes transaction sizes
can_issueprotocol gated by PHY training statea transport with different states cannot drive it
throttleprotocol responds to transport retrya working retry mechanism becomes protocol back-pressure
sem_timeoutprotocol lifetime depends on a transport timertimeouts become wrong, and §17's corruption follows

Four properties.

Nothing here is a bug today. In a single-transport design every line works, and the design ships.

The cost appears only when the transport changes — which is precisely the scenario §8 makes attractive. The protocol engine that was supposed to be portable is not, and moving it means re-deriving four unrelated behaviours.

The third row is the most damaging. 21.6 §19: a transport retry is the reliability mechanism doing its job, and a protocol layer that throttles on it converts a healthy correction into a performance problem — and hides the real signal-integrity cause (21.7 §32).

And the fix is not to delete the couplings but to replace them with contract terms the transport publishes on its own boundary — §16.

16. Corrected RTL — Two Transports, One Protocol Layer

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// CORRECTED. Everything the protocol layer needs is published BY the transport
// as part of its contract — no transport internals are read.
typedef struct packed {
  logic [15:0] max_object_bytes;    // replaces max_burst — a CONTRACT value
  logic        accepting;           // replaces train-state peeking
  logic [15:0] completion_bound;    // replaces the borrowed timer
  logic        retains_across_recovery;  // §17's field — the one that matters
} transport_caps_t;
 
// The protocol layer now reads ONLY this.
always_comb begin
  max_burst   = tcaps.max_object_bytes;
  can_issue   = tcaps.accepting;
  sem_timeout = tcaps.completion_bound;
  throttle    = 1'b0;   // transport retry is INVISIBLE here, by contract
end
 
// Transport A — a platform-style serial transport.
transport_caps_t caps_serial;
assign caps_serial = '{ max_object_bytes: SERIAL_MAX_BYTES,
                        accepting:        serial_link_up,
                        completion_bound: SERIAL_COMPLETION_BOUND,
                        retains_across_recovery: 1'b1 };
 
// Transport B — an in-package die-to-die transport.
transport_caps_t caps_d2d;
assign caps_d2d = '{ max_object_bytes: D2D_MAX_BYTES,
                     accepting:        d2d_link_up,
                     completion_bound: D2D_COMPLETION_BOUND,
                     retains_across_recovery: 1'b0 };   // <-- DIFFERENT (§17)
 
assign tcaps = USE_D2D ? caps_d2d : caps_serial;

Architecture. A capability record published by the transport, so the protocol layer depends on stated values rather than on observed internals.

State. None in the protocol layer; each transport holds its own.

Cycle/event behaviour. accepting is a contract signal the transport drives; the protocol layer never sees a training state or a retry count.

Contract. retains_across_recovery is the field that carries the semantics of §17, and it exists because the two transports genuinely differ. A capability record that omits a difference does not remove the difference — it hides it, which is 22.5 §4's unstated-assumption failure.

Failure. If the protocol layer assumes one value of retains_across_recovery rather than reading it, swapping the transport produces §17 — the same protocol, the same semantics, and orphaned transactions.

DV/debug. One scoreboard and one monitor now work against both transports, because the observable boundary is identical (20.4 §17) — which is the practical payoff of the whole refactor.

17. Failure — Same Protocol, Different Recovery Assumption

The subtlest failure in the chapter, and it survives every unit test.

StepWhat happens
1protocol layer accepts semantic object X, expects a completion
2the transport takes a link event and recovers
3transport A would have retained X's obligation across recovery
3′transport B discards it — X's transport state is gone
4the protocol layer is still waiting for X's completion
5its timeout was derived from the old transport's bound (§15) and is too long
6X is orphaned: never completed, never failed, holding its identity
7eventually the identity is reused (22.4 §11) — and now a stale completion can corrupt a live request

Four readings.

The protocol did not change and the semantics did not change. Only an unstated assumption about what a transport recovery means to a live obligation changed — 21.4 §22's epoch reconciliation, arriving through a portability change.

Step 6 is a silent hang: no error, no fault, no link event visible to the protocol layer. The link is up and healthy.

Step 7 turns a hang into corruption, which is why 22.4 §12's generation tagging is the second half of the fix — the first half is stating the assumption at all.

And the general rule is that a portable protocol layer must treat "what survives recovery" as an explicit contract term, never as something it learned from the transport it happened to be built against.

18. Assertions

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// MANDATORY. Illustrative architectural properties (§4) — not normative for
// either technology.
 
// (1) ACCEPTED WORK SURVIVES A RECOVERY THAT CLAIMS TO RETAIN IT.
// English: if the transport advertises retention, a semantic object accepted
// before a recovery must still be live after it. Sampled at recovery exit.
// Catches §17 in the configuration where retention was PROMISED.
a_retained_survives_recovery: assert property (
  @(posedge clk) disable iff (!por_n)
    ($fell(in_recovery) && tcaps.retains_across_recovery)
      |-> (live_obj_count == $past(live_obj_count, RECOVERY_SAMPLE_DEPTH))
);
 
// (2) A PHYSICAL RETRY IS NOT A NEW SEMANTIC REQUEST.
// English: however many times the transport retransmits, the protocol layer
// observes one acceptance. Catches the §15 `throttle` coupling and 21.6 §19's
// duplicate-delivery misreading.
a_retry_invisible_to_protocol: assert property (
  @(posedge clk) disable iff (!por_n)
    transport_retry_fire |-> !sem_valid_rise
);
 
// (3) THE PROTOCOL LAYER NEVER READS TRANSPORT INTERNALS.
// English: protocol-layer control depends only on the capability record.
// This is a NON-INTERFERENCE property — best discharged formally, because
// simulation only shows it held for the stimulus you ran (21.7 §17).
a_no_transport_coupling: assert property (
  @(posedge clk) disable iff (!por_n)
    $stable({phy_lane_count, phy_train_state, transport_retry_count})
      || $stable({max_burst, can_issue, sem_timeout})
);
 
// (4) CONFIG EPOCH IS STABLE FOR A LIVE OBJECT.
// English: an object's configuration context cannot change underneath it.
// Catches 21.6 §27's mid-flight mutation, which a transport swap makes newly
// possible.
a_epoch_stable_for_live_object: assert property (
  @(posedge clk) disable iff (!por_n)
    (live_obj_valid && $changed(cfg_epoch_q)) |-> in_quiesce
);

Architecture. Two behavioural contracts, one structural non-interference property, one lifetime property.

State. The live-object count and the epoch register.

Sampled timing. Property (1) samples on $fell(in_recovery)the recovery exit edge, because that is when retention is observable; sampling during recovery would compare against a transient. Property (3) is written as a stability implication so it is formally dischargeable; as a simulation property it proves only what the stimulus explored.

Contract. RECOVERY_SAMPLE_DEPTH must be derived from the recovery's own duration — a guessed value makes (1) either vacuous or constantly false, which is 21.6 §29's bounded-window trap.

Failure if omitted. Without (1), §17 ships. Without (2), a healthy retry mechanism is throttled and the real cause is masked. Without (3), the layering can regress at any time and nothing notices until a transport swap is attempted years later.

DV/debug. Property (3) is the one to run in a formal flow. Non-interference is a proof obligation, and it is the only one of the four that protects the architecture rather than a behaviour.

19. Choosing the Boundary

QuestionReading
is the boundary inside a package, between dies?a die-to-die link is the candidate class
is it between components across a platform?a platform serial link is the candidate class
do you need PCIe semantics at an in-package boundary?PCIe-over-UCIe is architecturally relevant (§8)
do you need device discovery, hot-plug, removability?that is a software and platform model, not a transport choice (§12)
is the boundary crossing an organisation?the standard-versus-proprietary question — 23.2

And the framing that matters more than any row: the question is "what architectural boundary am I trying to standardise?" — not "which interconnect is fastest?"

20. Common Misconceptions

"UCIe is just faster PCIe." §5: they align at the top and diverge at the bottom. The differences are scope, not speed.

"UCIe replaces PCIe everywhere." §9: what gets replaced is a transport beneath a protocol — frequently a proprietary one. PCIe's platform role is untouched.

"PCIe over UCIe means PCIe electrical signalling between dies." §8: it means PCIe semantics carried over a UCIe PHY and package channel. Protocol ≠ electrical link.

"Shorter reach means near-zero latency." §11: a short channel removes t_flight and can reduce t_phy. Protocol processing, queueing, reliability and bridges are unchanged.

"A PCIe device and a UCIe-connected die have the same software model." §12: a die-to-die boundary can be entirely invisible to software.

"If both support PCIe semantics, the PHYs are interchangeable." §10: hot-plug, removability, topology and channel assumptions differ completely.

"Raw GT/s is enough to compare links." §13: without generation, topology, directionality and raw-versus-payload, two numbers in a table are not a comparison.

"Lower latency automatically means better system performance." §11, 22.4 §8: only if the workload cannot already hide it.

21. Understanding Check

22. Summary

Five things.

Normalise the stacks before comparing (§5). Align by responsibility, compare across a row, and treat every diagonal as invalid.

They align at the top and diverge at the bottom (§6, §10). Semantics can be shared; channel, reach, topology, removability and failure model cannot.

PCIe-over-UCIe is the fact that dissolves the confusion (§8) — and it forces the distinction between a protocol and an electrical link, which is the single most useful idea in the chapter.

Latency is a sum of terms and a shorter channel removes only some of them (§11). Protocol processing, queueing, reliability and bridges are unchanged by distance.

And a portable protocol layer depends on published contract values, never on transport internals (§15–§17) — with "what survives recovery" as the term that, left unstated, produces a silent orphan and then a corruption.

On evidence: neither base specification was inspected — UCIe requires registration, PCIe requires PCI-SIG membership. Level B on both sides, Level A on neither, which is why this chapter contains no numeric comparison at all (§13). That symmetry does not survive into the next chapters.