Skip to content
VLSI Mentor

CXL · Module 13

Shared Memory Across CXL

The coherency rules do not change when the agents are on opposite sides of a link. What changes is that every instantaneous step becomes a window, responses stop arriving in order, and the protocol starts depending on a delivery guarantee it does not provide itself.

13.1 built the permission model on an assumption it never stated: that a snoop and its response are adjacent in time.

Across a link they are not, and every mechanism in that chapter has to survive the gap.

1. The Engineering Problem — The Same Rules, Much Further Apart

Nothing in the previous chapter is repealed here. SWMR still holds. A read still returns the latest write in the coherence order. Dirty data must still survive eviction. Every invariant carries over unchanged.

What changes is time, and time changes three things that were invisible on one die.

Every protocol step becomes a window. Revoking a remote agent's permission is no longer a signal that settles within a cycle — it is a message that crosses a link, is processed, and is acknowledged back. Measured on a four-cycle link, that round trip leaves the old permission alive for four cycles, and everything the protocol does during that window has to be safe.

Responses stop arriving in order. Once several requests are outstanding across a link, the order in which answers come back is not the order in which questions were asked. A design that matches an answer to the oldest outstanding question is right only while it is lucky.

And the protocol starts depending on something it does not provide. Coherency has no retransmission of its own. A dropped invalidation is not a slow invalidation — it is a protocol that stops. The timeout and the retry are somebody else's obligation, and the coherency layer has to be explicit about depending on them.

2. The One-Sentence Model

Distance turns a step into a window. The rules are unchanged; what changes is how long the old world persists after you have decided to replace it, and everything that can go wrong across a link goes wrong inside that window.

Call it same rules, longer windows. Every defect in this chapter is a window that was not waited out, or an identity that was not checked inside one.

3. What This Chapter Owns

GroundOwner
Permissions, SWMR, and what coherency does not promise13.1
What changes when the agents are across a linkthis chapter
Who owns a line and how ownership moves13.3
Per-line state and the transition machinery13.4
Where a CHI fabric and a CXL boundary meet13.5

Deferred:

Deferred groundOwner
Concrete read, write and ownership-transfer flowsModule 14
Fabric topology and switchesModules 15 and 16
Latency anatomy and bandwidth modellingModule 18

This chapter is about consequences, not mechanisms. It introduces no new invariant. Every model below takes something 13.1 treated as instantaneous and gives it a duration, then asks what has to be true for the invariant to survive.

4. Teaching-Model Boundary

The risk in this chapter is inventing protocol. There are no opcodes, no message names, no channel structure and no ordering rules attributed to CXL below. Where a mechanism is needed — a tag, a timeout, a bias flip — it is built here and labelled.

What is transferable is the shape of the problem. Any coherency protocol crossing any link faces the same four obligations: wait out the window, match by identity, serialise conflicts at one point, and depend explicitly on reliable delivery. Those hold whether the link is CXL, a coherent fabric, or two chiplets.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Everything in 13.1 assumed a snoop and its response were adjacent in time.
// A link makes them N cycles apart, and every one of those cycles is a window
// in which the old permission still exists.
module link_delay #(parameter int LAT = 4) (
  input  logic       in_valid, input logic [2:0] in_tag, input logic [7:0] in_data,
  output logic       out_valid, output logic [2:0] out_tag, output logic [7:0] out_data,
  output logic [3:0] in_flight,
  output logic [7:0] n_sent, n_arrived
);

Measured: a message sent with tag 1 and payload 0xAA shows in_flight=1 immediately, is absent from the output for three cycles, and arrives on the fourth carrying its tag and payload intact.

That is the entire model, and it is deliberately trivial, because the interesting part is not the link — it is what every other mechanism has to do about it.

The tag matters more than the payload. A link that delivers data without preserving which request the data belongs to has not delivered anything usable, which is section 7.

6. Waveform — The Exposure Window

Transcribed from the printed cycle trace of the cross-link model in section 11.

A write request that has to cross a link and come back

8 cycles
A write request that has to cross a link and come backwindow openswindow opensack returns, window closesack returns, window closesclkwant_wrinv_ackwait_cyc00123444exposedgrants00000011t0t1t2t3t4t5t6t7
Figure 1 — Transcribed from the printed trace. The remote agent holds a readable copy for every cycle between the request and the acknowledgement. On one die that window is a cycle; here it is the round trip.

The exposed row is the whole chapter. It is high from the moment the local agent decides it wants exclusive access until the moment the remote acknowledgement returns — and throughout that time the remote agent holds a copy it believes is valid and will serve reads from.

Nothing here is wrong. The design waits, the invariant holds, and the grant count rises only at cycle 6. The point is that the window exists at all, and that its length is a property of the link rather than of the protocol.

