CXL · Module 5
PCIe Reuse in CXL
Which PCIe structures CXL keeps wholesale, which it extends, which are CXL's own, and which move when PCIe moves — with the engineering obligation each class creates. Five RTL models simulated, eight mutations, eight killed.
Chapter 5.1 argued why the reuse exists: a protocol's merit does not determine whether it gets deployed, and the expensive parts of an interconnect are the parts CXL had no reason to reinvent.
This chapter is the inventory. What, specifically, is reused — and what does each kind of reuse oblige you to do?
1. The Engineering Problem — "Reuse" Is Four Different Contracts
A schedule meeting asks: this PCIe structure is reused, so we can skip it, correct?
The answer depends entirely on what "reused" means for that structure, and there are four distinct answers hiding under one word:
- The structure is identical to PCIe. Existing PCIe verification IP exercises it. You can genuinely skip it.
- The structure has the same shape and does more in CXL. PCIe VIP exercises the shape and none of the extra behaviour. You cannot skip it, and a green PCIe regression is not evidence.
- The structure is CXL's own. PCIe VIP has nothing to say about it. Any claim otherwise is a coverage overclaim.
- The structure tracks PCIe's generation. It was correct last generation and may be wrong this one, whether or not anyone touched it.
Four contracts, four different obligations, and the fourth is the one that ships bugs — because nothing changed in your code, so nothing triggered a review.
2. The One-Sentence Model
Every PCIe structure in a CXL design belongs to exactly one of four reuse classes — reused, extended, CXL-specific, revision-dependent — and the class does not describe the structure, it describes what you still owe it: DV effort, VIP applicability, and whether it must be re-examined every generation.
Call it the obligation, not the description. The classification is only useful if it changes what you do.
3. What This Chapter Owns
| Question | Owned by |
|---|---|
| Why the reuse decision was taken | 5.1 |
| Per-layer inherited / extended / added | 4.5 |
| Which structures, and what each class obliges | this chapter |
| How the two ends agree at bring-up | 5.3 |
| Training and the operating-point space | 5.4 |
| How the host learns what the device supports | 5.5 |
Chapter 4.5 classified layers as inherited, extended or added. This chapter classifies structures, and adds a fourth class 4.5 did not need — revision-dependent — because a structure can be perfectly inherited and still move underneath you.
4. The Four Reuse Classes
| Class | Means | What you owe it |
|---|---|---|
| Reused | byte-for-byte PCIe | nothing — VIP covers it |
| Extended | same structure, extra CXL meaning | CXL DV; VIP covers shape only |
| CXL-specific | no PCIe counterpart | CXL DV; VIP does not apply |
| Revision-dep | follows the PCIe generation | re-examine every gen |
The last column is the one worth memorising. Only one class carries a standing per-generation obligation, and it is the class people forget exists.
5. The Reuse Matrix
| Structure | Class | Owed |
|---|---|---|
| Electricals | reused | none |
| Connector | reused | none |
| LTSSM | reused | PCIe VIP |
| Initial rate | reused | none |
| Ordered sets | reused | PCIe VIP |
| Modified TS | extended | CXL DV |
| Alt-protocol neg | extended | CXL DV |
| Config space | extended | CXL DV |
| Width / rate set | revision-dep | review per gen |
| Flit format | revision-dep | review per gen |
| FEC / CRC | revision-dep | review per gen |
| CXL DVSEC | CXL-specific | CXL DV; no VIP |
.cache / .mem | CXL-specific | CXL DV; no VIP |
Read the right-hand column, not the middle one. Thirteen structures, four obligations, and only three of the thirteen can honestly be skipped on the strength of a PCIe regression.
6. Why Enumeration Is the Most Valuable Single Reuse
Of everything in §5, config-space reuse is the one that pays most, and the reason is ordering.
A host must be able to find and identify a device before it knows anything about it. If CXL had defined its own discovery mechanism, a CXL device in a non-CXL host would be invisible — not degraded, invisible — and Chapter 5.1's dead-pair count would include every host that had not been updated.
Because CXL.io uses PCIe's configuration space, a CXL device presents an ordinary Type 0 header and enumerates on any PCIe host. The CXL-specific information lives in a DVSEC — a structure a CXL-aware host looks for, and a PCIe-only host simply does not read.
That asymmetry is the whole design. Enumeration must not depend on CXL; CXL claims must depend on the CXL structure. RTL 2 makes both directions checkable.
7. The Cost Column — What Reuse Does Not Give You
Inheritance is also coupling, and the bill arrives in three places.
Your roadmap is partly someone else's. Flit format, FEC and CRC machinery follow the PCIe generation. A CXL design cannot independently choose to change them.
Your native operating space is smaller than PCIe's. Public material puts x16/x8/x4 and 32/64 GT/s in the native set, with x2/x1 and 16/8 GT/s degraded. RTL 3 sweeps that grid: over five widths and four rates, 6 of 20 points are native and 14 are degraded. A design that sizes buffers for "whatever PCIe can do" has sized for the wrong set.
Your VIP coverage claim is smaller than it looks. PCIe VIP fully exercises the reused rows and the shape of the extended rows. It has nothing whatsoever to say about the CXL-specific rows. RTL 1 turns that into a checkable claim rather than an assumption in a slide.
8. Teaching-model boundary
9. RTL 1 — What Each Class Obliges You To Do
The classification is worthless as a label. Made into logic, it becomes a claim the design can be held to.
module reuse_classifier (
input logic clk, rst_n,
input logic [1:0] rclass, // REUSED/EXTENDED/CXL_SPEC/REV_DEP
input logic cls_valid,
input logic behaves_as_pcie, // observed: identical to PCIe?
input logic pcie_vip_covers, // claimed: PCIe VIP exercises it
input logic revisited_this_gen,
output logic needs_cxl_dv, needs_regen_review,
output logic reused_but_differs_err, vip_overclaim_err, stale_revision_err
);
localparam logic [1:0] REUSED = 2'd0, EXTENDED = 2'd1,
CXL_SPEC = 2'd2, REV_DEP = 2'd3;
// Anything not purely inherited needs CXL-specific DV.
assign needs_cxl_dv = cls_valid && (rclass != REUSED);
// Only revision-coupled structures must be re-examined each generation.
assign needs_regen_review = cls_valid && (rclass == REV_DEP);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
reused_but_differs_err <= 1'b0; vip_overclaim_err <= 1'b0;
stale_revision_err <= 1'b0;
end else if (cls_valid) begin
// A structure called REUSED that does not behave as PCIe is misclassified.
if ((rclass == REUSED) && !behaves_as_pcie) reused_but_differs_err <= 1'b1;
// PCIe VIP cannot cover a structure PCIe does not have.
if ((rclass == CXL_SPEC) && pcie_vip_covers) vip_overclaim_err <= 1'b1;
// A revision-coupled structure carried forward unexamined.
if ((rclass == REV_DEP) && !revisited_this_gen) stale_revision_err <= 1'b1;
end
end
endmodule class needs_cxl_dv needs_regen_review
REUSED 0 0
EXTENDED 1 0
CXL-SPECIFIC 1 0
REVISION-DEP 1 1Three of four classes need CXL DV. Exactly one carries a per-generation review obligation, and it is the only row where doing nothing is itself a change.
10. RTL 2 — Enumeration Must Not Depend on CXL
Section 6's asymmetry, in two lines that must not be symmetric.
module config_space_overlay #(
parameter bit ASSUME_DVSEC = 1'b0 // 1 = the broken shape
) (
input logic clk, rst_n, probe,
input logic hdr_is_type0, // ordinary PCIe endpoint header
input logic dvsec_present,
input logic [3:0] dvsec_revision,
output logic enumerated, cxl_claimed,
output logic enum_failed_err, claimed_absent_err, old_revision_err
);
localparam logic [3:0] MIN_REV = 4'd1; // teaching value
// Enumeration depends ONLY on the reused PCIe structure. This is the point:
// a CXL device is discoverable by a host that knows nothing about CXL.
assign enumerated = probe && hdr_is_type0;
assign cxl_claimed = enumerated &&
(ASSUME_DVSEC ? 1'b1
: (dvsec_present && dvsec_revision >= MIN_REV));
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
enum_failed_err <= 1'b0; claimed_absent_err <= 1'b0; old_revision_err <= 1'b0;
end else begin
// A well-formed endpoint must enumerate whether or not it is CXL.
if (probe && hdr_is_type0 && !enumerated) enum_failed_err <= 1'b1;
// Claiming CXL from a device that never presented the structure.
if (cxl_claimed && !dvsec_present) claimed_absent_err <= 1'b1;
// Present, but too old to mean what we are about to assume.
if (cxl_claimed && dvsec_present && (dvsec_revision < MIN_REV))
old_revision_err <= 1'b1;
end
end
endmodule PCIe-only device : enumerated=1 cxl_claimed=0 | assume-DVSEC claims=1
CXL device rev1 : enumerated=1 cxl_claimed=1
DVSEC rev0 : enumerated=1 cxl_claimed=0 <-- present but too old
assume-DVSEC variant claimed_absent_err=1Row 1 is the reuse working: a device with no CXL structure at all still enumerates. Row 3 is the subtler case — present is not the same as usable. Public material requires the primary function to carry CXL DVSEC ID0 at Revision 1 or greater, so a structure below that revision does not carry the meaning a host is about to assume from it.
11. RTL 3 — The Native Operating Space Is Smaller Than PCIe's
module degraded_mode_table (
input logic clk, rst_n,
input logic [2:0] width_code, // 0:x1 1:x2 2:x4 3:x8 4:x16
input logic [2:0] rate_code, // 0:2.5 1:5 2:8 3:16 4:32 5:64
input logic sel_valid,
output logic supported, is_native, is_degraded,
output logic unsupported_accepted_err, degraded_called_native_err
);
logic w_native, w_degraded, r_native, r_degraded;
// Publicly described: x16/x8/x4 native, x2/x1 in degraded mode.
assign w_native = (width_code >= 3'd2) && (width_code <= 3'd4);
assign w_degraded = (width_code <= 3'd1);
// Publicly described: 64.0 and 32.0 GT/s native; 16.0 and 8.0 degraded.
assign r_native = (rate_code >= 3'd4);
assign r_degraded = (rate_code == 3'd2) || (rate_code == 3'd3);
assign supported = sel_valid && (w_native || w_degraded) &&
(r_native || r_degraded);
// Native only if BOTH axes are native. One degraded axis degrades the point.
assign is_native = supported && w_native && r_native;
assign is_degraded = supported && !is_native;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
unsupported_accepted_err <= 1'b0; degraded_called_native_err <= 1'b0;
end else if (sel_valid) begin
if ((supported || is_native) && (rate_code < 3'd2)) unsupported_accepted_err <= 1'b1;
if (is_native && (w_degraded || r_degraded)) degraded_called_native_err <= 1'b1;
end
end
endmodule over 5 widths x 4 rates (8..64 GT/s): native=6 degraded=14 unsupported=0
x16 @ 64 GT/s : native=1 degraded=0
x1 @ 64 GT/s : native=0 degraded=1 <-- one axis degrades the point
x16 @ 8 GT/s : native=0 degraded=16 of 20. The AND on the two axes is the reason: a full-width link at a degraded rate is a degraded operating point, and so is a native rate on a degraded width. Mutation M5 replaces that AND with an OR and the native count jumps — which is precisely the mistake a datasheet reader makes when they see "supports x16" and "supports 64 GT/s" as independent claims.
Note also the initial training rate. §4 records CXL starting at 2.5 GT/s, which is below the degraded floor of 8 GT/s. That is not a contradiction: the rate a link trains at and the rate it operates at are different questions. The link comes up at Gen 1 because it must come up before capability is known, then moves to a supported operating rate. Chapter 5.4 is where that distinction becomes the subject.
12. RTL 4 — Extra Fields Exist Only in the Modified Variant
The clearest instance of the extended class: CXL does not invent a bring-up sequence, it uses PCIe's ordered sets in a modified form whose additional fields are only meaningful in that variant.
module ordered_set_reuse #(
parameter bit PARSE_ALWAYS = 1'b0 // 1 = the broken shape
) (
input logic clk, rst_n, os_valid,
input logic os_is_modified, // modified variant, not the standard one
input logic [7:0] info_field, // only meaningful when modified
output logic caps_valid,
output logic [7:0] caps_seen,
output logic parsed_standard_err, caps_without_modified_err
);
logic parse_en;
assign parse_en = os_valid && (PARSE_ALWAYS ? 1'b1 : os_is_modified);
assign caps_valid = parse_en;
assign caps_seen = parse_en ? info_field : 8'h00;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
parsed_standard_err <= 1'b0; caps_without_modified_err <= 1'b0;
end else begin
if (parse_en && !os_is_modified) parsed_standard_err <= 1'b1;
if (caps_valid && !os_is_modified) caps_without_modified_err <= 1'b1;
end
end
endmodule modified OS : caps_valid=1 caps=0xa5
standard OS : caps_valid=0 caps=0x00 | parse-always caps=0xa5
parse-always variant parsed_standard_err=1The broken variant reads 0xa5 out of a standard ordered set — a field that, in that variant, means something else entirely. The bug is not that the parse fails. It is that the parse succeeds and returns a number. That is the characteristic failure of the extended class: shared structure makes wrong reads look like right ones.
13. RTL 5 — Which Values Move When PCIe Moves
module revision_coupled_param #(
parameter bit HARDCODE_COUPLED = 1'b0
) (
input logic clk, rst_n,
input logic [2:0] pcie_gen, // the generation actually negotiated
input logic gen_valid,
output logic [8:0] flit_bytes, // coupled: follows the PCIe generation
output logic [3:0] cxl_fixed_field, // not coupled: CXL's own
output logic coupled_mismatch_err, gen_unsupported_err
);
localparam logic [8:0] FLIT_G5 = 9'd0; // teaching: no flit mode at Gen5
localparam logic [8:0] FLIT_G6 = 9'd256; // teaching value
logic [8:0] expected;
assign expected = (pcie_gen >= 3'd6) ? FLIT_G6 : FLIT_G5;
// The bug shape: a value that MOVES with the generation, frozen at one.
assign flit_bytes = HARDCODE_COUPLED ? FLIT_G6 : expected;
assign cxl_fixed_field = 4'd1; // genuinely CXL's own; does not move
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
coupled_mismatch_err <= 1'b0; gen_unsupported_err <= 1'b0;
end else if (gen_valid) begin
if (flit_bytes != expected) coupled_mismatch_err <= 1'b1;
if (pcie_gen < 3'd3) gen_unsupported_err <= 1'b1;
end
end
endmodule gen 6 : correct flit=256 fixed=1 | hardcoded flit=256
gen 5 : correct flit=0 fixed=1 | hardcoded flit=256 <-- frozen
hardcoded variant coupled_mismatch_err=1At Gen 6 the two designs are indistinguishable. The hardcoded design is only wrong on a generation it has not been tested against yet — which is the entire hazard of the revision-dependent class, and why it is the only class with a standing review obligation rather than a one-time DV cost.
14. Assertions
Concurrent SVA execution: NOT SUPPORTED BY Icarus Verilog. Not executed; each maps to a procedural stand-in and a mutation.
// SAFETY -------------------------------------------------------------------
// V1 — anything not purely reused requires CXL-specific DV.
a_dv_obligation: assert property (@(posedge clk) disable iff (!rst_n)
cls_valid |-> (needs_cxl_dv == (rclass != REUSED)));
// V2 — only revision-coupled structures carry a per-generation obligation.
a_regen_obligation: assert property (@(posedge clk) disable iff (!rst_n)
cls_valid |-> (needs_regen_review == (rclass == REV_DEP)));
// V3 — PCIe VIP is never claimed over a CXL-specific structure.
a_no_vip_overclaim: assert property (@(posedge clk) disable iff (!rst_n)
(cls_valid && (rclass == CXL_SPEC)) |-> !pcie_vip_covers);
// V4 — a well-formed PCIe endpoint enumerates regardless of CXL.
a_enum_independent: assert property (@(posedge clk) disable iff (!rst_n)
(probe && hdr_is_type0) |-> enumerated);
// V5 — CXL is never claimed without the CXL structure at sufficient revision.
a_claim_needs_dvsec: assert property (@(posedge clk) disable iff (!rst_n)
cxl_claimed |-> (dvsec_present && (dvsec_revision >= MIN_REV)));
// V6 — a point is native only if BOTH axes are native.
a_native_both_axes: assert property (@(posedge clk) disable iff (!rst_n)
is_native |-> (w_native && r_native));
// V7 — supported partitions exactly into native and degraded.
a_point_partition: assert property (@(posedge clk) disable iff (!rst_n)
supported |-> (is_native ^ is_degraded));
// V8 — modified-variant fields are never parsed from a standard ordered set.
a_fields_need_modified: assert property (@(posedge clk) disable iff (!rst_n)
caps_valid |-> os_is_modified);
// V9 — a revision-coupled value always matches the negotiated generation.
a_coupled_tracks_gen: assert property (@(posedge clk) disable iff (!rst_n)
gen_valid |-> (flit_bytes == expected));
// LIVENESS -----------------------------------------------------------------
// V10 — every classified structure eventually gets its obligation discharged.
// ENVIRONMENT ASSUMPTION: the project actually runs the DV it owes. This
// is a process property, not a hardware one, and no RTL can enforce it.
a_obligation_discharged: assert property (@(posedge clk) disable iff (!rst_n)
needs_cxl_dv |-> s_eventually cxl_dv_complete);V10 is included deliberately as a property RTL cannot enforce. It is stated because the failure it describes is real and common — a structure correctly classified as needing CXL DV, and the DV never scheduled — but its environment assumption is a project plan, not a signal. Recognising which properties are outside the design's control is part of writing an honest verification plan.
15. Mutation Testing
Eight mutations. Clean code restored after each.
| ID | Mutation | Result |
|---|---|---|
| M1 | only CXL-specific structures need CXL DV | KILLED — obligation table |
| M2 | VIP-overclaim check disabled | KILLED — positive test |
| M3 | enumeration requires the CXL structure | KILLED — enum_failed_err |
| M4 | DVSEC revision not checked | KILLED — old_revision_err |
| M5 | one native axis is enough | KILLED — degraded_called_native_err |
| M6 | 16 GT/s reclassified as native | KILLED — degraded_called_native_err |
| M7 | info fields parsed from any ordered set | KILLED — parsed_standard_err |
| M8 | the coupled value stops tracking the generation | KILLED — positive test |
8/8 killed, 0 escapedM1 and M2 escaped on the first run, and for different reasons — which is the point worth carrying away.
M1 escaped because the obligation table was printed, not checked. EXP1 displayed a four-row table of needs_cxl_dv and needs_regen_review, a human read it, and nothing in the testbench required any cell to hold a particular value. Changing the design changed the printout and no verdict. Printing a table is not checking it.
M2 escaped because the fault was never presented. The overclaim detector only fires on CXL_SPEC with pcie_vip_covers asserted, and EXP1 set pcie_vip_covers only for the reused and extended classes. The check was correct, wired, and reachable — it simply never saw its input combination.
REUSED that does not behave as PCIe : detected
PCIe VIP claimed over a CXL-only structure: detected
revision-coupled value carried forward : detectedAdding EXP1b exposed a third gap the mutations had not yet reached: stale_revision_err had never fired either, because EXP1 always set revisited_this_gen. One missing stimulus usually indicates a family of them, since the same optimistic default tends to be applied across a whole experiment.
16. Debug Lab
A CXL device is invisible to a non-CXL host
ENUMERATION-COUPLED-TO-CXL// Only enumerate devices we can actually use.
assign enumerated = probe && hdr_is_type0 && dvsec_present;A CXL memory device works in the validation rack and does not appear at all in a customer's older server — no device in the PCIe topology, nothing in the enumeration log, no error. Swapping in a plain PCIe card in the same slot works.
PCIe-only path : enumerated=0
enum_failed_err=1Enumeration was made conditional on the CXL structure. The reasoning ("why enumerate something we cannot use?") inverts the ordering the whole reuse depends on: the host must be able to find and identify the device before it knows what the device is, and on a non-CXL host the answer is that it is a perfectly usable PCIe device.
The device has made itself undiscoverable to exactly the population §5.1 counted as the reason for the reuse.
assign enumerated = probe && hdr_is_type0; // reused — unconditional
assign cxl_claimed = enumerated && dvsec_present
&& (dvsec_revision >= MIN_REV); // added — conditionalThe reused layer must never take a dependency on the added layer. Dependencies run upward only: the CXL claim may depend on PCIe enumeration, never the reverse. Any time a reused structure gains a condition referencing a CXL-specific signal, the reuse has been silently cancelled — and the failure mode is invisibility, which produces no error to investigate.
A host reads capability fields that were never sent
MODIFIED-FIELDS-FROM-STANDARD-OS// The ordered set arrived. Extract the capability field.
assign parse_en = os_valid;Two devices from the same vendor negotiate different capability sets on identical hosts, run to run. Occasionally a device claims support for a protocol it does not implement, and the link then fails later in a way that points at the protocol rather than at bring-up.
standard OS : caps_valid=0 caps=0x00 | parse-always caps=0xa5
parsed_standard_err=1Capability information lives in specific symbol positions of the modified ordered-set variant. In a standard ordered set those positions carry something else. Parsing unconditionally extracts whatever occupies the position and presents it as a capability field.
The result is not a parse error. It is a plausible number, which is far worse — the design proceeds confidently on a value that means nothing, and the eventual failure is at a completely different layer from the cause.
assign parse_en = os_valid && os_is_modified;
assign caps_valid = parse_en;
assign caps_seen = parse_en ? info_field : 8'h00;A shared structure with conditional meaning needs the condition checked at every read, not once at the top. This is the characteristic hazard of the extended reuse class: because the container is identical, a wrong read is byte-legal and produces a value rather than an error. Whenever a field's meaning depends on a variant bit, that bit belongs in the same expression as the field, not in a comment.
A design that was correct last generation fails on the next
REVISION-COUPLED-VALUE-FROZEN// The flit is 256 bytes.
assign flit_bytes = 9'd256;A controller that passed a full regression on the previous platform fails on a new one during framing, with no RTL change in between. Git blame shows the line was written two years ago and has never been modified.
gen 6 : correct flit=256 | hardcoded flit=256
gen 5 : correct flit=0 | hardcoded flit=256 <-- frozen
coupled_mismatch_err=1flit_bytes is a revision-dependent value: it follows the PCIe generation. Hardcoding it produced a design that is exactly right on the generation it was written for, and there was never a moment at which the code "became" wrong — the environment moved.
This is why revision-dependent is a class of its own rather than a footnote on reused. Every other class has a one-time cost that a code review can catch. This one has a standing obligation, and no diff triggers it.
// Derive from the generation actually negotiated, and check it.
assign expected = (pcie_gen >= 3'd6) ? FLIT_G6 : FLIT_G5;
assign flit_bytes = expected;
// ...
if (gen_valid && (flit_bytes != expected)) coupled_mismatch_err <= 1'b1;Track the coupling in the design, not in an engineer's memory. Every revision-dependent value should be derived from the negotiated generation and checked against it, so that running on an unsupported combination is a detected error rather than silently wrong framing. The review question is: which constants in this file would change if PCIe advanced a generation, and what would tell us?
A DVSEC is present and the host trusts it anyway
PRESENCE-MISTAKEN-FOR-VALIDITY// The CXL structure is there, so the device is CXL.
assign cxl_claimed = enumerated && dvsec_present;An early-silicon device enumerates, is identified as CXL, and then behaves inconsistently — some fields read as expected, others return values that make no sense for the fields the host believes it is reading.
DVSEC rev0 : enumerated=1 cxl_claimed=1
old_revision_err=1Presence and validity were treated as the same question. Public material requires the primary function to carry CXL DVSEC ID0 at Revision 1 or greater; a structure below that revision does not necessarily lay out the fields the host is about to parse.
The host is reading a real structure at real offsets with a real ID, and interpreting it under a contract that structure never agreed to.
localparam logic [3:0] MIN_REV = 4'd1;
assign cxl_claimed = enumerated && dvsec_present && (dvsec_revision >= MIN_REV);A version field is a contract, not metadata. Any structure carrying a revision is telling you that its layout has changed at least once, and reading it without checking the revision is reading a format you have not agreed on. The same reasoning applies to the modified ordered set in Lab 2 — in both cases the structure is present and the meaning is conditional.
A green PCIe regression is read as coverage of the CXL layers
VIP-COVERAGE-OVERCLAIM// PCIe VIP exercises the link. Coverage claimed.
assign pcie_vip_covers = 1'b1;No RTL failure at all — this one surfaces as a schedule decision. A coverage report shows high numbers, the PCIe regression is clean, CXL-specific DV is deprioritised, and the first coherency bug is found by a customer.
class needs_cxl_dv needs_regen_review
REUSED 0 0
EXTENDED 1 0
CXL-SPECIFIC 1 0
REVISION-DEP 1 1
vip_overclaim_err=1 (CXL-SPECIFIC claimed as PCIe-VIP-covered)PCIe VIP exercises the reused rows fully and the shape of the extended rows. It has no stimulus at all for structures PCIe does not define — the CXL DVSEC layout, .cache and .mem semantics. Claiming coverage for those is not an optimistic estimate; it is a claim about tests that do not exist.
The classification table said this plainly. What was missing was any mechanism that held the claim to the table.
// The claim is checkable. Make it checked.
if ((rclass == CXL_SPEC) && pcie_vip_covers) vip_overclaim_err <= 1'b1;Reuse saves verification effort in exactly the rows where it saves design effort, and not one row further. The saving is real — three of §5's thirteen structures can honestly be skipped — and the inference from a clean PCIe regression to CXL confidence is not. This lab is also where mutation M2 came from: the check above existed and no test ever presented the combination that reaches it, so disabling it changed nothing.
17. Verification Plan
| Item | Approach and goal |
|---|---|
| Obligation table | assert both outputs, all four classes — checked, not printed |
| Misclassification | drive each wrong claim — all three detectors fire |
| Enumeration | probe with and without DVSEC — enumerates in both |
| Revision gate | sweep revision across the floor — claim flips at it |
| Operating points | cross width x rate — all 20 classified, native = 6 |
| Ordered-set variant | cross valid x modified — read only in the modified cell |
| Generation coupling | sweep the generation — coupled tracks, fixed does not |
| Diagnostic liveness | broken variants — every diagnostic observed firing |
The second and last rows exist because of this chapter's own escapes. A plan that lists checks without requiring each to have been seen to fire cannot distinguish a working checker from an unreachable one.
18. Design Review
- For each PCIe structure in the design, which of the four classes is it, and who decided?
- Which constants would change if PCIe advanced a generation, and what would detect it?
- Does any reused structure take a condition on a CXL-specific signal? That cancels the reuse.
- Where a field's meaning depends on a variant bit, is the bit in the same expression as the field?
- Is any structure with a revision field read without checking the revision?
- Which coverage claims rest on PCIe VIP, and does any of them cover a CXL-specific row?
- Has every diagnostic in the design been observed to fire in at least one test?
19. How This Appears in Real Engineering
The reuse matrix is a schedule document, not a diagram. Its practical output is the DV column: which blocks need CXL-specific effort and which do not. Teams that produce the classification and never derive the obligations from it have drawn a picture.
Revision-dependent rows dominate cross-generation bring-up. When a controller moves to a new PCIe generation, the failures cluster in exactly the rows §5 marks revision-dependent, and they are unusually hard to triage because no code changed.
"Present" versus "valid" is a recurring bring-up bug. Labs 2 and 4 are the same mistake at two layers — a structure that exists and does not yet mean what is being assumed. On early silicon, where revisions and variants are genuinely in flux, this class is disproportionately common.
Coverage overclaim is a management-visible failure. Lab 5 has no RTL symptom at all. It surfaces as a decision to deprioritise work, and the evidence that it was wrong arrives from a customer.
20. Common Misconceptions
| Claim | Why it is wrong |
|---|---|
| "Reused means we can skip the DV" | Only for the reused class — 3 of §5's 13 rows. Extended, CXL-specific and revision-dependent all need CXL DV. |
| "CXL replaced the PCIe LTSSM" | It did not. Public material describes CXL using the alternate protocol negotiation mechanism defined in the PCIe specifications, carried in modified ordered sets within existing Configuration states. |
| "CXL supports x1 through x16 and 8 through 64 GT/s" | Publicly described as x16/x8/x4 and 32/64 GT/s natively, with x2/x1 and 16/8 GT/s in degraded mode. Native and supported are different claims. |
| "The link trains at 8 GT/s minimum" | It starts training at the PCIe Gen 1 rate, 2.5 GT/s. Training rate and operating rate are different questions — see 5.4. |
| "A CXL device needs a CXL host to be seen" | No. It presents a Type 0 header and enumerates on any PCIe host; only the DVSEC is CXL-aware. That is the most valuable single reuse. |
| "If the DVSEC is there, the device is CXL" | Presence is not validity. Public material requires Revision 1 or greater; below that the layout is not the one being parsed. |
| "PCIe VIP gives us most of our CXL coverage" | It gives full coverage of reused rows and shape-only coverage of extended rows, and none of CXL-specific rows. |
21. Interview Reasoning
22. Exercises
-
Classify. Take §5's thirteen structures and, for each, write the single test that would detect a misclassification. Which structures have no cheap detector, and what does that imply about how their class should be decided?
-
Calculate. RTL 3 gives 6 native of 20 points across five widths and four rates. Recompute if x4 were reclassified as degraded, and again if 16 GT/s became native. State which change a datasheet reader is more likely to assume, and what it would cost them.
-
DV task. Write the coverage cross that would have caught M1, and separately the one for M2. Explain why only one of the two is a coverage problem, and what a plan that conflates them will miss.
-
Debug task. A controller fails framing on a new platform with no RTL change. List your first five checks in order, and state which of §5's classes each is testing.
-
Design. Extend
config_space_overlayso a host can distinguish "not CXL", "CXL at an unsupported revision", and "CXL usable" as three separate outcomes. State which existing diagnostic becomes redundant and why that is a good sign. -
Critique. Argue that the revision-dependent class should be folded into extended. Identify the obligation your argument loses, and describe a failure that would then go undetected.
23. Summary
"Reuse" is four contracts wearing one word, and the class of a structure describes what you still owe it, not what it looks like.
- Reused costs nothing beyond PCIe. Extended costs CXL DV. CXL-specific costs CXL DV and voids any PCIe VIP claim. Revision-dependent costs a review every PCIe generation.
- Only 3 of §5's 13 structures can honestly be skipped on a clean PCIe regression.
- Enumeration is the most valuable single reuse, and it works only because dependencies run upward only — the CXL claim may depend on PCIe discovery, never the reverse.
- The native operating space is smaller than PCIe's: 6 of 20 width-by-rate points, because the two axes combine with AND.
- Training rate and operating rate are different questions. The link starts at 2.5 GT/s, below the degraded floor, because it must come up before capability is known.
- Verification lesson from this chapter's escapes: a missing check and a missing stimulus both read as "mutation survived" and have opposite fixes. Ask whether the checker evaluated at all.
Chapter 5.3 takes up the mechanism this chapter has only named: how the two ends actually exchange capability and agree, using PCIe's alternate protocol negotiation.
Standards & specifications
- Governing standard
- CXL Specification (CXL Consortium)(opens CXL Consortium in a new tab)
Defines CXL.io, CXL.cache and CXL.mem, and the coherence and memory-pooling behaviour built on them. System design and deployment topology are not mandated.
This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.
Where this fits
Part of the CXL curriculum.
