Skip to content

UCIe · Module 5

Layer Responsibilities

A decision framework for assigning UCIe functions to layers — the uncertainty-and-lifetime test, a full responsibility matrix, three worked wrong-ownership cases, and a design-review checklist that outlives UCIe.

Chapters 5.1 to 5.3 examined each layer in isolation. This chapter is not a recap of them, and if it were it would be worthless — you can already recite what each layer does. The useful question is harder and comes up constantly in real design work:

A new function appears in the design. Which layer should own it?

Specifications enumerate the functions that already exist. They do not tell you where to put the one your architecture just invented — a new status register, a new metadata field, a new recovery behaviour, a new configuration parameter. This chapter builds the test for that, and the test generalises well beyond UCIe.

1. The Ownership Test

Two questions decide it, and they are almost always sufficient:

  1. What uncertainty does this function resolve?
  2. What state lifetime must it maintain?

The layer that owns both answers owns the function.

A function belongs to the layer that owns the uncertainty it resolves and the state lifetime it must maintain.

Mapped onto the stack:

LayerUncertainty it ownsState lifetime it maintains
ProtocolWhat does this traffic mean?The semantic transaction — issue to completion
AdapterCan this be transported reliably, and does the link permit progress?The transport and the link session
PHYCan the physical channel move bits at all?The physical link — training to retrain

The two questions usually agree, and when they disagree you have found something interesting: either the function should be split, or it is genuinely mode-dependent (§6).

2. The Responsibility Matrix

The complete picture. The interesting rows are the ones people get wrong, and each of those carries its reasoning.

FunctionProtocolAdapterPHYWhy
Transaction meaningOnly Protocol can interpret it
Transaction tagsIdentity; released on semantic completion (§4)
Ordering guaranteesDefined by the protocol; nothing below knows what may pass what
Transport framingDefines delivery units, not meaning (§3)
Integrity (CRC)mode modeMode-dependent (§5)
Retry / replaymode modeNeeds detection and retained state (§5)
Flow / resource accountingTracks capacity on the remote die
Protocol arbitrationChooses between streams sharing one link
Parameter negotiationExchanges with the remote partner
Higher-level link stateOwns bring-up coordination
Lane mappingPhysical arrangement
Lane healthDiscovered physically
TrainingEstablishes the physical link
Sideband control pathPhysical control channel
Clocking and signallingElectrical
Status abstraction upwardEach layer compresses its own state for the layer above (§7)

Three rows deserve unpacking, and they are §3, §5, and §6.

3. Framing: Meaning Versus Delivery

"Framing" is ambiguous, and the ambiguity causes real design arguments. Split it:

  • Protocol structure describes meaning — what a request looks like, which fields carry an address, how a completion is recognised. That belongs to the layer implementing the protocol.
  • Transport framing describes delivery — where a transport unit begins and ends so the receiver can find its boundaries and check it.

Protocol structure describes meaning; transport framing describes delivery.

The test discriminates cleanly. Transport framing resolves transport uncertainty — where does this unit end, is it intact — and its state lives for the transfer. Protocol structure resolves semantic uncertainty and its state lives for the transaction. Different uncertainty, different lifetime, different owner.

The mode nuance from 5.1 applies here too: in a raw format the Protocol Layer populates the payload entirely, so the division shifts. The principle does not shift — it is still meaning versus delivery — only which layer is doing which.

4. State Lifetime as the Decisive Test

When the uncertainty question is ambiguous, lifetime usually settles it. Follow one transaction and watch three pieces of state with three different lifespans:

StateCreatedDestroyedLifetime
Protocol tagRequest issuedCompletion matchedThe full semantic round trip
Adapter replay entryTransport unit launchedDelivery confirmedOne delivery, plus confirmation latency
PHY training stateBring-up or recoveryRetrain or link lossThe physical link session

These are nested but not aligned: a single tag may outlive many replay entries, and a replay entry may outlive nothing at all if delivery is immediate. A PHY training state may span thousands of transactions or be destroyed mid-transaction by a fault.

State with different lifetimes cannot share an owner, because the owner would have to implement all three destruction rules and would need information from all three layers to know when each applies. That is the mechanical reason the layers exist — not tidiness, but the impossibility of one module correctly managing three unrelated lifetimes.

