UCIe · Module 25
Product Integration
Turning every cross-die assumption into an explicit, versioned, testable contract with a named owner — the twelve-row contract matrix, the capability fields suppliers least volunteer, why two dies can each pass their own sign-off and still fail in the package after recovery, and what makes an integration decision irreversible.
Chapters 25.8 and 25.9 were about finding bugs. This is the culmination of Module 25 — and the question deliberately spans further than any one engineer's block.
1. What They Ask
"Describe end-to-end integration of a UCIe chiplet into a product."
Or: "You're the integration lead. What's your plan?" · "What would you want from the chiplet team before tape-out?" · "First silicon arrives. What do you do?"
They are testing whether you can see past your own block. A candidate who answers only about RTL has answered a smaller question than the one asked.
2. The One-Sentence Model
Integration succeeds when every cross-die assumption becomes an explicit, versioned, testable contract with a named owner.
Four words are doing work there. Explicit — written down, not understood (§7). Versioned — because the peer you integrate with in three years is not the one you designed against (§9). Testable — checkable before silicon (§16). Named owner — because an unowned contract is an unowned failure (§19).
3. What They Are Really Testing
| They are checking | The tell |
|---|---|
| do you think in contracts or in blocks? | you name owners, not modules |
| do you know the phases? | §6 — and which ones are irreversible |
| compatibility reasoning | §10 — a predicate, not equality |
| configuration ownership | §11–§12 — one owner, atomic commit |
| reset and recovery scope | §13 — the table, not a hand-wave |
| the non-RTL contracts | §14, §15 — firmware and package |
| can you plan a bring-up? | §17 — with pass/fail evidence per stage |
| whose bug is it? | §18 — sometimes neither die's |
And the last row is the one that separates an integration lead from an engineer. "Both dies are correct and the package is broken" is a real outcome, and knowing it exists changes how you write contracts.
4. What You Can Safely Assert
5. The Answer Ladder
15 SECONDS — the model, and the scope.
"Integration is really contract management. Every assumption that crosses
a die boundary has to become something written down, versioned, testable
before silicon, and owned by a named person. The technical work spans
architecture through firmware and bring-up, but the failures almost
always trace back to an assumption nobody wrote down."90 SECONDS — adds the phases and the failure shape.
"I'd think about it in phases. First the architecture contract — what
crosses the boundary, what the semantics are, who owns configuration.
Then interface freeze, which is the point of no return, because the two
dies tape out separately and no single change reconciles them
afterwards.
Then RTL integration and subsystem verification against a peer model,
not against the peer's RTL. In parallel, the package assumptions and the
firmware contract — capability discovery, configuration ownership, error
reporting.
Then pre-silicon signoff, a manufacturing test plan, and a staged
bring-up where each stage has explicit pass/fail evidence.
And the failure mode I'd design against specifically is two dies that
each pass in isolation and fail together — usually because they
interpreted something like reset scope differently and nobody wrote it
down."
[STOP — that last sentence is the hook, §22.]Three properties.
Both versions lead with contracts, not with a flow diagram. The phases matter and they are the second thing.
"The point of no return" is the sentence that shows you understand why this is different from SoC integration (24.3 §5) — separate tape-outs cannot be reconciled by one ECO.
And the closing sentence plants §18, which is the strongest story in the chapter and the one that synthesises the whole module.
6. The Phases
| Phase | Produces | Reversible? |
|---|---|---|
| architecture contract | what crosses, semantics, ownership | yes |
| interface freeze | the contract, versioned | NO — separate tape-outs |
| RTL integration | the die | expensive |
| subsystem verification | confidence against a peer model | yes |
| package feasibility | reach class, bump budget, thermal | early, and it bounds everything |
| firmware / configuration | discovery, config, error paths | yes |
| emulation / FPGA where applicable | pre-silicon software bring-up | yes |
| pre-silicon signoff | the decision to tape out | NO |
| manufacturing test plan | what is testable pre- and post-package | must be planned before tape-out |
| first-silicon bring-up | §17 | — |
| production diagnostics | field evidence | — |
Three properties.
Two rows are irreversible, and both are decisions rather than deliverables. Naming them is what makes this a plan rather than a list.
Package feasibility is early (24.3 §6): a partition the package cannot support is not a partition, so this gates the architecture contract rather than following it.
And the manufacturing-test row must be planned pre-tape-out (21.7 §4): observability cannot be added afterwards, so what is testable at each stage is a design decision made in phase 1.
7. The Contract Matrix
The chapter's strongest artefact. If you can reproduce this, you can answer the question.
| Contract | Owner | Producer | Consumer | Versioned? | Reset scope | Config source | Verified by | Silicon observable |
|---|---|---|---|---|---|---|---|---|
| link profile | integration lead | negotiation | both dies | yes | link | negotiated | link checker | active-config register |
| protocol semantics | protocol architect | protocol layer | peer protocol layer | yes | none | fixed at design | semantic scoreboard | trace event stream |
| traffic classes + progress reserve | system architect | both | both | yes | none | negotiated | stress + starvation test | per-class counters |
| reliability ownership | protocol architect | adapter or protocol | the other | yes | none | capability | fault injection | retry counters |
| reset scope | integration lead | reset controller | all blocks | yes | itself | fixed | recovery-with-traffic test | reset cause register |
| recovery retention | protocol architect | adapter | protocol layer | yes | link | capability | §18's test | outstanding count |
| power states | power architect | PMU | both dies | yes | domain | firmware | state-sweep test | state register |
| configuration ownership | integration lead | one owner (§11) | all | yes | none | firmware | atomicity assertion | config epoch |
| capability / version | product owner | each die | integrator | yes | none | ROM / straps | compatibility predicate | capability register |
| error classes + severity | RAS owner | all | firmware | yes | none | fixed | fault injection | first-fault register |
| package / channel | package lead | package | PHY | revision | n/a | characterisation | PHY signoff | margin telemetry |
| firmware interface | firmware owner | hardware | driver | yes | none | discovery | software bring-up | status/control regs |
Four readings.
Every row has a named owner, and that is the point. An unowned row is where §18 happens.
The "silicon observable" column is what makes each row testable in the field (21.7 §6). A contract with no observable cannot be checked after tape-out — so that column is a design requirement, not documentation.
Three rows are owned by the integration lead — link profile, reset scope, configuration ownership — because they are cross-cutting and nobody else will claim them.
And the recovery-retention row is the one that fails in §18. It is a protocol-architect contract, it is easy to leave implicit, and it produces a failure neither die owns.
8. Where the Contracts Sit
Three things to read.
Firmware consumes the capability contract, not the dies. That indirection is what lets the partitioning change across generations without changing the software model (22.4 §12).
The contracts block is the only path between the dies in this view — deliberately, because every cross-die assumption should be in that box or it is not in the plan.
And every contract terminates at a named owner (§7). An arrow that reaches nobody is §18.
9. RTL — the Capability Contract
// ILLUSTRATIVE ONLY. What one die must publish for an integrator to decide
// whether it can be used, and for a peer to negotiate with it at bring-up.
typedef struct packed {
// IDENTITY — for attribution and errata matching
logic [15:0] vendor_id;
logic [15:0] part_id;
logic [7:0] silicon_rev;
logic [15:0] errata_rev;
// PROTOCOL
logic [15:0] protocol_caps; // what it CAN carry
logic [15:0] protocol_required; // what it NEEDS the peer to accept
logic [7:0] ordering_domains;
// TRAFFIC AND PROGRESS — 22.3 §17's deadlock, as fields
logic [7:0] tc_caps;
logic [7:0] tc_progress_critical; // which MUST NOT be starved
logic provides_progress_reserve;
logic [15:0] max_outstanding;
// RELIABILITY — the field that decides who protects the link
logic uses_adapter_retry;
logic supplies_own_integrity;
// RECOVERY — §18's field. Leaving this implicit is the failure.
logic retains_across_recovery;
logic requires_replay_on_recovery;
logic [7:0] reset_scope_model;
// CONFIGURATION
logic [7:0] cfg_version;
logic is_config_owner; // exactly ONE die may assert this (§11)
// COLLATERAL — what the supplier SHIPPED, not what the die does
logic has_peer_model;
logic has_protocol_checker;
} chiplet_capability_t;Architecture. One record per die, published in a readable register and available at design time as data, structured so a missing agreement is a missing field.
State. A constant per die (ROM or straps), plus a register holding the peer's copy after exchange.
Event. Read at design time by §10's predicate; exchanged at bring-up and re-exchanged on renegotiation — a die that changes its advertised capability mid-agreement is 21.6 §27's illegal mutation.
Contract. Three field pairs exist because the pair is the evidence. protocol_caps with protocol_required — what it can do versus what it needs. tc_progress_critical with provides_progress_reserve — 22.3 §17's deadlock is exactly a mismatch across those two. retains_across_recovery with requires_replay_on_recovery — §18.
Failure. Omitting retains_across_recovery is §18. Omitting is_config_owner is §11. Omitting the two has_* fields means the integrator discovers the verification gap after committing (24.1 §11).
DV/debug. Both capability records belong in the debug snapshot (21.7 §9). In an interoperability matrix the failing pair is usually distinguished by one field — and §19 is that case.
10. Compatibility Is a Predicate
// ILLUSTRATIVE ONLY (§9). Design-time / verification model. THIRTEEN named
// outcomes, because "incompatible" is not a finding (22.1 §22).
typedef enum {
COMPAT_OK,
X_PROTOCOL_UNMET,
X_RELIABILITY_OWNER, // §19's failure
X_RECOVERY_MODEL, // §18's failure
X_RESET_SCOPE,
X_PROGRESS_RESERVE,
X_NO_CONFIG_OWNER, // §11
X_TWO_CONFIG_OWNERS, // §11
X_CFG_VERSION,
X_SYSREQ_PROTOCOL,
X_SYSREQ_OUTSTANDING,
RISK_NO_PEER_MODEL, // not a blocker — changes the plan
RISK_ERRATA
} compat_e;
function automatic compat_e compatible(chiplet_capability_t a,
chiplet_capability_t b,
sys_req_t req);
// PROTOCOL: intersection, checked in BOTH directions.
if ((a.protocol_caps & b.protocol_required) != b.protocol_required)
return X_PROTOCOL_UNMET;
if ((b.protocol_caps & a.protocol_required) != a.protocol_required)
return X_PROTOCOL_UNMET;
// RELIABILITY: they must AGREE on who protects the link. One side relying
// on the adapter's retry while the other supplies its own — or neither
// supplying any — is §19, and the symptom is corruption with a legal trace.
if (a.uses_adapter_retry != b.uses_adapter_retry) return X_RELIABILITY_OWNER;
if (!a.uses_adapter_retry &&
!(a.supplies_own_integrity && b.supplies_own_integrity))
return X_RELIABILITY_OWNER;
// RECOVERY: §18. Both must agree what a link recovery does to outstanding
// semantic work. Retain-vs-replay is fine; retain-vs-discard is not.
if (a.retains_across_recovery != b.retains_across_recovery)
return X_RECOVERY_MODEL;
if (a.requires_replay_on_recovery != b.requires_replay_on_recovery)
return X_RECOVERY_MODEL;
if (a.reset_scope_model != b.reset_scope_model) return X_RESET_SCOPE;
// PROGRESS: if either marks a class progress-critical, the PEER must
// actually reserve for it (22.3 §17).
if (|a.tc_progress_critical && !b.provides_progress_reserve)
return X_PROGRESS_RESERVE;
if (|b.tc_progress_critical && !a.provides_progress_reserve)
return X_PROGRESS_RESERVE;
// CONFIGURATION OWNERSHIP: exactly one (§11).
if (!a.is_config_owner && !b.is_config_owner) return X_NO_CONFIG_OWNER;
if (a.is_config_owner && b.is_config_owner) return X_TWO_CONFIG_OWNERS;
if (a.cfg_version != b.cfg_version) return X_CFG_VERSION;
// THE SYSTEM REQUIREMENT — a pair can be mutually compatible and still
// unusable for THIS product.
if ((a.protocol_caps & b.protocol_caps & req.needed) != req.needed)
return X_SYSREQ_PROTOCOL;
if (min16(a.max_outstanding, b.max_outstanding) < req.min_outstanding)
return X_SYSREQ_OUTSTANDING;
// RISKS change the plan, not the answer.
if (!a.has_peer_model || !b.has_peer_model) return RISK_NO_PEER_MODEL;
if (max16(a.errata_rev, b.errata_rev) > req.errata_tolerance)
return RISK_ERRATA;
return COMPAT_OK;
endfunctionArchitecture. A pure predicate over two capability records and a system requirement, returning one of thirteen named outcomes.
State. None — so it runs offline over a catalogue of candidate parts.
Event. Evaluated at selection, long before silicon; re-run whenever a capability revision changes.
Contract. Three checks are agreement checks rather than intersection checks — reliability owner, recovery model, reset scope. Those cannot be negotiated to a lowest common denominator; the two sides must mean the same thing, and §18 and §19 are what happens when they do not.
Failure. Returning a boolean collapses thirteen findings into one symptom. And omitting the req input produces pairs that are mutually compatible and useless for the product — which is a real outcome when a part is selected on interface conformance alone.
DV/debug. The two RISK_* results are the commercially useful ones: they do not block the pairing, they change the verification plan and the contract terms. A pairing with no peer model on either side is buildable and is a different project (24.3 §16).
11. Wrong RTL — Distributed Self-Configuration
// WRONG — each block observes the configuration write and applies it locally.
// Every one of these is locally reasonable.
always_ff @(posedge clk) begin
if (cfg_write && (cfg_addr == ADDR_LINK)) link_mode_q <= cfg_data;
if (cfg_write && (cfg_addr == ADDR_ROUTE)) route_q <= cfg_data;
if (cfg_write && (cfg_addr == ADDR_REL)) reliability_q<= cfg_data;
if (cfg_write && (cfg_addr == ADDR_TC)) tc_map_q <= cfg_data;
endThe failure:
| Cycle | Die A | Die B | Traffic |
|---|---|---|---|
| 1,000 | firmware writes the TC map | — | — |
| 1,001 | A applies the new TC map | still old | — |
| 1,002 | firmware writes reliability | A: new TC, old reliability | a transfer arrives |
| 1,002 | A classifies under the new map | B interprets under the old | misclassified |
| 1,004 | A applies reliability | B applies TC map | — |
| 1,006 | — | B applies reliability | consistent again |
Five properties.
Every write is correct and the sequence is the defect. No block did anything wrong locally.
A misclassified transfer is worse here than a dropped one, because the traffic-class map decides which queue and which reserve it uses (22.3 §13) — so a progress-critical transfer can lose its reserve and deadlock the pair.
The window spans both dies, so it is longer than the single-die version and load-dependent — the hardest class to reproduce.
And there are two defects, not one: no single owner (§7), and no atomic commit (§12). Fixing only the commit still leaves four blocks deciding independently.
The ownership model is the first fix: one config owner (is_config_owner, §9), each die validates against its own capability, both prepare, and only the owner commits.
12. RTL — Atomic Commit
// CORRECTED. One owner, shadow-validate-quiesce-commit, one epoch.
typedef struct packed {
logic [7:0] link_mode;
logic [7:0] tc_map;
logic reliability_owner;
logic [7:0] route_sel;
} cfg_t;
cfg_t requested_q; // written by firmware — NEVER read by datapath
cfg_t candidate_q; // proposed, validated, not yet in effect
cfg_t active_q; // the ONLY thing the datapath reads
logic [7:0] cfg_epoch_q;
logic validated_q, prep_local, prep_peer, commit_fire;
// A commit requires: validated, BOTH sides prepared, and nothing outstanding.
// Committing with work in flight leaves those objects running under the OLD
// configuration while the new one is active (22.5 §11).
assign commit_fire = commit_req && validated_q && prep_local && prep_peer
&& (outstanding_q == '0);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
active_q <= CFG_SAFE_DEFAULT;
cfg_epoch_q <= '0;
validated_q <= 1'b0;
end else begin
// Any new request INVALIDATES a prior validation, so a late write cannot
// ride in on an earlier approval.
if (cfg_write) validated_q <= 1'b0;
else if (validate_req) validated_q <= cfg_is_consistent(candidate_q);
else if (commit_fire) begin
// THE WHOLE CONFIGURATION MOVES IN ONE CYCLE. Committing fields
// separately is §11.
active_q <= candidate_q;
cfg_epoch_q <= cfg_epoch_q + 8'd1;
validated_q <= 1'b0;
end
end
end
// MANDATORY. English: the active configuration changes only on a validated,
// mutually-prepared commit at quiescence. Non-overlapping implication because
// the preconditions must have held in the cycle the commit was accepted, not
// when its effect appears. Fires at the cycle of §11's partial application.
a_cfg_atomic: assert property (
@(posedge clk) disable iff (!rst_n)
$changed(active_q)
|-> ($past(commit_fire) && ($past(outstanding_q) == '0))
);
// MANDATORY. English: an event carrying a stale epoch is rejected, not applied.
// Catches a straggler being interpreted under a configuration that was not
// live when it was issued (21.6 §11).
a_stale_epoch_rejected: assert property (
@(posedge clk) disable iff (!rst_n)
(rx_fire && (rx_cfg_epoch != cfg_epoch_q)) |-> rx_rejected
);Architecture. Four configuration states, one owner, one commit that moves everything, and a monotonic epoch.
State. Three cfg_t registers, the epoch, a validation flag and two prepare bits.
Event. commit_fire requires four conditions. The epoch increments exactly once, which is what lets any later event be attributed to the configuration it ran under.
Contract. outstanding_q must count every outstanding obligation across every class (22.2 §14). A quiesce that drains one class commits with work still in flight under the old rules.
Failure. §11. Also: committing without prep_peer produces a one-sided commit — the same failure with a longer window and a remote victim.
DV/debug. cfg_epoch in every trace event (21.7 §16) is what makes a cross-reconfiguration trace interpretable. Without it a straggler is indistinguishable from a peer violation.
13. Reset and Recovery Ownership
| Question | Must be answered explicitly |
|---|---|
| who initiates? | one named initiator — both or neither deadlocks (22.5 §4) |
| what scope? | link / function / die / package — four different actions |
| what state clears? | transport state, yes; semantic obligations, no (25.3 §16) |
| what survives? | outstanding identities, coherence state, device ownership |
| how does the peer know? | an observable event, not an inference |
| what happens to outstanding work? | retain, or replay — never silently drop |
| how is software informed? | a status path plus the first-fault evidence (25.9 §21) |
And the sixth row is §18. It is a single field in §9's capability record, it is easy to leave implicit, and the failure it produces is owned by nobody.
14. The Firmware Contract
| Firmware needs | Hardware must provide |
|---|---|
| capability discovery | a readable capability record (§9) |
| configuration ownership | one owner, and a commit that is observably atomic (§12) |
| error and status | classes with defined severity, not raw codes |
| recovery command and status | an initiate path and an observable completion |
| first-failure evidence | a sticky register that firmware must not clear accidentally (25.9 §11) |
| version compatibility | enough to run §10's predicate at runtime |
15. The Package Contract
| Agreed with the package team | Why it is an integration item |
|---|---|
| die placement and adjacency | bounds which boundaries are even possible |
| bump availability and die edge | bounds how wide a boundary can be |
| power delivery per die | a die's budget is a partition input |
| thermal placement | hot dies cannot be arbitrarily co-located |
| test access | what is probeable pre- and post-package (§6) |
| link budget ownership | who signs off that the channel meets the PHY's needs |
| channel characterisation | the evidence behind that signoff |
And the link-budget row is the one that needs a name early. It sits between the PHY team and the package team, and if neither owns it, it is discovered at first silicon — which is the most expensive possible time.
No physical figure is asserted here (§4). The architectural point is that each row needs an owner.
16. The Verification and Interoperability Contract
Before tape-out:
| Test | Establishes |
|---|---|
| endpoint tests against a contract-derived peer model | our side is correct independently (24.3 §16) |
| cross-die tests | the pair works in the modelled configurations |
| fault and recovery with work outstanding | §18's contract (25.8 §16) |
| configuration matrix sweep | every negotiated combination, not just the default |
| version-mismatch tests | the predicate rejects rather than mis-negotiates (§10) |
| long-duration stress | slow leaks and wrap conditions (21.4 §34) |
| assertions + scoreboard + coverage crosses | 25.8 §18 · §19 |
And the peer-model row carries the most risk. If our peer model is built from the other team's RTL, we verify against their interpretation including its bugs (21.6 §24) — and §18 becomes undetectable pre-silicon, because both models share the misunderstanding.
17. The Bring-Up Plan
Each stage needs pass/fail evidence, not a subjective judgement.
| # | Stage | Pass evidence |
|---|---|---|
| 1 | power, clocks, reset | clocks measurable; reset cause register as expected |
| 2 | sideband / basic visibility | a register read returns a known value |
| 3 | training | link reaches ACTIVE; no TRAINERROR in history |
| 4 | negotiated configuration | active config matches the requested one — and if not, that is the finding (21.7 §38) |
| 5 | basic traffic | accepted count rises; completions retire; outstanding returns to zero |
| 6 | sustained traffic | credit recovers to full each round trip (25.6 §19); staged counters reconcile |
| 7 | retry / error injection | retry counters rise; bytes_unique unaffected; no duplicate delivery |
| 8 | recovery with work outstanding | outstanding set preserved or replayed; zero orphan completions — §18 |
| 9 | software path | discovery, configuration, error reporting, first-fault dump |
| 10 | stress and duration | no slow leak; no counter wrap; no drift |
Three properties.
Stage 4 is a measurement, not a formality. A link that trains to a lower configuration than requested passes stage 3 and fails stage 4 — and reading it as a pass is what produces the 58%-of-expected bandwidth report (21.7 §38).
Stage 6's evidence is recovery to full, not just "traffic flows." Monotonic credit decline at this stage is 25.9 §7's trace.
And stage 8 is where §18 is caught if it was not caught pre-silicon. Zero orphan completions is the specific evidence, and it requires the correlation instrumentation to exist — which is a phase-1 decision.
18. Flagship — the Package Fails and Neither Die Is Wrong
Two dies. Each passes its own full regression. The package fails after a recovery.
| Die A | Die B | |
|---|---|---|
| interpretation of a link recovery | transport-only — obligations survive | semantic reset — discard and start clean |
retains_across_recovery | implicitly assumed 1 | implicitly assumed 0 |
| documented? | in a design review slide | in a different design review slide |
| own regression | passes | passes |
| link conformance | passes | passes |
The timeline:
| Cycle | Event |
|---|---|
| 1,000 | A issues semantic operation X; B accepts it; a completion is owed |
| 1,050 | a link event occurs; recovery begins |
| 1,090 | recovery completes successfully — link ACTIVE, CRC clean |
| 1,091 | B discards X's obligation — its documented behaviour |
| 1,091 | A retains X — its documented behaviour |
| 1,092 | A waits. No error. No fault. The link is healthy |
| 4,000 | A's timeout fires and frees X's identity |
| 4,010 | a new operation takes the same identity |
| 4,260 | a straggler for X's old use arrives and matches the new one |
| 4,260 | the new operation is retired without ever completing — silent corruption |
Six readings, and this is the story to tell.
Neither supplier violated anything. Both documented their behaviour; nobody compared the two documents — which is the entire failure.
Every transport instrument is clean. CRC passed, the link is ACTIVE, retry counters are normal (23.3 §14) — so a waveform of the link shows nothing.
Cycle 1,092 is a silent hang and cycle 4,260 escalates it to wrong data, prevented by generation matching (25.4 §12).
Pre-silicon detection required two things, and both are integration decisions rather than DV effort: §10's predicate, which returns X_RECOVERY_MODEL before either RTL exists, and a contract-derived peer model (§16) rather than one built from the other team's RTL — because a model built from B's RTL would share B's assumption.
Post-silicon detection is stage 8 (§17): zero orphan completions under recovery-with-outstanding-work.
And the ownership answer is the senior part. "Whose bug is it?" — neither die's. It is the recovery-retention row of §7's matrix, owned by the protocol architect, and it was never filled in. That is what "named owner" in §2 buys.
19. Flagship — the Versions "Match"
Compatibility metadata says both sides are at the same version. Integration fails with data corruption.
| Die A | Die B | |
|---|---|---|
cfg_version | 7 | 7 — "compatible" |
uses_adapter_retry | 1 — relies on the Adapter's CRC and retry | 0 — runs raw |
supplies_own_integrity | 0 | 1 |
| each side in isolation | correct | correct |
Four readings.
The link works and is unprotected in one direction. A carries no integrity of its own and assumes the Adapter provides it; B does not use the Adapter's reliability. Traffic flows; a marginal channel corrupts it.
The symptom is corruption with a legal protocol trace (22.2 §13) — which sends the investigation to signal integrity, where the channel is within spec.
A single version number cannot express this (22.5 §10): equality of one integer says nothing about mandatory features, dependencies or optional behaviour. This is why §10 is a predicate over thirteen outcomes rather than a comparison.
And X_RELIABILITY_OWNER catches it at selection (§10), before silicon — including the harder case where both sides expect the other to supply integrity, which the second clause of that check exists for.
20. Whiteboard Exercise
A senior walkthrough, condensed:
Lead with contracts and owners, not a block diagram. Three rows you own personally: link profile, reset scope, configuration ownership (§7).
Insist on four capability fields the supplier is least likely to volunteer: retains_across_recovery, uses_adapter_retry, is_config_owner, tc_progress_critical — because §18, §19, §11 and 22.3 §17 are exactly those four fields being implicit.
Demand a contract-derived peer model (§16), and treat its absence as a RISK_NO_PEER_MODEL that changes the plan rather than a blocker.
Then bring-up with evidence per stage (§17), and name stage 4 and stage 8 as the two that catch the expensive failures.
And close on §18 — the failure that is neither die's bug — because it is the argument for the whole contract matrix in one story.
21. Weak Answers
| The answer | Why it is weak |
|---|---|
| "We'd integrate the RTL and run the regression." | answers a smaller question; no contracts, no owners, no bring-up |
| "UCIe makes it interoperable." | 22.5 §4 — the link is one row of §7's matrix |
| "The versions match, so they're compatible." | §19 — equality of one integer expresses nothing |
| "Each block can apply its own configuration." | §11 — one owner, atomic commit |
| "Reset clears everything and we start again." | §13 — semantic obligations must survive or be replayed |
| "We'd test recovery by injecting it and checking the link returns." | 25.8 §16 — proves retraining, not the contract |
| "Firmware can figure out the configuration." | §14 — discovery needs a hardware capability record |
| "We'll debug it when we get silicon." | 21.7 §4 — observability cannot be added afterwards |
22. Controlling the Next Question
| Close with | Invites | Which is |
|---|---|---|
| "…and the failure I'd design against is one that's neither die's bug." | "such as?" | §18 — the best story in Module 25 |
| "…compatibility is a predicate, not matching version numbers." | "what would you check?" | §10 + §19 |
| "…exactly one die owns configuration." | "what if both think they do?" | §11 + §12's atomicity |
| "…every contract needs a named owner." | "which ones do you own?" | §7's three integration-lead rows |
And the first row is the strongest hook in the chapter, because "neither die's bug" is counter-intuitive, and the follow-up lands on a ten-cycle timeline where every instrument is clean and the data is wrong.
23. Understanding Check
24. Summary
Five things.
Integration is contract management (§2). Explicit, versioned, testable, owned — and the failures trace back to whichever of those four was missing.
The contract matrix is the artefact (§7). Twelve rows, each with an owner and a silicon observable, because a contract you cannot check after tape-out is documentation.
Compatibility is a predicate over thirteen outcomes (§10), and three of its checks are agreement checks that no version number can express (§19).
One configuration owner and an atomic commit (§11, §12). Distributed self-application leaves two dies interpreting the same bytes differently, and the window spans the package.
And the defining failure is nobody's bug (§18): two correct dies, a clean link, a silent hang that becomes corruption — prevented by one capability field and a contract-derived peer model.
25. Module 25 Complete
| Ch | The question | What it added |
|---|---|---|
| 25.1–25.2 | what is it, why did it happen | answer structure; selection over recall |
| 25.3 | walk the stack | responsibility boundaries; three identities |
| 25.4 | trace Streaming end to end | acceptance is not offering |
| 25.5 | CXL over UCIe | semantics vs transport; retry is not reissue |
| 25.6 | credit flow control | ownership, not counters |
| 25.7 | partition an SoC | scope before drawing; dependency depth |
| 25.8 | design the environment | independence of the predictor |
| 25.9 | debug a bring-up failure | first divergent boundary |
| 25.10 | integrate into a product | contracts with named owners |
And the through-line across all ten is one habit: every chapter's hardest failure was something true that nobody wrote down — an acceptance event assumed, an identity reused, a credit's ownership implied, a recovery's scope unstated, a predictor's input unexamined, a contract unowned. Making assumptions explicit is not documentation discipline. It is the engineering.