7. RTL 2 — Responses Arrive Out Of Order

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Once responses can be in flight for several cycles they can also arrive in a
// different order from the requests. Matching by ARRIVAL ORDER is the bug;
// matching by IDENTITY is the design.
//
// MATCH_BY_ORDER is a verification-only hook, default 0, so the wrong design
// can be demonstrated rather than described.
  logic [2:0] sel_tag;
  assign sel_tag = (MATCH_BY_ORDER != 0) ? order_q[head_q[2:0]] : resp_tag;
  assign mismatch = resp_en && (sel_tag != resp_tag);

Four requests are issued with tags 0, 1, 2 and 3. The response for tag 3 comes back first. Measured, side by side, on two instances of the same module:

DesignRetiresMismatch
match by identitytag 30
match by arrival ordertag 01

The order-matching instance retires the oldest outstanding request — which was never the one the response named. It is not merely inefficient; it completes the wrong transaction and leaves the right one outstanding forever.

Two rejection cases are also distinguished, because they are found in different places:

Response forResult
a tag never issuedunknown_resp — routing or tag corruption
a tag that already completeddup_resp — a retry that was not suppressed

Measured at 1 each, and a rejected response completes nothing: the completion count stays at 4.

Tag 0 is used deliberately in that test. A count or a scan that skips index zero is invisible if index zero is never occupied, and a mutation doing exactly that survived the first run until the stimulus was changed.