The Protocol layer owns semantics, tags and ordering with a transaction lifetime. The Adapter owns transport, reliability, negotiation and link state with a link-session lifetime. The PHY owns lanes, training and signalling with a physical-link lifetime. Each lower layer exposes only an abstracted status upward.Protocolmeaning, tags, orderingTransactionlifetimeissue to completionAdaptertransport, reliability,linkSession lifetimenegotiated to retrainPHYlanes, training,signallingLink lifetimetrain to retrainabstract statusabstract status12
Figure 1 — responsibility ownership across the stack. Each layer owns one kind of uncertainty and the state lifetime that goes with it, and exposes only an abstraction upward. The dashed returns are what the layer above is permitted to see: an abstracted status, never the internal state that produced it.

5. Why Reliability Is Not Automatically the PHY's Job

A natural instinct says errors are physical, so error protection belongs at the physical layer. Apply the test and see why that fails.

Reliability requires two capabilities: detecting that something went wrong, and recovering from it. The PHY can plausibly do the first — it is closest to the channel. It cannot do the second, because recovery requires a retained copy of what was sent, and retention must last until delivery is confirmed by the far side. That is transport-session state, not physical-link state.

Reliability belongs where the architecture has both enough information to detect failure and enough retained state to recover from it.

That is why CRC-in-the-PHY is insufficient rather than merely unconventional: a layer that detects corruption but holds nothing to resend can only report, not repair. And it is why the Adapter — which already retains transport units for flow control and already coordinates with the remote partner — is the natural owner when reliability is enabled.

The mode dependency then reads sensibly rather than as an exception: in a raw format the Protocol Layer retains its own state and handles its own protection, which satisfies the same rule with a different layer.

6. Bring-Up Has Three Separate Owners

Collapsing bring-up into one link_up bit is among the most common architectural errors, and 5.5 will show what it costs at integration. Three distinct questions, three owners:

  • PHY: can the physical link function? Training complete, sufficient usable lanes, signalling established.
  • Adapter: have both ends agreed a usable operating point, and is transport ready? Parameters negotiated, resources initialised, link state machine in its ready state.
  • Protocol: may semantic traffic now progress? Its own resources available — tags free, ordering permits, queues have space.

Each is a genuine precondition for the next, and each can be false while the others are true. A PHY that is trained but not negotiated is not usable. An Adapter that is ready but whose Protocol Layer has no free tags cannot issue. One bit cannot represent three conditions, and squashing them together means the debug question "why is nothing moving?" has no localising answer.

7. Three Wrong-Ownership Cases

Each is a real pattern, and each looks locally reasonable.

Case 1 — Protocol owns lane health

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// BAD ownership — illustrative architecture RTL, not UCIe normative naming.
assign may_issue = have_request && lane_good[0] && lane_good[1];

Why it is wrong. Protocol now depends on a specific lane count and numbering. Lane repair that transparently remaps lanes becomes visible upward and breaks it. The Protocol Layer can no longer be verified against an abstract model of the layer below, because that model would have to expose lane detail. And the layer is now bound to one PHY family rather than to a specification-defined boundary.

Test. Lane health resolves physical uncertainty with a physical-link lifetime — both PHY. Protocol should consume the abstraction:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
assign may_issue = have_request && link_operational && protocol_resources_ready;

Case 2 — PHY owns transaction ordering

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// BAD ownership — the PHY cannot legitimately know this input exists.
if (packet_is_ordered)
  hold_lane_transfer <= 1'b1;

Why it is wrong. This is semantic leakage downward, and the giveaway is the input itself: packet_is_ordered is a protocol classification. For the PHY to have it, something must have carried semantic meaning down two layers — meaning the Adapter also had to pass through information it does not interpret. The uncertainty being resolved is semantic and the lifetime is the transaction's; both say Protocol.

Case 3 — Adapter owns the tag lifecycle

The subtlest, because the Adapter genuinely handles tags — they pass through it on every transfer.

But handling is not owning. The Adapter cannot know when the semantic transaction completes, when a tag may be safely reused, or whether a returning completion matches the outstanding entry — all of which require interpreting the transaction. It carries tag bits as opaque payload.

This is the clearest illustration that contact is not ownership. The test: tag lifetime is issue-to-completion (Protocol); the uncertainty is which request a completion belongs to (semantic). Both say Protocol, despite the Adapter touching the bits more often than the Protocol Layer does.

8. Ownership Shows Up in Module Ports

The cleanest structural check available: look at what crosses each module boundary.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Illustrative endpoint hierarchy — not UCIe normative port naming.
module endpoint;
  protocol_layer u_protocol (...);
  d2d_adapter    u_adapter  (...);
  physical_layer u_phy      (...);
endmodule

What must not appear on u_protocol's ports: lane_good, lane_map, training_state, module_enable — any physical detail.

What must not appear on u_phy's ports: transaction_tag, ordered_request_class, completion_expected — any semantic classification.

