UCIe · Module 28
“UCIe Is Only a PHY”
The belief that standardising the wires is what makes chiplets interoperate — why the PHY dominates every discussion, the counterexample of two chiplets with identical PHYs that cannot talk, and the double-retry bug that appears when an upper layer's timeout is shorter than the transport's delivery time.
It usually surfaces during scoping. Someone is sizing an IP block or writing a partition plan, and the line item reads "UCIe PHY" — with everything above it quietly assumed to be the team's own problem. Sometimes that assumption is right. When it is wrong, it is wrong in one of two opposite directions, and both are found at integration.
1. The Belief
"UCIe is a standardised die-to-die PHY. The layers above it are mine to build."
The belief is a scope claim, not a technical error — and that is what makes it hard to challenge. Nobody says anything false about signalling; they simply draw the specification's boundary in the wrong place, and then plan, budget and build against that boundary.
The replacement model (§7): interoperability is a stack property, not a wire property. A PHY moves bits. Something must still own link bring-up, parameter negotiation, protocol mapping, and — where it exists — delivery guarantees — and the architecture's job is to say which side of the boundary each of those sits on before anyone budgets for them.
2. Why a Competent Engineer Believes It
The PHY dominates the discussion for reasons that are entirely legitimate.
It is the hard part. Die-to-die signalling at aggressive bump pitch is genuinely the most difficult engineering in the stack, and it is where the differentiating work happens. Attention follows difficulty.
Every published comparison is a PHY comparison. Bandwidth density, GT/s, energy per bit, bump pitch, reach — these are the numbers that appear in every slide, because they are the numbers that can be compared. The layers above do not reduce to a KPI, so they are absent from the material an engineer reads most.
The name suggests it. "Interconnect" reads as "the thing between" — physical by connotation.
And prior experience reinforces it. Most standardised interfaces an engineer has integrated are essentially a PHY plus a thin controller they built: a memory PHY, a SerDes. The pattern generalises well and fails here.
One more, less comfortable. A PHY is the easiest part to procure and the easiest to scope, so a plan that treats the problem as a PHY plus in-house logic is a plan that can be written quickly. Scoping pressure selects for this belief even when the engineer knows better.
3. The Hidden Assumption
That standardising the wires is what makes chiplets interoperate — that if two dies agree on signalling, everything above it is a private implementation choice.
Two sub-assumptions.
A — that bring-up is a physical process. If two PHYs can train, the link exists. This omits parameter negotiation and link-state agreement, which are agreements between logic, not between transmitters.
B — that reliability is always the upper layer's job. Because in a PHY-plus-controller world it is. If a transport underneath already provides delivery guarantees, building another one is not redundancy — it is a defect (§10).
4. The Root-Cause Tree
| Level | What happens |
|---|---|
| belief | "UCIe is only a PHY" |
| ↓ assumption A | if the wires agree, the dies interoperate |
| ↓ assumption B | reliability is always mine to provide |
| ↓ architecture decision | reliability ownership is never asked (27.1 §7 B3) — it is assumed, in one of two opposite directions |
| ↓ RTL decision | the protocol engine implements its own retry, with its own timeout, over a transport that may already retry (§10) |
| ↓ DV decision | the environment tests upper-layer retry and transport retry, never both at once |
| ↓ observed failure | duplicate delivery under marginal link conditions only |
| ↓ misleading symptom | "the link is unreliable" — it is retrying, and duplicates appear |
| ↓ first divergence | the cycle the upper timeout expired while a lower-layer retry was still in flight |
| ↓ corrected model | §7, §11 — one named reliability owner, and an upper timeout bounded by the transport's worst-case delivery |
The tree's second branch is the one to notice. Assumption B produces two opposite failures depending on which way the assumption falls: build a retry layer over one that exists (§10's duplicate delivery), or omit one because you assumed the transport had it (§13's silent loss). Both come from the same unasked question, which is why the review item is "who owns reliability?" rather than "is there retry?"
5. Sourcing and Scope
6. What a PHY Is and Is Not
| Concern | Physical? | What happens if nobody owns it |
|---|---|---|
| signalling, equalisation, training | yes | no bits move |
| link state management | no | each side has its own idea of "up" (26.5 §13) |
| parameter negotiation | no | two dies train and then disagree about width or capability |
| protocol mapping | no | bits arrive and mean nothing |
| delivery guarantee | no | either provided twice, or not at all (§10, §13) |
| arbitration between protocols | no | one protocol starves another |
Three readings.
Five of six rows are agreements between logic, not properties of transmitters. That ratio is the chapter in one table — the PHY is the hardest row and the smallest fraction of what must be agreed.
Row 3 is the one that surprises people most. Two dies can train successfully and still disagree about what was negotiated. Training establishes that the channel works; it does not establish that the two sides concluded the same thing about it.
And row 5 is the shaded band's centre. "Who provides delivery guarantees?" has three possible answers — the transport, the protocol layer, or nobody — and all three are architecturally legitimate. The defect is not any particular answer; it is not having one (§4).
7. The Minimal Counterexample
Two chiplets. Identical PHYs — same signalling, same rate, same training procedure, electrically perfect. Do they interoperate?
No. And each reason is a separate, sufficient refutation.
| They still fail if… | Because |
|---|---|
| they disagree on the link state machine | one considers the link usable at a point the other does not (26.5 §13) |
| they negotiate parameters differently | trained successfully, then disagree about width or capability |
| they map different protocols | bits arrive intact and mean nothing |
| both provide retry | §10 — duplicate delivery under load |
| neither provides retry | §13 — silent loss, and each assumed the other |
| they hold different retention policies | 27.5 §8 — a hang after recovery |
The belief predicts interoperability. Six independent mechanisms deny it — and the PHY was perfect in all six.
Three readings.
A perfect PHY is a necessary condition and not close to a sufficient one. That is the precise correction: not "the PHY doesn't matter" — it matters enormously — but "agreeing on it settles one of six things."
The industry's own behaviour corroborates this (22.1 §4). Intel's UCIe milestone was described as an interoperability test chip — two independent IP implementations on two different companies' process nodes, demonstrated interoperating. If agreeing on a PHY were sufficient, interoperability would not be the thing worth demonstrating. The existence of the demonstration is evidence about what is hard.
And rows 4 and 5 are the same unasked question producing opposite failures — which is why the architecture review's item is phrased as ownership rather than presence (27.1 §7 B3).
8. When the Belief Is Locally Useful
| The simplification | Where it holds | Where it breaks |
|---|---|---|
| "it's a PHY plus my controller" | integrating a memory PHY or a SerDes — the pattern is exactly right there | when the standard's scope includes layers above the PHY |
| "compare interconnects on PHY KPIs" | choosing between PHY implementations at a fixed stack | when comparing stacks, where the KPIs are the smaller question |
| "the PHY is where the risk is" | schedule and silicon risk — often true | interoperability risk, which lives in the agreements (§7) |
Two readings.
Row 1 is why this belief is held by engineers who have integrated more standards, not fewer. The PHY-plus-controller pattern is correct for most interfaces they have shipped. Generalising from a strong base of experience is not carelessness — it is the normal way expertise works, and it is exactly what makes this misconception durable.
And row 3 is a genuinely useful distinction to keep. PHY risk and interoperability risk are different risks with different owners and different mitigations. The belief collapses them into one, and the collapse is what leaves the second unmanaged.
9. Architectural Consequence
| Decision | With the belief | With the correct model |
|---|---|---|
| reliability ownership | assumed, in one direction or the other | named once, explicitly — and recorded as a contract row |
| area and power budget | PHY only | PHY plus the logic that owns §6's five non-physical rows |
| verification scope | a PHY-level environment | the layer that owns link state, negotiation and delivery |
| interoperability plan | "we match the PHY spec" | the paired configuration matrix (27.5 §20) |
| supplier contract | electrical parameters | capability record including the retention and reliability model |
| schedule risk | concentrated in analogue | also in agreement-level integration |
Three readings.
Row 1 is the whole chapter, and it produces §10 and §13 as its two outcomes. Neither is a subtle bug — one duplicates data and one loses it — and both are invisible in single-side verification because each side is internally consistent.
Row 2 is the budget error that gets discovered late and cheaply misattributed. A plan sized for a PHY discovers the adapter-level logic during implementation, and it is recorded as "scope growth" rather than as a scoping error — so the same mistake is available next time.
And row 5 is the supplier version. An electrical datasheet is not a capability record. The fields that decide whether two dies work together are the ones about behaviour — who retries, what survives recovery, who commits configuration (27.1 §20) — and none of them appear in a PHY specification.
10. RTL Consequence — Two Reliability Layers
The natural code for an engineer who believes the layers above the PHY are theirs: a protocol engine with its own retry and its own timeout.
// WRONG. ILLUSTRATIVE. An upper-layer retry engine. Every line is competent —
// this is exactly how you build reliability over an unreliable transport. The
// defect is that nobody established whether the transport below is unreliable,
// and the timeout was chosen from measured latency rather than from a stated
// worst case.
localparam int UPPER_TIMEOUT = 200; // BUG 1: derived from observation
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
for (int e = 0; e < N_ENTRY; e++) begin
op_live_q[e] <= 1'b0;
op_timer_q[e] <= '0;
end
end else begin
if (issue_fire) begin
op_live_q[alloc_id] <= 1'b1;
op_timer_q[alloc_id] <= '0;
op_sem_id_q[alloc_id] <= next_sem_id_q;
end
for (int e = 0; e < N_ENTRY; e++) begin
if (op_live_q[e]) begin
if (op_timer_q[e] == UPPER_TIMEOUT) begin
// BUG 2: re-issue with a NEW semantic identifier. From this layer's
// point of view the old operation is gone, so a fresh id is
// the obvious choice — and it makes one request into two
// operations at the peer.
op_sem_id_q[e] <= next_sem_id_q;
next_sem_id_q <= next_sem_id_q + 1'b1;
op_timer_q[e] <= '0;
reissue_fire <= 1'b1;
end else begin
op_timer_q[e] <= op_timer_q[e] + 1'b1;
end
end
if (cmpl_fire && (cmpl_id == e[ID_W-1:0])) op_live_q[e] <= 1'b0;
end
end
endArchitecture. A per-operation timer and a re-issue path — a correct reliability layer, built at the wrong altitude.
State. Live bits, timers, and a semantic identifier that this layer feels entitled to change (BUG 2).
Event. op_timer_q == UPPER_TIMEOUT triggers a re-issue without any knowledge of what the transport is currently doing.
Contract. It assumes the transport either delivers promptly or has given up. If the transport is still retrying, both assumptions are false — and nothing in this layer can tell the difference between a slow delivery and a lost one.
Failure — the timeline. A marginal link. The transport's own retry takes longer than 200 cycles to complete.
| Cycle | Upper layer | Transport | Peer | Observable |
|---|---|---|---|---|
| 0 | issues sem_id = 5, timer starts | attempt 1 sent | — | normal |
| 90 | timer = 90 | attempt 1 corrupted; transport begins retry | — | no upper-layer visibility |
| 150 | timer = 150 | attempt 2 in flight | — | — |
| 200 | timeout → re-issue as sem_id = 6 | attempt 2 still in flight | — | two operations now exist |
| 210 | 5 and 6 both live | attempt 2 delivered | receives operation 5 | peer begins work on 5 |
| 230 | — | attempt 3 (for 6) delivered | receives operation 6 | peer now has two operations |
| 260 | — | — | completes 5 | response for 5 |
| 261 | retires 5 | — | — | looks normal |
| 290 | — | — | completes 6 | second completion for one request |
| 291 | retires 6 | — | — | the operation was performed twice |
Root cause. Two independent reliability mechanisms, neither aware of the other, and an upper-layer timeout shorter than the lower layer's worst-case delivery time. BUG 2 makes it corrupting rather than merely wasteful — a re-issue that preserved the semantic identifier would produce a duplicate the peer could detect; a re-issue with a fresh identifier produces a duplicate the peer cannot distinguish from a genuine second request.
Why it only appears under marginal conditions. On a clean link the transport never retries, so the upper timer never races anything. The bug requires transport retry latency to exceed the upper timeout — which happens exactly when the link is degraded, and therefore exactly when nobody trusts the link anyway.
DV/debug. The reported symptom is "the link is unreliable — we see duplicates when the error rate rises." The link is retrying correctly; the duplicates are manufactured above it. The discriminator is operations issued at the requester versus operations received at the peer (27.6 §13) — one issued, two received, locates it above the transport instantly.
11. Corrected — One Owner, and a Bounded Timeout
// CORRECT. ILLUSTRATIVE. Two changes, and the second is the one usually missed.
// (a) exactly one layer provides retry, established at the architecture gate;
// (b) if an upper timeout exists at all, it is bounded BELOW by the transport's
// STATED worst-case delivery — so it can never race a retry in progress.
localparam int UPPER_TIMEOUT = TRANSPORT_MAX_DELIVERY + TIMEOUT_MARGIN;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
for (int e = 0; e < N_ENTRY; e++) op_live_q[e] <= 1'b0;
end else begin
if (issue_fire) begin
op_live_q[alloc_id] <= 1'b1;
op_timer_q[alloc_id] <= '0;
op_sem_id_q[alloc_id] <= next_sem_id_q; // assigned ONCE, for its life
next_sem_id_q <= next_sem_id_q + 1'b1;
end
for (int e = 0; e < N_ENTRY; e++) begin
if (op_live_q[e]) begin
if (op_timer_q[e] == UPPER_TIMEOUT) begin
// A timeout here is a FAULT, not a retry. The transport owns retry;
// exceeding its stated worst case means the transport failed, and
// that is an error to report rather than a condition to paper over.
op_live_q[e] <= 1'b0;
fault_class_q <= FC_TRANSPORT_TIMEOUT;
fault_sem_id_q <= op_sem_id_q[e];
fault_valid_q <= 1'b1;
end else begin
op_timer_q[e] <= op_timer_q[e] + 1'b1;
end
end
if (cmpl_fire && op_live_q[cmpl_id] && (cmpl_gen == op_gen_q[cmpl_id]))
op_live_q[cmpl_id] <= 1'b0;
end
end
end
// MANDATORY. English: this layer never re-issues an operation — retry is owned
// below. Catches the reintroduction of §10's BUG 2, including by someone
// "improving" error recovery later.
a_no_upper_reissue: assert property (
@(posedge clk) disable iff (!rst_n)
!reissue_fire
);
// MANDATORY. English: an operation's semantic identifier never changes while it
// is live. This is the general form of BUG 2 and holds regardless of which
// layer owns retry (25.5 §11).
a_sem_id_immutable: assert property (
@(posedge clk) disable iff (!rst_n)
(op_live_q[chk] && $past(op_live_q[chk]))
|-> (op_sem_id_q[chk] == $past(op_sem_id_q[chk]))
);
// MANDATORY, and it is a PARAMETER check rather than a temporal one — so it
// belongs in an elaboration-time assertion. English: the upper timeout must
// exceed the transport's stated worst-case delivery, or the two layers race.
initial begin
if (UPPER_TIMEOUT <= TRANSPORT_MAX_DELIVERY)
$error("UPPER_TIMEOUT (%0d) must exceed TRANSPORT_MAX_DELIVERY (%0d)",
UPPER_TIMEOUT, TRANSPORT_MAX_DELIVERY);
endArchitecture. Retry lives in exactly one layer. The upper layer keeps a timer — but it is a fault detector, not a retry trigger, and that distinction is the fix.
State. Identical to §10 minus the mutable identifier. op_sem_id_q is written once, at allocation.
Event. A timeout now produces a named fault rather than a re-issue. An operation that exceeds the transport's stated worst case has genuinely failed, and reporting it is more useful than silently trying again.
Contract. TRANSPORT_MAX_DELIVERY must be a stated number from the transport's owner (27.5 §6) — not measured. A timeout tuned until it stops firing cannot detect the failure it exists for (21.6 §29), and a measured worst case is a lower bound on the real one.
Failure. The residual risk is the other direction of §4's branch: if the transport does not provide retry and this layer no longer does either, there is no reliability at all (§13). That is why the fix is "name the owner", not "remove the upper retry" — the assertion a_no_upper_reissue is correct only in a configuration where the transport owns it.
DV/debug. The elaboration-time check is worth more than either assertion, because it fires at compile time on every configuration — including derivative products where someone changed one parameter and not the other. That is the failure mode a temporal assertion catches too late to be cheap.
12. DV Consequence
| DV mistake the belief produces | Consequence |
|---|---|
| upper-layer retry and transport retry tested separately | §10's race is never constructed |
| the environment models an unreliable transport or a reliable one, never a slow one | timeout-versus-delivery is untested |
| no coverage bin for "upper timeout expired while transport retry in flight" | the exact failure condition is unmeasured |
| the checker treats a re-issue as a new operation | it agrees with the DUT's error (27.3 §7) |
| interop testing is PHY-level | §7's six mechanisms all untested |
Two readings.
Row 3 is the coverage item that would have found this before silicon, and it is one cross: transport retry in progress × upper-layer timer near expiry. 27.3 §16's concurrency argument in its most specific form — each mechanism works; the pair does not.
And row 5 is the interop consequence. A PHY-level interoperability test proves the wires agree. §7 lists five further mechanisms it cannot exercise, and each of them is sufficient on its own to prevent two chiplets from working together.
13. The Other Direction — Nobody Owns It
§10 is what happens when the assumption falls one way. This is the other, and it is quieter.
The setup. The integrator assumes the transport provides delivery guarantees, so the protocol layer implements none. The transport's configuration does not provide them — or the supplier assumed the integrator would.
| Symptom | Why it misleads |
|---|---|
| occasional lost transactions under load | rare enough to look like a software or firmware issue |
| no error reported anywhere | nothing detected a loss, because nothing was checking |
| CRC and link counters clean | the transport did not fail — it delivered what it accepted |
| the failure rate tracks link margin | looks like a physical problem |
| each side's documentation is correct | neither claims to provide what neither provides |
Three readings.
This is worse than §10, because §10 at least produces evidence. A duplicate is visible. A silent loss with nothing checking produces a symptom with no first divergence at all (27.6 §6) — the first observable event is whatever eventually depends on the missing data.
And both organisations are individually correct. 27.5 §8's pattern exactly: two individually valid assumptions, no shared answer. The contract row that prevents it is one line — "who provides delivery guarantees?" — with the answer recorded on both sides.
The detection that should exist regardless is an end-to-end semantic completion check: operations issued versus operations retired, compared over a long run. If reliability is provided somewhere, the counts match. If they do not match and nothing errored, nobody owns reliability — and that is a five-minute measurement that settles the question empirically.
14. Which Review Gate This Corrupts
| Gate | How |
|---|---|
| 27.1 Architecture | B3 — "where is reliability provided, and by whom?" is never asked, because it looked like a PHY question |
| 27.2 RTL | I1/I2 — UPPER_TIMEOUT has no derivation and no owner |
| 27.3 Verification | §16's crosses — the two retry layers are never exercised together |
| 27.5 Integration | the capability record contains electricals and not behaviour |
And 27.1 §20's compatibility predicate catches both directions mechanically. X_DOUBLE_RETRY when both sides provide it, X_NO_RELIABILITY when neither does — two symmetric checks, and only one of them is ever noticed informally. Everyone spots missing reliability eventually; nobody spots two layers of it until latency is inexplicably high and duplicates appear under load.
15. Whiteboard Question
"Two chiplets have identical, perfectly working PHYs. Give me three independent reasons they might still not interoperate."
A weak answer hesitates, then offers one — usually protocol mismatch — and stops.
A strong answer names them by category (§7): link state agreement — one side considers the link usable at a point the other does not. Parameter negotiation — both trained, then disagreed about width or capability. Reliability ownership — both provide retry, or neither does. And it adds the fourth if pressed: retention across recovery, where each side holds a defensible and opposite policy (27.5 §8).
Then the sentence that shows the model rather than the list: "the PHY is a necessary condition and roughly one of six things that must agree — and the other five are agreements between logic, not properties of transmitters."
And the corroborating observation, if you want to close it well (22.1 §4): "which is why an industry interoperability demonstration between two IP vendors on two process nodes was considered a milestone. If matching the PHY were sufficient, that wouldn't have been worth demonstrating."
16. Interview Ladder
Weak candidate answer. "UCIe is the standard die-to-die PHY — it standardises the physical interface so chiplets from different vendors can connect."
Why the interviewer probes. The answer is not wrong about the PHY; it is a scope claim, and the interviewer wants to know whether the candidate has ever had to make the layers above work. The follow-up is diagnostic: someone who has integrated a real link will have hit §7's list.
Follow-up. "Suppose two dies have identical PHYs. What else has to agree?"
Strong revised answer. "The PHY is necessary and not sufficient. They also have to agree on link state management — when each side considers the link usable — on parameter negotiation, on protocol mapping, and critically on who provides delivery guarantees. That last one has three legitimate answers: the transport, the protocol layer, or nobody — and the defect isn't picking the wrong one, it's not picking. If both provide retry you get duplicate delivery under marginal conditions; if neither does you get silent loss. Both are found at integration, and both come from the same unasked question."
And the scope statement, source-qualified (§5): "the specification's own public material lists protocol mapping among its focus areas alongside die-to-die I/O — so treating it as only a PHY under-scopes what has to be agreed."
17. How to Remember the Correct Model
A PHY moves bits. Interoperability is an agreement, and agreements are made by logic.
And the operational form, which is what you actually use in a review: count the things that must agree. Signalling is one of them. If your plan has an owner for exactly one and an assumption for the other five, the plan is a PHY plan wearing an interconnect label.
The memory hook for the failure is the parameter relationship: an upper timeout shorter than the transport's worst-case delivery is two reliability layers racing — and the elaboration-time check that prevents it is three lines (§11).
18. Understanding Check
19. Summary
Six things.
The belief is a scope claim, not a technical error (§1) — which is why nobody in the room objects to it.
Only one of six things that must agree is physical (§6). Link state management, parameter negotiation, protocol mapping, delivery guarantees and arbitration are agreements between logic.
The counterexample is two perfect identical PHYs that still fail (§7), for six independent reasons — corroborated by the industry treating cross-vendor interoperability as a milestone worth demonstrating.
The unasked question is ownership, and it fails in both directions (§4). Both layers retry → duplicate delivery under degradation (§10). Neither does → silent loss with no first divergence (§13).
In RTL it is a parameter relationship (§10–§11): an upper timeout shorter than the transport's worst-case delivery is two reliability layers racing — and an elaboration-time check catches it at compile time, on every configuration.
And the durable part of the belief is real (§8): the PHY-plus-controller model is correct for most interfaces an engineer has shipped. Count what must agree (§17) — that is the repair, not abandoning the pattern.