8. RTL 3 — Measuring The Exposure Window

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
      if (revoke && !open_q) begin open_q <= 1'b1; cnt_q <= 8'd0; end
      else if (open_q) begin
        if (ack) begin
          open_q <= 1'b0;
          // The maximum is LATCHED. A window that has closed is exactly the
          // one that explains a stale read nobody can reproduce.
          if (cnt_q > window_max) window_max <= cnt_q;
        end else begin
          cnt_q <= cnt_q + 8'd1;
          // A window far longer than the link round trip means the
          // acknowledgement is not coming, not that the link is slow.
          if (cnt_q >= (LAT[7:0] * 8'd4)) still_exposed_err <= 1'b1;
        end
      end

Measured: a window held open for 6 cycles closes on the acknowledgement, and the maximum latches at 6. A subsequent shorter window does not reduce it.

The distinction between a slow window and a stuck one is a threshold, and the threshold is derived from the link. A window of four cycles on a four-cycle link is expected. A window of twenty is not slow — it means the acknowledgement is never coming, and it is reported as still_exposed_err rather than waited on indefinitely. Measured at 1 with the line still marked exposed.

9. RTL 4 — Two Directions, One Manager

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  // A device reaching host memory is the caching direction.
  assign use_cache_proto = acc_en &&  initiator && !target_is_device;
  // A host reaching device-attached memory is the memory direction.
  assign use_mem_proto   = acc_en && !initiator &&  target_is_device;
  // Host to host memory, or device to its own memory, needs no cross-link
  // coherency protocol at all.
  assign local_access    = acc_en && (initiator == target_is_device);
  // The host manages coherency in BOTH cross-link directions -- including for
  // memory that is physically attached to the device.
  assign host_manages    = 1'b1;

The four combinations, measured, with exactly one classification per access:

InitiatorTargetProtocol
devicehost memorycaching direction
hostdevice memorymemory direction
hosthost memorylocal, none
deviceits own memorylocal, none

The row people find surprising is the second one. A host reaching memory that is physically attached to a device still has the host managing coherency for it. Physical attachment and coherency management are different questions, and conflating them is the most common misreading of the CXL protocol split.

Measured: 1 caching-direction access, 1 memory-direction access, 2 local, with host_manages asserted in both cross-link cases.

10. RTL 5 — Bias: Whose Memory Is It Anyway

Bias states with a draining transition between host bias and device biasHOSTFLIPDEVICEflip requestedfliprequestedtraffic drainedtraffic drainedflip requestedfliprequestedtraffic drainedtraffic drained
Figure 2 — Bias as a concept. In host bias every access is coherent with the host; in device bias the device reaches its own memory directly and the host is kept out. The flip between them must drain whatever is in flight.
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  // In device bias the device reaches its own memory without crossing the link.
  assign dev_direct   = dev_acc && bias_q && !flip_q;
  // The host may only reach it in host bias -- otherwise the device's private
  // view and the host's view could diverge.
  assign host_allowed = host_acc && !bias_q && !flip_q;

Measured behaviours:

StateDevice accessHost access
host biasnot direct — goes through the linkallowed
device biasdirectblocked
flippingneither, until traffic drainsblocked

The flip is the interesting part. Requested while two host accesses are still outstanding, it does not take effect — measured, the bias stays in host mode for three further cycles and completes only when the outstanding count reaches zero. Flipping early would leave the device operating on its own private view while host traffic that assumed the coherent view was still in flight.

A flip requested again while traffic is outstanding raises unsafe_flip_err, measured at 1.

This is a concept model. It captures the idea that device-attached memory can be operated coherently or privately, and that switching between those modes is a drain-and-swap rather than a mode bit. No CXL mechanism, encoding or timing is claimed.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  assign inv_sent    = want_write && remote_holds_read && !wait_q;
  // The grant waits for the acknowledgement to come BACK across the link.
  assign grant_write = wait_q && inv_ack;
  // The invariant: a write grant while the remote agent still holds read.
  assign swmr_broken = grant_write && remote_q;

The invariant is character-for-character the one from 13.1. What changed is the wait: measured, the write request waits 8 cycles for the invalidation to cross, be processed, and be acknowledged back, and swmr_broken never fires.

12. RTL 7 — Coherency Assumes Reliable Delivery

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Coherency has no retransmission of its own: a dropped invalidation does not
// degrade performance, it stalls the protocol forever. The timeout and retry
// are a LINK-layer obligation.
  assign timed_out = busy_q && (age_q >= TIMEOUT[7:0]);

An invalidation is sent and dropped. The acknowledgement is offered every cycle and cannot help, because the message never arrived. Measured: 12 cycles of waiting, then timed_out=1, a retry, and the retry is acknowledged — with stalled_err recorded.

This is the dependency the coherency layer must state out loud. Nothing in the permission model retransmits anything. Without a timeout the protocol does not run slowly — it stops, holding a window open forever, which is precisely the still_exposed_err condition from section 8 seen from the other side.

The measured design also refuses to acknowledge a dropped message: the ack_in && !dropped_q term means an acknowledgement offered for a message that never landed does nothing, which is what makes the timeout the only exit.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
      if (sample_en) begin
        n_samples <= n_samples + 8'd1;
        // Both peaks are latched. Across a link the interesting events are
        // transient and a current-value counter reports none of them.
        if (flight_now > peak_flight) peak_flight <= flight_now;
        if (window_now > peak_window) peak_window <= window_now;
      end

Measured: in-flight counts of 2, 7 and 1 sampled in that order leave peak_flight=7; exposure windows of 5, 11 and 2 leave peak_window=11. Idle cycles do not count as samples.

Across a link, every number worth knowing is a peak. The average in-flight count tells you the link is comfortable; the peak tells you whether the outstanding-request table ever ran out of entries. The average window tells you the link is fast; the peak tells you how long a stale copy could have survived.

14. RTL 9 — The Serialisation Point

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Once requests cross a link they can arrive in any order, so "who asked first"
// is not a well-defined question. ONE place must decide the order for a line,
// and both requesters must accept that decision.
  assign conflict = (req_a && req_b) || (req_a && (own_q == 2'd2)) || (req_b && (own_q == 2'd1));
  assign both_granted_err = grant_a && grant_b;

Two agents request exclusive access to the same line in the same cycle. Measured:

StepResult
simultaneous requestconflict=1, winner A, both_granted=0
the loserqueued, not refused
winner finishesline passes to B, 2 grants in a defined order

A conflict is a normal operating condition, not an error. What would be an error is two agents each believing they won, which is the cross-link form of the two-writer failure from 13.1 — and both_granted_err exists to catch it, with its own fault-injection hook because the single-owner encoding makes it unreachable otherwise.

The tie-break rule itself does not matter. Any deterministic rule works. What does not work is having no rule, or having a different rule at each end of the link — which is exactly what "who asked first" degenerates into once messages can overtake each other.

15. RTL 10 — Did It Actually Work?

Every other model in this chapter verifies a mechanism. This one verifies the outcome.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  // A read issued after a write committed must not return an older value.
  assign stale_read = rd_return && rd_after_write && (rd_val != last_q);

Measured: a read returning the committed value is clean; a read returning an older value after a commit is stale, with the gap recorded. A larger gap latches a new worst case of 8, and a smaller later gap does not reduce it.

The rd_after_write qualifier is doing real work. A read that was not ordered after the write is not stale no matter what it returns — it simply happened earlier in the coherence order. Removing that term turns every ordinary read into a violation, and it is a mutation that survived until the testbench included a read with the qualifier low.

16. Quantitative Reasoning

The exposure window is the link round trip, and it is the number that changes.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
window = send + remote processing + acknowledge

Measured on a four-cycle link: 4 cycles in the waveform, 8 cycles in the cross-link model with a longer remote turnaround. On one die the same step is a cycle. Nothing about the protocol changed; the duration did.

Outstanding requests needed to hide the window:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
requests_in_flight >= window / issue_interval

Measured peak in-flight of 7 against a peak window of 11 — a design sized for the average would have run out of tags at the peak, and the peak is the only number that reveals it.

Invalidation cost across a link. The messages are the same as 13.1 — one per sharer — but each now carries a round trip, and the grant waits for the slowest of them:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
upgrade latency = max over sharers of (round trip to that sharer)

That is a maximum, not a sum and not a mean, which is why a single distant sharer costs as much as many near ones.

Timeout threshold. The measured design uses a threshold derived from the link rather than a constant: a window beyond four times the round trip is treated as stuck rather than slow. Measured, a dropped message times out after 12 cycles and is retried once.

The direction split has no latency in it at all. Two of the four access combinations need no cross-link protocol — measured, 2 of 4 local. The cheapest coherency traffic is the traffic that does not cross.

Access directions between host and device showing which need a cross-link protocolhostcache and coreshost memoryhost attachedthe linkturns steps into windowsdevicecache and logicdevice memorydevice attachedlocal, no protocollocal, no protocolcaching directionhost managesmemory directionhost still manages12
Figure 3 — The two cross-link directions and the two that never leave home. The host manages coherency in both directions that cross, including for memory physically attached to the device.

17. Assertions

Presented as SystemVerilog and executed as procedural checkers — see section 19.

No write grant while a remote copy exists.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_cross_link_swmr;
  @(posedge clk) disable iff (!rst_n)  grant_write |-> !remote_holds_read;
endproperty

A response retires the request it names.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_identity_match;
  @(posedge clk) disable iff (!rst_n)  complete |-> (complete_tag == resp_tag);
endproperty

Exactly one classification per access.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_one_direction;
  @(posedge clk) disable iff (!rst_n)
    acc_en |-> ($countones({use_cache_proto, use_mem_proto, local_access}) == 1);
endproperty

The host manages coherency in both cross-link directions.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_host_manages;
  @(posedge clk) disable iff (!rst_n)
    (use_cache_proto || use_mem_proto) |-> host_manages;
endproperty

The host never reaches device memory in device bias.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_bias_exclusion;
  @(posedge clk) disable iff (!rst_n)  host_allowed |-> !device_bias;
endproperty

A bias flip completes only with nothing outstanding.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_flip_drains;
  @(posedge clk) disable iff (!rst_n)
    $rose(device_bias) |-> $past(outstanding == 0);
endproperty

Never two owners of one line.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_single_owner;
  @(posedge clk) disable iff (!rst_n)  !(grant_a && grant_b);
endproperty

A read ordered after a commit returns the committed value.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_no_stale;
  @(posedge clk) disable iff (!rst_n)
    (rd_return && rd_after_write) |-> (rd_val == last_committed);
endproperty

A window beyond the link budget is reported, not waited on.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
property p_window_bounded;
  @(posedge clk) disable iff (!rst_n)
    (window_now >= LAT*4) |-> still_exposed_err;
endproperty

109 assertion sites across the ten models and the waveform trace. All pass.

18. Mutation Testing

57 mutations injected, 57 killed, 0 surviving.

FamilyInjected
link delay and delivery5
response matching and identity7
exposure window5
direction split4
bias6
cross-link SWMR5
reliability and timeout6
telemetry3
serialisation and conflict8
end-to-end staleness6
integration, run under the waveform trace2

Representative kills:

MutationCaught by
messages arrive with no delaythe in-flight and arrival check
responses matched by arrival orderthe out-of-order sequence
a duplicate reported as unknowna response for an already-completed tag
the window closes without an acknowledgementthe six-cycle hold
the window maximum tracks instead of latchinga shorter window after a longer one
cache and mem directions swappedthe four-row truth table
the device manages coherency for its own memorythe memory-direction access
the host may access in device biasthe blocked-access case
the flip does not wait for traffic to draintwo outstanding accesses
write granted without the acknowledgementthe eight-cycle wait
no timeout, so the protocol stalls foreverthe dropped invalidation
the loser is not queuedthe simultaneous request
reads before the write also count as stalea read with the ordering qualifier low

Ten mutations did not die on the first run.

SurvivorClassification
outstanding count skips slot 0equivalent under the stimulus — tag 0 was never used
device goes direct in host biasstimulus gap
host blocked even in host biasobservation gap
blocked host accesses not countedoutput never observed
no invalidation is sentoutput never observed
cross-link SWMR break never detectedchecker unreachable through the ports
both agents granted the same linechecker unreachable through the ports
worst gap tracks instead of latchingstimulus gap — no smaller gap followed the larger
reads before the write also stalestimulus gap — the qualifier was always high
a reissued tag stays marked donegenuinely equivalent — replaced, not recorded

Two are worth naming. The slot-zero count is the 12.4 lesson recurring in a new shape: a scan that skips index zero is invisible if index zero is never occupied, and the fix was to use tag 0 deliberately. And one mutation — a reissued tag keeping its done marking — turned out to be provably equivalent, because that bit only matters while the slot is not live and a reissued-then-completed tag ends marked either way. It was replaced with a mutation that changes behaviour rather than recorded as a survivor.

19. Verification Strategy

Tool reality. Icarus Verilog 13.0 only. No concurrent SVA, so section 17's properties are executed procedurally. Two Icarus-specific constraints bit during authoring: a part-select of a function call's result is illegal and needed an explicit temporary, and a zero-argument function had to become a task.

A signal-name collision between two DUTs in one testbench — n_blocked and n_retry appearing in both the bias model and the telemetry bank — was caught at elaboration and fixed by naming the ports explicitly at the instance.

Independent oracles.

  • resp_matcher — design: a live-bit array indexed by tag. Oracle: an explicit tag set, with order deliberately not represented.
  • direction_split — design: boolean expressions. Oracle: a literal four-row truth table.
  • cross_link_swmr — design: a wait flag and counter. Oracle: expected wait length stated per case.
  • link_reliability — design: age and drop flags. Oracle: expected timeout and retry counts.
  • conflict_order — design: an owner register and queue bits. Oracle: expected winner and grant order per sequence.

The response-matcher oracle is the important one: it holds outstanding requests as a set, with no notion of order at all, because order is exactly what must not matter. An oracle that kept a queue would encode the bug.

Coverage. The points that matter are link latency, outstanding depth, response order, direction, bias state, and conflict shape. The crosses worth driving are outstanding depth crossed with response order — the only way to reach the out-of-order case with more than one candidate — and bias state crossed with initiator, which is what separates the four access classifications. A cross of tag value against latency is noise.

20. Synthesis and Implementation Reality

The outstanding-request table is the new structure, and it is sized by the window.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
entries >= peak in flight
tag width = log2(entries)

Measured peak in-flight of 7 on a four-cycle link. Under-sizing it does not degrade throughput gracefully — it stalls issue entirely, because a request with no tag cannot be sent.

Every message carries identity, and identity is width on every wire. The tag travels out with the request and back with the response, so it costs bits in both directions plus a comparator at the return path. That is the price of not matching by arrival order, and it is unavoidable.

Timers scale with outstanding requests, not with the link. One age counter per outstanding request, not one for the link, because each request times out independently. That is entries × log2(timeout) bits of storage doing nothing most of the time and preventing an indefinite stall the rest of it.

The bias flip is a drain, and drains need a counter that cannot be wrong. The outstanding count gating the flip is the same class of derived counter 12.1 warned about: if it can drift low, the flip completes early and the two views diverge. It should be derived from the same structure that issues the requests, not maintained separately.

The serialisation point is a single-owner register and a queue, and its cost is trivial. What is not trivial is guaranteeing there is only one of it per line — that is a topology property, not an RTL one, and it is where Modules 15 and 16 pick up.

No gate counts are offered. The structural claims — table sized by peak in-flight, tag width on both directions, one timer per outstanding request — hold regardless of process.

21. Silicon Observability

CounterClass
peak_flightpolicy input
peak_windowpolicy input
n_sent vs n_arrivedtelemetry
mismatchhard alarm
unknown_resphard alarm
dup_resptelemetry, then alarm if it grows
still_exposed_errhard alarm
n_cache_dir vs n_mem_dirpolicy input
n_blocked (bias)policy input
n_flips, unsafe_flip_errtelemetry / hard alarm
n_timeout, n_retrytelemetry
stalled_errhard alarm
n_conflictpolicy input
both_granted_errhard alarm
n_stale, worst_gaphard alarm
ObservationReading
peak_flight at table capacitythe outstanding table is the throughput limit, not the link
peak_window far above the round tripacknowledgements are being delayed, not lost
still_exposed_err setan acknowledgement is never coming; the link, not the protocol
mismatch non-zeroresponses are being matched by order somewhere
dup_resp growingretries are not being suppressed at the source
n_blocked high in device biasthe workload wants the coherent view; the bias is wrong
n_flips highthe bias is thrashing and each flip costs a drain
n_conflict high, both_granted_err cleancontention, working correctly
n_stale non-zerothe end-to-end guarantee broke; nothing else matters

n_stale sits at the bottom deliberately. Every other counter measures a mechanism; that one measures whether the mechanisms achieved anything. A system with clean mechanism counters and a non-zero stale count has a gap nobody has modelled.

22. Debug Lab

1

A transaction completes and the wrong one is still outstanding

ORDER-MATCHING
Symptom

Requests complete, but the completion data belongs to a different request. One request never completes at all. The problem appears only when several requests are outstanding.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  out-of-order response : identity match -> tag 3, mismatch=0
  order match (broken)  : retired tag 0 instead, mismatch=1
Evidence

Compare the tag a response carries against the tag the design retired. If they differ, the design is matching by arrival order rather than identity.

Likely Causes

A FIFO of outstanding requests retired from the head; an assumption that a link preserves order; a tag that is issued but not carried back.

Debug Sequence

Issue four requests and return the last one first. Identity matching retires the one named; order matching retires the oldest. The measured contrast is retiring tag 3 against retiring tag 0 for the same response.

Root Cause

Once responses can be in flight for several cycles, arrival order carries no information about which request an answer belongs to.

Fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
assign sel_tag  = resp_tag;                       // the response names its request
assign mismatch = resp_en && (sel_tag != resp_tag);
Prevention

Carry a tag on every message in both directions and alarm on a mismatch. A design that cannot detect this cannot distinguish it from data corruption.

2

A stale read that nobody can reproduce

EXPOSURE-WINDOW
Symptom

One agent reads a value that another agent overwrote. It happens rarely, only under load, and never in a directed test.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  exposure window : now=6 max=6 (latched)
Evidence

Read the latched peak exposure window. The window that caused the stale read has closed by the time anyone looks, and a current-value counter reports zero.

Likely Causes

A grant that does not wait the full round trip; a remote agent slower to process an invalidation than the design assumed; an acknowledgement path with more latency than the request path.

Debug Sequence

Compare peak window against the expected round trip. A peak near the round trip is normal; a peak far above it means acknowledgements are being delayed. Then confirm the grant is gated on the acknowledgement rather than on elapsed time.

Root Cause

The old permission outlived the moment the new one was granted. The window always existed; the bug is proceeding inside it.

Fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
if (cnt_q > window_max) window_max <= cnt_q;   // latch the peak
assign grant_write = wait_q && inv_ack;        // and never grant on elapsed time
Prevention

Latch the peak window in hardware. A stale read is a past-tense event and only a latched maximum can describe it afterwards.

3

The protocol stopped and nothing reported an error

LOST-MESSAGE
Symptom

One line becomes permanently inaccessible. The requesting agent waits forever. No error, no timeout, no alarm — the system simply has a line nobody can use.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  dropped invalidation : timed_out=1 retries=1
Evidence

Check whether the coherency layer has any bound on waiting. It has no retransmission of its own, so a dropped message is not slow — it is terminal.

Likely Causes

An invalidation lost in the interconnect; an acknowledgement lost on the return path; a link layer assumed to be reliable that is not; no timeout anywhere in the stack.

Debug Sequence

Read still_exposed_err and the timeout counters. A window far beyond the round-trip budget means the acknowledgement is not coming, which is a delivery failure rather than a protocol one. Measured, a dropped message times out after 12 cycles and the retry succeeds.

Root Cause

Coherency depends on reliable delivery it does not provide. Without a timeout and retry somewhere beneath it, one lost message stalls the protocol permanently.

Fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
assign timed_out = busy_q && (age_q >= TIMEOUT[7:0]);
// and the acknowledgement for a message that never landed must do nothing:
if (ack_in && !dropped_q) begin ... end
Prevention

State the delivery dependency explicitly in the design, and bound every wait. An unbounded wait in a protocol with no retransmission is a permanent hang waiting for a dropped packet.

4

Adding memory to the device did not help the host

DIRECTION-CONFUSION
Symptom

Memory is attached to the device to relieve host pressure. Host accesses to it are slower than expected and generate coherency traffic nobody predicted.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  direction: device->host mem = cache proto (1), host->device mem = mem proto (1)
Evidence

Check which side manages coherency for that memory. Physical attachment and coherency management are different questions, and the host manages coherency for device-attached memory it accesses.

Likely Causes

An assumption that memory physically on the device is managed by the device; a capacity plan that counted device-attached memory as local to the device; confusion between the caching direction and the memory direction.

Debug Sequence

Classify each access by initiator and target. Measured, only two of the four combinations cross the link at all — a host reaching host memory and a device reaching its own memory need no protocol. The other two do, and the host manages both.

Root Cause

Where memory lives and who manages its coherency are independent, and the design was planned as though they were the same.

Fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
assign host_manages = 1'b1;    // in BOTH cross-link directions
Prevention

Count the four access classes separately. A single "coherency traffic" number cannot show that half of it is a direction somebody did not expect to exist.

5

The device and the host disagree about memory the device owns

UNSAFE-BIAS-FLIP
Symptom

After switching device-attached memory into device mode, the host observes values the device never wrote, or the device observes values the host thought it had written.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  bias : flips=1 device_direct=1 host_blocked=1 unsafe_flip=1
Evidence

Check whether host traffic was still outstanding when the mode changed. A flip is a drain-and-swap, not a mode bit.

Likely Causes

A flip applied immediately on request; an outstanding counter that can read low; a second flip request arriving mid-flip.

Debug Sequence

Request a flip with traffic outstanding and confirm it does not take effect. Measured, the bias holds for three further cycles and completes only when the outstanding count reaches zero. Then request again mid-flip and confirm unsafe_flip_err fires.

Root Cause

The mode changed while accesses that assumed the old mode were still in flight, so two views of the same memory existed at once.

Fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
else if (flip_q && (outstanding == 4'd0)) begin
  bias_q <= ~bias_q; flip_q <= 1'b0;
end
Prevention

Derive the outstanding count from the structure that issues the requests, never maintain it separately, and alarm on a flip requested while one is pending.

6

Two agents each believe they own the line

NO-SERIALISATION-POINT
Symptom

Two agents on opposite sides of the link both proceed as exclusive owner of the same line. Each observed the other's request arriving after its own.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  simultaneous request : conflict=1 winner=1 both_granted=0 B queued=1
Evidence

Ask where the order for that line is decided. If each end decides locally, "who asked first" has two different answers and both are locally correct.

Likely Causes

No single serialisation point for the line; a tie-break rule that differs at each end; an ordering derived from arrival time rather than from a decision.

Debug Sequence

Issue two requests for the same line in the same cycle and confirm exactly one grant. Measured, A wins, B is queued rather than refused, and B receives the line when A finishes — two grants in a defined order with both_granted=0 throughout.

Root Cause

Once messages can overtake each other, arrival order is not a shared fact. One place must decide and both ends must accept the decision.

Fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
assign both_granted_err = grant_a && grant_b;   // and a fixed, deterministic tie-break
Prevention

Queue the loser rather than refusing it — a refusal invites an immediate retry and a livelock. And alarm on a double grant even though the encoding should make it impossible.

7

A response arrived for a request that already finished

DUPLICATE-RESPONSE
Symptom

Completion counts exceed request counts. Occasionally a freshly-issued request completes instantly with data belonging to an older transaction.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  unissued response : unknown_resp=1 ; duplicate: dup_resp=1
Evidence

Distinguish a response for a tag never issued from one for a tag that already completed. They have different causes and are found in different places.

Likely Causes

A retry that was not suppressed after the original succeeded; a tag reused before the previous transaction fully drained; a response duplicated by the interconnect.

Debug Sequence

Send a response for a tag never issued — it must be unknown_resp and not a duplicate. Then send a second response for a tag that already completed — it must be dup_resp and not unknown. Measured at 1 each, and neither completes anything: the completion count stays at 4.

Root Cause

The design accepted a response it had no outstanding request for. If it retires a slot on that basis, it completes a transaction that is still in flight.

Fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
assign complete     = resp_en && live_q[sel_tag];   // only a LIVE slot completes
assign dup_resp     = resp_en && !live_q[resp_tag] &&  done_q[resp_tag];
assign unknown_resp = resp_en && !live_q[resp_tag] && !done_q[resp_tag];
Prevention

Never let a tag be reused until its transaction has fully drained, and keep the two rejection counters separate — a duplicate points at the retry logic, an unknown at routing.

8

Every mechanism counter is clean and the data is wrong

END-TO-END
Symptom

Windows close on time, responses match their tags, no conflicts are mishandled, no timeouts fire. A read still returns a value older than a committed write.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  end-to-end staleness : stale reads=1 worst gap=1 reads=7
Evidence

n_stale is the only counter that measures the outcome rather than a mechanism. If it is non-zero while every mechanism counter is clean, there is a path nobody has modelled.

Likely Causes

A bypass path that skips the coherency check; a cache that answers before the invalidation is processed; an ordering assumption between two mechanisms that each behave correctly alone.

Debug Sequence

Read the worst gap as well as the count — how far behind the stale read was. Measured, a gap latched at 8 with a later smaller gap not reducing it. A large gap points at a long-lived stale copy; a gap of one points at a race at the commit boundary.

Root Cause

Correct mechanisms composed into an incorrect system. Every counter measured its own part and none measured the result.

Fix
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
assign stale_read = rd_return && rd_after_write && (rd_val != last_q);
Prevention

Always carry one end-to-end check alongside the mechanism counters. Mechanism coverage does not imply outcome correctness, and only the outcome check can tell you so.

23. Design Review

Cross-link coherency path with tagging, window measurement, serialisation and an end-to-end checkrequeststagged on issueserialisationone order per linewindowmeasured, boundedlinkdelay and reorderingmatcherby identity, not ordertimeoutdelivery is assumedbiasdrain, then swapstale checkdid it work?conflict?revokesendresponseackif stuck12
Figure 4 — The cross-link coherency path assembled. Identity travels with every message, the window is measured, the conflict order is decided in one place, and one check at the end asks whether any of it worked.

What a reviewer should attack first.

Whether every message carries identity. If a response can be matched to a request by arrival order anywhere in the design, it will complete the wrong transaction the first time the link reorders — and the link will.

Whether the grant waits on the acknowledgement or on time. A grant gated on elapsed cycles is a guess about the remote agent's speed, and it will be wrong under load.

Whether the window is latched. A stale read is a past-tense event. Without a latched peak, the evidence is gone before anyone looks.

Where the timeout lives. Coherency has no retransmission. Ask which layer provides it and what happens if that layer does not.

How many serialisation points exist per line. One is correct. Two is two agents each believing they won.

Whether the bias flip drains. A mode bit that flips on request rather than on a drained count produces two views of the same memory.

Whether anything measures the outcome. Mechanism counters can all be clean while the data is wrong.

What is deliberately not here. No message names, opcodes, channels or credits — none is citable. No transient state storage: a line waiting on a remote acknowledgement is neither S nor M, and 13.4 is where that becomes a table. No ownership transfer between host and device — 13.3. No topology, no switch, no fabric manager — Modules 15 and 16.

24. How This Appears In Real Engineering

In architecture review, the number that decides the design is the peak outstanding count, and it is almost always estimated from the average. The measured contrast — peak in-flight 7 against a peak window of 11 — is the shape of that mistake: a table sized for the mean stalls issue at the peak, and issue stalling looks like a link bandwidth problem.

In RTL design, matching by arrival order is the defect that survives the longest, because it works perfectly until the link reorders something. Directed tests almost never reorder, and the first reordering in production completes the wrong transaction.

In verification, the trap is that the interesting cases all require concurrency plus latency. A test with one outstanding request cannot reorder, cannot conflict, and cannot expose a window. The stimulus has to keep several requests alive at once and vary their return order deliberately.

In bring-up, the lost-message hang is the one that looks like a hardware fault and is a missing timeout. One line becomes permanently unusable, no alarm fires, and the system otherwise runs.

In system integration, the direction confusion is the recurring planning error: memory physically attached to a device is not therefore managed by the device, and capacity plans that assume otherwise mispredict both latency and coherency traffic.

25. Common Misconceptions

"A link just makes coherency slower." It makes every protocol step a window, and windows are where the bugs live. The measured exposure window is time during which the old permission is still real.

"Responses come back in order." Measured false: the response for tag 3 arrived before those for tags 0, 1 and 2, and a design matching by order retired tag 0 for it.

"Coherency handles lost messages." It has no retransmission at all. A dropped invalidation stalls the protocol permanently — measured, it took a 12-cycle timeout and a retry to recover.

"Memory attached to the device is managed by the device." Measured false in the direction model: the host manages coherency in both cross-link directions, including for device-attached memory.

"Bias is a mode bit." It is a drain and a swap. Flipping with traffic outstanding leaves two views of the same memory, and the model refuses to complete the flip until the outstanding count reaches zero.

"Whoever asked first wins." Across a link there is no shared notion of first. One serialisation point decides, and both ends accept it.

"The average window is what matters." The peak is what matters. Measured peak_window=11 against samples of 5 and 2 — the average describes a system that never had a problem.

"Clean mechanism counters mean correct behaviour." Every mechanism counter can be clean while an end-to-end stale read is happening. That is what the outcome check is for.

26. Interview Reasoning

27. Exercises

  1. Calculation. A link has a 40-cycle round trip and a request can be issued every 4 cycles. Compute the outstanding-request table depth needed to keep the link busy, the tag width that implies, and the total tag storage if the tag travels in both directions.

  2. Analysis. A design reports a mean exposure window of 6 cycles and a latched peak of 45 on a 10-cycle-round-trip link. State what the mean suggests, what the peak suggests, and which of the two would appear in a stale-read investigation.

  3. RTL task. Extend resp_matcher so a tag cannot be reissued until its transaction has fully drained. State what state that requires, and the failure that becomes possible if a tag is reused one cycle early.

  4. Assertion task. Write the property proving a response retires the request it names. Then explain why this property passes trivially on a design that matches by order when responses happen to return in order, and what stimulus is required to make it meaningful.

  5. Design task. Add a second serialisation point so that two lines can be arbitrated in parallel. State what must be true about the mapping from line to serialisation point, and the failure that occurs if one line can reach both.

  6. Testbench design. Design the stimulus that distinguishes identity matching from order matching. Explain why any test with a single outstanding request passes on both, and state the minimum number of concurrent requests required.

  7. Debug task. A line becomes permanently inaccessible and no alarm fires. Give your investigation order, name the counter that separates a lost message from a slow one, and explain which layer owns the fix.

  8. Design review. A colleague argues that because the host manages coherency for device-attached memory, that memory should be treated as ordinary host memory for capacity planning. Give the strongest version of that argument, then the measurement that shows what it misses.

28. Summary

Distance turns a step into a window.

  • The rules are unchanged. SWMR, the coherence order and the writeback obligation carry over from 13.1 intact. Only the durations change.
  • Every revocation is a window. Measured 4 cycles in the trace and 8 in the cross-link model, with the remote agent holding a readable copy throughout.
  • Responses arrive out of order. With four requests outstanding and tag 3 returning first, identity matching retired tag 3 and order matching retired tag 0 — the wrong transaction, silently.
  • Two rejections, two causes. unknown_resp for a tag never issued and dup_resp for one already completed, measured at 1 each, with a rejected response completing nothing.
  • The window must be latched. Peak 6, unreduced by a later shorter window; a window beyond four round trips raises still_exposed_err rather than waiting forever.
  • Two of four access directions cross the link, and the host manages coherency in both of them — including for memory physically attached to the device.
  • Bias is a drain and a swap. Measured: the flip held while two accesses were outstanding, completed at zero, blocked the host in device bias, and raised unsafe_flip_err on a second request mid-flip.
  • Coherency assumes reliable delivery it does not provide. A dropped invalidation needed a 12-cycle timeout and a retry; without one the protocol stops rather than slows.
  • One serialisation point per line. A simultaneous request produced one winner, the loser queued, and 2 grants in a defined order.
  • One check measures the outcome. Stale reads with a worst gap latched at 8, because every mechanism counter can be clean while the data is wrong.
  • Verification: 109 assertion sites, 57 of 57 mutations killed, zero surviving. Ten first-run escapes were four stimulus gaps, three unobserved outputs, two unreachable checkers needing fault-injection hooks, and one provably equivalent mutation that was replaced rather than recorded.

Next: 13.3 Ownership in CXL, which takes the windows measured here and asks the question they exist to protect: who owns this line right now, and what has to happen for that answer to change.

Continue learning

Related tutorials

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.