This makes ownership reviewable without reading a line of logic: a port list is an ownership claim. If a physical signal appears on the protocol module, the violation is visible in the hierarchy before anyone examines behaviour — which is why port-list review is worth doing deliberately rather than incidentally.

9. What May Legitimately Cross

Abstraction does not mean hiding everything, and over-hiding is its own failure — a system nobody can debug.

Each layer should compress its internal state into defined facts the layer above can act on:

  • PHY upward: operational or not; degraded capability where the architecture defines it; error indication.
  • Adapter upward: link operational; negotiated capability; transport and error status.

The distinction that matters: an abstraction is a defined interface contract; raw internal state is an implementation detail. phy_degraded is a contract — it means something the Adapter can act on and it survives a PHY reimplementation. lane_good[7] is implementation.

For debug, the answer is not to widen the functional interface but to expose internal state through a separate observability path — status registers, debug buses, trace — that no functional logic depends on. That keeps the functional contract narrow while keeping the design diagnosable.

10. Assertions Can Catch the Symptoms

Assertions cannot prove an architecture is correctly layered — that is a structural review question (§8). They can catch behavioural manifestations:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Illustrative ownership-boundary properties — conceptual, not UCIe normative.
 
// Protocol must not accept traffic while the abstracted link is down.
property p_no_protocol_accept_when_link_down;
  @(posedge clk) disable iff (!rst_n)
    !link_operational |-> !(fdi_valid && fdi_ready);
endproperty
assert property (p_no_protocol_accept_when_link_down);
 
// Adapter must not transmit while the PHY is not operational.
property p_no_adapter_tx_when_phy_down;
  @(posedge clk) disable iff (!rst_n)
    !phy_link_up |-> !(rdi_valid && rdi_ready);
endproperty
assert property (p_no_adapter_tx_when_phy_down);

Both are safety properties, and note what they check: that each layer respects the abstraction its neighbour provides. They would not catch Case 1 or Case 3 above, because those are structural violations that behave correctly in the configuration they were written for. Ownership defects are found by review; ownership-respecting behaviour is found by assertion. Use both and do not confuse them.

11. A Design-Review Checklist

For any new signal, state element, or function — in UCIe or anywhere layered:

  1. What uncertainty does it resolve?
  2. Which layer has the information to interpret it? If a layer must be told what it means, it does not own it.
  3. How long must the state live, and what event destroys it? Can the candidate owner observe that event?
  4. Which neighbour needs only an abstraction of it? Define that abstraction explicitly.
  5. Would exposing it across a boundary make one layer change when the other's implementation changes? If yes, it is leaking.
  6. Can each layer still be verified with its neighbour replaced by a model? If not, the boundary has been broken.

Question 6 is the sharpest practical test, because it is checkable rather than a matter of taste: if a layer's testbench needs a real neighbour rather than a model, something crossed the boundary that should not have.

12. Common Misconceptions

13. Understanding Check

14. Summary and What Comes Next

Ownership is decided by two questions: what uncertainty does this resolve, and what state lifetime must it maintain? Protocol owns semantic uncertainty over a transaction lifetime; Adapter owns transport and link uncertainty over a session lifetime; PHY owns physical uncertainty over a link lifetime. The two questions almost always agree, and where they do not you have found either a function that should be split or one that is genuinely mode-dependent.

Three rows in the matrix carry most of the difficulty. Framing divides into protocol structure (meaning) and transport framing (delivery). Reliability needs detection and retained state for recovery, which is why the PHY cannot own it alone. And bring-up has three owners, not one bit — physical function, negotiated transport, and protocol resources are independent conditions.

The wrong-ownership cases share a shape: Protocol reading lane health binds it to a PHY implementation; the PHY reading a semantic class proves meaning leaked down through the layer between; and the Adapter appearing to own tags is really contact mistaken for ownership. State with different lifetimes cannot share an owner, because no single module can observe all three destruction events.

For review, a port list is an ownership claim, and the sharpest practical test is whether each layer can be verified with its neighbour replaced by a model. Assertions catch layers failing to respect an abstraction; they do not catch a leak that happens to behave.

Ownership says where state belongs. It says nothing about what happens when those layers exchange signals on the same clock edge — under stalls, status changes, resets, and asynchronous updates. That composition is where locally correct layers produce a broken system:

  • 5.5 — Layer Interactions — combinational ready-loops, elastic buffering, status racing data, reset sequencing across three state machines, CDC at layer boundaries, backpressure latency, and deadlock.

Browse the full path on the UCIe tutorials index.