PCIe · Module 30
Architecture Checklist — The Gate Before the Gates
If two competent engineers can read the architecture and implement incompatible behaviour, the review has failed. 46 sign-off questions, each with the evidence that satisfies it and the failure that escapes when it is skipped.
Module 29 traced six systems and every failure traced back to something nobody wrote down. This module is the counter-measure: four gates that ask whether a design is ready, rather than what it does. This is the first, and it runs before RTL is considered mature.
1. What This Gate Owns — and What It Must Not Steal
If two competent engineers can read the architecture and implement incompatible behaviour, the architecture review has failed.
That is the entire test. Not "is the architecture good" — a judgement nobody can adjudicate in a room — but "is it decisive": does it resolve the choices that, left open, produce two implementations that both look correct and do not interoperate.
| This gate owns | This gate does not own | Owned by |
|---|---|---|
| contracts — who owns what state, for how long, visible to whom | line-level RTL correctness | 30.2 |
| the declaration of performance targets and assumptions | whether they are met | 30.5 Performance Checklist |
| the verification handoff — what must be provable | whether verification is closed | 30.3 |
| the SoC-facing contracts the subsystem asserts | whether the SoC honours them | 30.4 |
| naming the observable state debug will need | debug procedure | 30.6 Debug Checklist |
Three readings.
Stealing a later gate's job is the most common way this review goes wrong. An architecture review that argues about a counter's width has stopped doing architecture. The discipline is to record the contract — "outstanding count must not saturate below the stated tag maximum" — and let 30.2 check the arithmetic.
And the reverse failure is worse. A performance question deferred to 30.5 is fine only if the assumption is written down; deferring an undeclared assumption means 30.5 will have nothing to verify against and will pass by default (§10).
This chapter does not re-teach any mechanism. BARs, credits, Completions, ordering, LTSSM, DMA and interrupts each have deep chapters, cited throughout. The checklist asks whether your architecture has decided about them.
2. Disposition Semantics — Say What You Mean
| Verdict | Means | Requires |
|---|---|---|
| PASS | the contract is explicit, owned, and independently implementable | the evidence named in the row |
| CONDITIONAL PASS | a bounded, named, owned gap with no correctness impact | the gap written down, an owner, a named later gate, and a stated bound |
| FAIL | a competent implementer could reasonably choose wrong | — |
Three readings.
Conditional pass must not become a polite way to record a failure. It is legitimate exactly when the gap is (a) bounded — you can state its size, (b) owned — a named person, (c) scheduled — a named later gate, and (d) correctness-neutral. "Performance margin not yet demonstrated; assumption is 1.5 : 1 oversubscription with non-concurrent peaks; owner: platform architecture; closes at 30.5" is a conditional pass. "We'll figure out reset later" is a FAIL wearing a conditional pass's clothes — it is unbounded and it is a correctness question.
A FAIL is not an insult and should not be softened. The cost of a fail at this gate is a meeting; the cost of the same issue found at 30.4 is a schedule; in silicon it is a respin. Reviewers who feel social pressure to avoid the word will produce a checklist that certifies everything.
And "standard PCIe behaviour" is an automatic FAIL as an answer, every time. It names no layer, no contract and no decision. The follow-up is always: which mechanism, in which chapter, and what did you choose where the mechanism permits choices?
3. Ownership Seams
The four boxes on the right are where reviews fail. They cross every horizontal boundary, so no single team owns them — and state with no owner is state with no lifetime, which is §5's fail criterion.
4. The Requirement → Owner → Evidence Matrix
The core artefact this gate produces. A requirement written as a capability is not reviewable; written as a contract with a lifetime, it is.
| Requirement | Owner | State | Event | Reset lifetime | External contract | DV owner | Silicon observable | Disposition |
|---|---|---|---|---|---|---|---|---|
| A tag is never reused while its request is live | requester | tag-live bitmap + generation | alloc on accept, free on retire | survives link Recovery; cleared on function reset | completer may return a Completion any time before timeout | checker + formal | tag map readable | PASS |
| Completions are correlated by tag, not arrival order | completer | per-tag context, bytes remaining | Completion accepted | as above | split Completions permitted (13.3) | scoreboard | outstanding count | PASS |
| Outstanding limit is a declared number with a derivation | architecture | tag count | — | — | bandwidth-delay product (29.2 §5) | perf model | high-water mark | PASS |
| Descriptor ownership transfers at exactly one defined point | sw + DMA | ownership bit / index | descriptor written back | undefined ⇒ FAIL | driver contract | scoreboard | ring indices | FAIL if unstated |
| First fault is sticky until explicitly cleared | error logic | first-fault register + valid | first qualifying error | survives Recovery | software reads then clears | negative test | the register | PASS |
| "Tags handled correctly" | — | — | — | — | — | — | — | FAIL — not a contract |
Three readings.
Compare row 1 with the last row. "Tags handled" is a topic; "a tag is never reused while its request is live" is a falsifiable statement with an owner, an event, and a reset lifetime. Only the second can be implemented identically by two teams, and only the second can be verified.
The "Silicon observable" column is not decoration. A contract that cannot be observed in silicon cannot be debugged in silicon, and a blank cell there is a finding — §11 makes it a checklist item.
And the "Reset lifetime" column is where most rows first go blank, which is exactly why §6 gives it a dedicated matrix. A blank cell there is a FAIL, not an omission, because §7 shows what a blank cell costs.
5. Architectural State Inventory
Rule: if state exists and its owner or lifetime is undocumented, the gate FAILS. Not "note it for later" — fail, because every Module 29 failure was undocumented state.
| State | Must declare | The failure when it is missing |
|---|---|---|
| live requests / outstanding count | owner, max, saturation behaviour | 29.2 §12: a window that binds invisibly |
| tags | allocation event, lifetime, reuse rule, generation | §9 and 30.2: stale-Completion misretirement |
| BAR / configuration | active vs requested vs supported | mid-traffic partial update (30.2) |
| queue ownership and occupancy | who inserts, who retires, bound | 29.3 §5: overflow with no safe threshold |
| credits | consumption and return points | 22.3 · 25.8 |
| DMA descriptors | ownership handoff point | 29.x's producer-consumer class of bug |
| completion correlation context | bytes remaining, status accumulation | 13.4: misassembled data |
| interrupt state | pending, masked, coalescing | 19.5 |
| retry / recovery state | what survives Recovery (18.5) | §7 |
| timeout state | who starts it, who owns the reaction | 25.7 |
| generation / epoch | width derivation, increment event | 29.5 §8: a stale grant matching |
| error status | sticky vs last-wins, clear protocol | first-fault loss (§4 row 5) |
And the review question for each row is one sentence: "who owns it, what event changes it, which resets clear it, and can software or a debugger see it?" Four answers. A row that cannot produce all four is not ready.
6. The Reset and Recovery Matrix
The single strongest artefact this gate produces, and the one most often absent.
| State | Link Recovery (18.5) | Hot Reset (18.10) | Function-level reset | Local block reset | Peer-visible? | SW-visible? |
|---|---|---|---|---|---|---|
| live request / tag table | retain — the request is still outstanding | discard + report | discard | must not differ from function reset | yes — peer may still complete | count |
| credits | re-established by the link | re-established | n/a | n/a | yes | no |
| BAR / configuration | retain | per architecture | discard → re-enumerate | retain | yes | yes |
| DMA descriptor position | retain | discard + report | discard | ambiguous ⇒ FAIL | no | yes |
| first-fault register | retain — this is the point | retain if possible | discard | retain | no | yes |
| interrupt pending | retain | discard | discard | retain | yes | yes |
| performance counters | retain, with an epoch bump | discard | discard | retain | no | yes |
Three readings.
Row 1's "peer-visible" cell is the one that changes designs. A local decision to discard live requests is not local: the peer does not know, and its Completions are still coming (10.4). Whatever you discard, something must absorb the arrivals — which makes this an architecture decision, not an RTL one.
The first-fault row deliberately retains across Recovery, because Recovery is frequently a consequence of the fault being investigated. A design that clears its evidence during the event it should be recording is the debug failure 25.1 exists to prevent.
And the "ambiguous ⇒ FAIL" cell is the template for the whole matrix. A blank is not neutral. Every blank cell is a place two engineers will choose differently, which is §1's test failing.
7. Wrong Architecture — "Reset Clears Everything"
The sentence sounds rigorous and decides nothing. Which reset?
| Interpretation | What it would clear | Consequence |
|---|---|---|
| local block reset | this block's registers | peer still holds live requests |
| link Recovery | nothing should be cleared | clearing here orphans live work |
| function-level reset | this function's state | siblings unaffected |
| platform reset | everything | the machine |
Failure — the timeline. A design reads "reset clears everything" and clears the tag table on the local reset that a Recovery event also triggers.
| Time | Event | Tag table | Peer | Consequence |
|---|---|---|---|---|
| 0 | 24 requests outstanding, tags 0–23 | 24 live | 24 Completions pending | steady |
| 1 | transient — link enters Recovery (18.5) | 24 live | still pending — the peer never saw a reset | — |
| 2 | local logic clears the table | 0 live | still pending | live work orphaned |
| 3 | link returns to L0 | 0 live | begins delivering | — |
| 4 | Completion for tag 7 arrives | tag 7 not live | — | dropped, or worse, accepted |
| 5 | tag 7 reallocated to a new request | tag 7 live (new) | — | the stale Completion now matches |
| 6 | new request retires on old data | — | — | silent data corruption |
| 7 | no error is reported anywhere | — | — | the link "recovered successfully" |
First divergence: step 2 — clearing state whose peer was not reset.
Root cause. Reset scope was expressed as a slogan rather than a matrix. §6's row 1 says retain across Recovery, and one cell of one table prevents the whole sequence.
And step 5 is why a generation field is an architecture decision, not an implementation detail. With a generation (29.5 §8), step 5's stale Completion cannot match and is counted instead. Without one, tag reuse alone is not enough to keep it out, and 30.2 will have no basis to require it because the architecture never asked.
8. RTL — Making the Contract Reviewable
// ILLUSTRATIVE. The point of writing an architecture contract as a type is that
// blanks become impossible: every field here is a decision someone had to make,
// and a struct with a TODO does not compile.
typedef struct packed {
logic live; // allocated and not yet retired
logic [7:0] tag; // the identity the peer will echo
logic [3:0] generation; // distinguishes THIS use of the tag from the last
logic [1:0] req_class; // bulk / stream / progress — 29.6's classification
logic [7:0] cfg_epoch; // which active configuration this was issued under
logic [1:0] fault_domain; // what a scoped reset may and may not retire
logic [15:0] bytes_left; // remaining, for split Completions (13.3)
logic [1:0] status_acc; // accumulated Completion status
} req_ctx_t;
req_ctx_t ctx_q [N_TAG];Architecture. Eight fields, and each one exists because a specific Module 29 or Module 25 failure happened without it. The struct is a review instrument: reading it aloud forces eight decisions.
State. One context per tag. generation and cfg_epoch are the two fields teams omit, and both are stale-event defences — the first against a late Completion (§7), the second against a configuration change mid-flight.
Event. live is set on acceptance (valid && ready), never on offering — 30.2 makes that its own gate. It clears on retirement, meaning the last Completion for the request was consumed, not on the first.
Contract. bytes_left and status_acc together encode that a request may be answered by several Completions (13.3) and that status must accumulate rather than last-write-win. If the architecture does not state which, two implementations will differ on a partially-failed transfer.
Failure. Drop generation → §7's step 5. Drop fault_domain → 29.6 §14's over-wide reset with no way to express containment. Drop cfg_epoch → a request issued under one configuration retired under another.
DV/debug. This struct is the scoreboard's model (30.3 §3), and making it explicit at architecture time means DV and RTL build against the same object rather than two similar ones.
9. Wrong Architecture — Ordering by Queue Position
The architecture says: "Completions return in order." No evidence is attached. RTL implements FIFO matching — the cheapest thing consistent with the sentence.
| Step | What the architecture assumed | What can happen |
|---|---|---|
| 1 | requests A, B issued (tags 3, 9) | — |
| 2 | Completions arrive in order | B's may arrive first (13.4) |
| 3 | FIFO pops the head → attributes B's data to A | wrong data, both requests |
| 4 | both retire "successfully" | no error |
Three readings.
This is an architecture failure, not an RTL failure, and that distinction is the point of running this gate first. The RTL faithfully implemented an unqualified sentence. The gate's job was to demand the evidence — which mechanism guarantees this, under what conditions, and what happens when they do not hold?
The fail criterion is generic and reusable: an ordering claim without a cited mechanism and a stated scope is a FAIL. Correlate by identity, and let ordering be an optimisation you can prove separately.
And note the shape it shares with §7: both are stale or mismatched correlation, and both are prevented by the same architectural instinct — match by identity, not by position or timing.
10. Performance Assumptions — Declared Here, Closed Later
This gate does not close performance. It ensures 30.5 has something to test against.
| Must be declared | Why, if omitted |
|---|---|
| target workload, concretely | "fast" is not testable; 30.5 measures the wrong thing |
| target useful throughput — post-encoding, retries excluded | 29.2 §4: comparing to a raw rate double-counts encoding |
| which flows are latency-sensitive | 29.6 §4: the small flow with the deadline is invisible in a bandwidth table |
| outstanding requirement, with its derivation | 29.2 §5: the tag count is derivable — rate × latency ÷ payload |
| oversubscription and the concurrency claim | 29.6 §5: the ratio is fine; the unstated bet is not |
| buffer headroom and its burst bound | 29.3 §5: depth alone is not a specification |
| what may be traded under contention | otherwise the first contention incident is an argument, not a decision |
Two readings.
Row 4 is the one to insist on, because it is arithmetic and therefore settleable in the room. "64 tags" is a preference; "64 tags, because 16 GB/s × 1 µs ÷ 256 B = 62.5, rounded up" is a derivation someone can check — and can recheck when the payload size changes.
And row 5 is what turns 29.6's flagship failure into a preventable one. The concurrency claim — "the workload never activates all three at peak simultaneously" — is cheap to write and it is the difference between a later incident being a known accepted risk and a surprise.
11. Observability Is Architecture
Rule: for every risk the architecture identifies, name the state that would let someone diagnose it in silicon. A risk with no observable is a risk with no plan.
| Known risk | Required observable | Cost |
|---|---|---|
| tag exhaustion limits throughput | outstanding high-water mark | one register |
| a stale event was accepted | stale-event counter | one counter |
| a queue nearly overflowed | occupancy high-water (29.4 §7) | one register |
| an error occurred and was overwritten | first-fault sticky + valid | one register + a bit |
| a class is starved | per-class delivered + starvation max (29.6 §6) | counters per class |
| recovery happened and nobody knows why | recovery reason + count | one register |
| a measurement spans a config change | epoch stamp (29.6 §13) | one counter |
| "did this ever happen?" | a sticky bit | one flop |
Two readings.
Every entry in the cost column is trivial, and every one replaced a multi-week investigation in Module 29. 29.5 §14's conclusion stands as the general rule: instrument whatever could not be reconstructed afterwards.
And the review question is not "is there debug logic" but "which of our named risks does it observe?" A design with rich generic tracing and no first-fault register has not addressed the risk it identified.
12. Worked Dispositions
PASS. Tag lifetime stated (allocate on acceptance, free on retirement of the final Completion); generation field with a width derivation; reset matrix complete for all four reset types; software ownership of descriptors defined at a single handoff point; checker strategy assigned to DV with named assertions. — Every cell in §4 is filled and each is falsifiable.
CONDITIONAL PASS. Performance margin not yet demonstrated. The declared assumption is 1.5 : 1 oversubscription on the shared upstream with non-concurrent peaks, derived from the stated workload; no correctness impact; owner named; closes at 30.5. — Bounded, owned, scheduled, correctness-neutral.
FAIL. Recovery semantics undefined while outstanding requests may exist. — §7. A correctness question, unbounded, with a silent-corruption failure mode.
FAIL. Software/device ownership of descriptors ambiguous. — Two teams will pick opposite handoff points and both will be self-consistent.
FAIL. "Standard PCIe behaviour." — §2. Names no layer, no mechanism, no decision.
FAIL. Ordering asserted without a cited mechanism. — §9.
13. The Architecture Checklist — 46 Questions
Each row: the question, why it matters, the evidence that satisfies it, and what makes it a FAIL. Weak evidence is called out where it is the common trap.
Role and topology
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 1 | Is the device an endpoint, root, switch or bridge, and is that stated once and consistently? | every downstream contract depends on it (2.3 · 2.4) | a role statement with its implications enumerated | the role is implied by the block diagram only |
| 2 | How many functions, and what is shared between them? | shared state across functions is a reset and isolation question | per-function state list | "one function for now" without stating what changes if not |
| 3 | Where does this sit in the intended topology, and what else shares its upstream path? | 29.6 §4: rivals are not neighbours | a competition graph, not just a connectivity diagram | only connectivity is documented |
| 4 | Is peer-to-peer traffic assumed, and on what basis? | platform, routing and software policy all bear on it | an explicit statement with its dependencies | assumed because two endpoints exist |
Transaction semantics
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 5 | Which transaction classes are generated, and which are only consumed? | defines requester vs completer duties (10.1) | a per-class table with direction | "supports memory transactions" |
| 6 | Posted vs non-posted responsibilities: what does the device issue and what must it answer? | 10.3 · 10.4 | a matrix by class | one word answers |
| 7 | What is the maximum outstanding non-posted count, and how was it derived? | it sets achievable bandwidth (29.2 §5) | the arithmetic | a round number |
| 8 | Can a request be answered by multiple Completions, and how is that handled? | 13.3 | bytes_left + status accumulation in the contract (§8) | assumed one-to-one |
| 9 | How is Completion status accumulated across a split? | last-wins vs sticky changes the reported result | a stated rule | unstated |
| 10 | What happens to a Completion with no matching live request? | §7's step 4 | counted, reported, never applied | "cannot happen" |
| 11 | Is there a Completion timeout, who starts it and who reacts? | 25.7 | owner + reaction + reporting | timeout exists, reaction unspecified |
| 12 | What ordering is assumed, by what mechanism, in what scope? | §9 | a citation and a scope | an unqualified sentence |
Addressing and BARs
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 13 | What is each BAR's size, type and alignment, and what does it expose? | 9.1 · 9.4 | a per-BAR map | "standard BAR setup" |
| 14 | What happens to accesses in unimplemented regions of a BAR? | silent aliasing is a real and confusing failure (25.5) | a stated response | undefined |
| 15 | Which registers are safe to access while traffic is live? | §7's cousin — a mid-flight config change | a per-register statement | all-or-nothing |
| 16 | Does the software-visible map match what the driver assumes? | 30.4 inherits this | a single map both teams signed | two documents |
DMA
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 17 | At exactly what point does descriptor ownership transfer? | the producer-consumer class of bug | one named event, both directions | two plausible readings exist |
| 18 | What address space do DMA addresses live in? | 30.4 §5's IOVA failure | an explicit statement | "physical addresses" assumed |
| 19 | How does the device signal completion of a DMA, and is data visible first? | ordering of data vs flag | a stated ordering requirement | the flag is "just a write" |
| 20 | What is the scatter-gather contract — alignment, max length, termination? | 20.4 | a per-field table | inherited from an example driver |
| 21 | What happens to in-flight DMA on each reset type? | §6 | the reset matrix row | blank |
Identity and tags
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 22 | What exact event allocates a tag, and what frees it? | acceptance vs offering (30.2) | valid && ready and final Completion consumed | "when the request is sent" |
| 23 | Is there a generation/epoch, and how was its width derived? | 29.5 §8 | the inequality and its numbers | no generation, or an unjustified width |
| 24 | Can a tag be freed by a local timeout while the peer may still respond? | the §7 hazard in its most common form | a stated policy with a stale-event defence | freed on timeout with no defence |
| 25 | Is the tag space partitioned by class or shared? | partitioning prevents one class exhausting another | a stated policy | unexamined |
Flow control and queues
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 26 | Where are credits consumed and returned? | 16.5 | the two points named | "handled by the controller" |
| 27 | Can one class's queue block another's progress? | 29.6 §9 head-of-line | separate pools, or a stated floor | shared queue, unexamined |
| 28 | What is each queue's depth, and what bounds it? | 29.3 §5: depth alone is not a spec | depth plus the burst or committed-bytes bound | a depth |
| 29 | What is the back-pressure path, and how long does it take to act? | 29.3 §4: back-pressure has latency | the dead time, quantified | "asserts when full" |
| 30 | Is there a deadlock argument for the queue structure? | 25.8 | a dependency-cycle analysis | absent |
Interrupts
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 31 | Which interrupt mechanism, and how many vectors? | 19.2 · 19.3 | a vector map | "MSI-X" alone |
| 32 | Is data guaranteed visible before the interrupt is signalled, and by what mechanism? | the classic producer-consumer inversion | a stated ordering argument | assumed |
| 33 | What is the coalescing/moderation policy and who tunes it? | 19.5 · 26.4 | policy + owner + range | fixed constant, no rationale |
| 34 | What happens to pending interrupts on each reset? | §6 | the matrix row | blank |
Reset, recovery, configuration
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 35 | Is the reset matrix complete for every state item and every reset type? | §6, §7 | the filled matrix | any blank cell |
| 36 | What survives link Recovery, and does the peer agree? | §7 | a retain/discard statement with peer implications | "reset clears everything" |
| 37 | Which resets are software-visible, and what must software do after each? | 30.4 inherits this | a software sequence per reset | hardware-only view |
| 38 | Is configuration applied atomically with respect to live traffic? | a partial update seen mid-flight | shadow/commit with an epoch (30.2) | field-by-field updates |
| 39 | What is the fault domain of this subsystem, and what may a scoped reset retire? | 29.6 §14 | a containment statement | no domain concept exists |
Errors, performance, observability, handoff
| # | Question | Why | Evidence | FAIL if |
|---|---|---|---|---|
| 40 | Is first-fault sticky, and what clears it? | evidence survives the event | a register + clear protocol | last-error-wins |
| 41 | Which errors are fatal, which are reported, which are counted? | escalation policy | a three-way classification | one error bit |
| 42 | Is the target workload stated concretely? | §10 | a workload description | "high performance" |
| 43 | Is useful throughput defined post-encoding with retries excluded? | 29.2 §4 | the definition in writing | compared against a raw rate |
| 44 | Is the oversubscription/concurrency claim written down? | 29.6 §5 | the ratio and the concurrency bet | ratio only, or neither |
| 45 | For every named risk, is there a named silicon observable? | §11 | risk → observable table | rich tracing, no risk mapping |
| 46 | Does every contract in §4 have a named DV owner and a checker strategy? | 30.3 starts here | the DV-owner column filled | "DV will cover it" |
14. Misconceptions
"The architecture is fine, it's all standard." §2: "standard PCIe behaviour" names no layer and no decision. It is an automatic FAIL as an answer.
"We'll define reset behaviour during implementation." §7: the implementation will define it, differently in two places, and the failure is silent data corruption with a successful-looking link recovery.
"A conditional pass keeps things moving." §2: only if the gap is bounded, owned, scheduled and correctness-neutral. Otherwise it is a FAIL that will be discovered later at higher cost.
"Performance isn't an architecture concern." §10: closing it is not, declaring it is — otherwise 30.5 has no target and passes by default.
"Debug features can be added later." §11: each observable costs one register, and adding them after tape-out costs a respin. The risk list already names what to instrument.
"Ordering is guaranteed." §9: by what mechanism, in what scope? Correlate by identity and prove ordering separately.
"Tags are just numbers." §5, §8: a tag without a generation cannot distinguish this use from the last, which is §7's step 5.
"State the requirement, not the implementation." Half right: state the contract — owner, event, lifetime, visibility. A requirement without a lifetime is a topic, not a contract.
15. Understanding Check
Q1. An architecture document says "reset clears everything." Is that a PASS?
FAIL, and it is one of the highest-severity fails available (§7). The sentence sounds rigorous and decides nothing: which reset? Local block, link Recovery, function-level and platform reset have different correct answers, and §6's matrix shows row 1 requires retain across Recovery. The timeline is concrete: a transient puts the link into Recovery, local logic clears a 24-entry tag table, the peer was never reset and its Completions are still coming, tag 7's Completion arrives against a dead entry, tag 7 is reallocated, and the new request retires on the old request's data — silent corruption, with the link reporting a successful recovery. The remedy is one cell of one table, and the deeper point is that a generation field is an architecture decision (§8): without it, tag reuse alone cannot keep a stale Completion out, and 30.2 will have no basis to demand one because the architecture never asked.
Q2. What separates a real CONDITIONAL PASS from a FAIL being softened?
Four properties, all of which must hold (§2): the gap is bounded — you can state its size; owned — a named person; scheduled — a named later gate; and correctness-neutral. "Performance margin not yet demonstrated; assumption is 1.5 : 1 oversubscription with non-concurrent peaks derived from the stated workload; owner named; closes at 30.5" satisfies all four. "We'll figure out reset later" satisfies none — it is unbounded and it is a correctness question, so it is a FAIL. The social dynamic is the real risk: a fail at this gate costs a meeting, at 30.4 it costs a schedule, and in silicon it costs a respin. Reviewers who avoid the word produce a checklist that certifies everything.
Q3. The architecture says "Completions return in order." What do you ask, and whose failure is it if it ships?
Ask for the mechanism and the scope: which mechanism guarantees this, under what conditions, and what happens when they do not hold? (§9). An ordering claim with no cited mechanism and no stated scope is a FAIL. And it is the architecture gate's failure, not RTL's — the RTL faithfully implemented an unqualified sentence by choosing FIFO matching, which is the cheapest thing consistent with it. When Completions for tags 3 and 9 arrive out of order (13.4), the FIFO attributes one request's data to the other and both retire without error. The reusable instinct is the one §7 shares: correlate by identity, never by position or timing, and let ordering be an optimisation proven separately.
Q4. Why does this gate declare performance targets without closing them, and what breaks if it skips the declaration?
Because the gates are ordered by what can be decided versus what can be measured (§1, §10). Closing performance requires an implementation to measure; declaring the target requires only a decision, and 30.5 cannot verify anything without one — a gate with no stated target passes by default, which is the worst possible outcome. Six things must be declared: the concrete workload, useful throughput defined post-encoding with retries excluded (29.2 §4 — comparing against a raw rate double-counts encoding), which flows are latency-sensitive, the outstanding requirement with its derivation, the oversubscription ratio and its concurrency claim, and the buffer headroom with its burst bound.
Two of those are worth insisting on in the room. The tag count is arithmetic — "64 tags because 16 GB/s × 1 µs ÷ 256 B = 62.5" is checkable and re-checkable when payload size changes, whereas "64 tags" is a preference. And the concurrency claim is what turns 29.6's flagship incident from a surprise into a known accepted risk — it costs one sentence.
16. What Comes Next
This gate asked whether the architecture is decisive. The next asks whether the RTL is faithful to it.
30.2 inherits every contract recorded here and checks it against the thing that actually breaks endpoint RTL: not wrong steady-state equations, but wrong ownership transitions when two legal events land in the same cycle.