The completion message that the course left as an assumption. This lesson uses the SiFive TileLink Specification, version 1.8.1 (27 January 2020), sections 9.2 and 9.3. TL-C has three operations: Acquire grows a cache's permission, Probe forcibly prunes it, and Release prunes it voluntarily. Every Acquire ends with a Grant and a GrantAck.
TileLink 1.8.1 message | Channel | Parameter | Course message | Note |
|---|---|---|---|---|
AcquireBlock NtoB | A | Grow | GetS | Grant may be toT: the MESI E grant |
AcquireBlock NtoT | A | Grow | GetM from I | Needs data |
AcquireBlock BtoT | A | Grow | GetM upgrade from S | Answered by Grant or GrantData, see below |
AcquirePerm | A | Grow | No direct equivalent | Permission only, for a block that will be entirely overwritten. Never returns data. |
ProbeBlock toN | B | Cap | Inv, or Fwd-GetM to an exclusive holder | Answer may carry data |
ProbeBlock toB | B | Cap | Fwd-GetS | Downgrade an exclusive holder to Branch |
ProbePerm | B | Cap | Inv without data | No data is ever returned |
ProbeAck, ProbeAckData | C | Prune or Report | Inv-Ack, Data to H | Data only when the home needs dirty data |
Grant, GrantData | D | Cap | Data with permission (Grant has no data) | Always sent by the slave |
GrantAck | E | None | Complete (Part 4, trace c) | Mandatory for every Grant |
Release BtoN, Release TtoN | C | Prune | PutS, PutE | Clean voluntary eviction |
ReleaseData TtoN | C | Prune | PutM | Dirty voluntary eviction |
ReleaseAck | D | None | Put-Ack | Acknowledges completion of the writeback |
All Probe answers go to the slave and every Grant comes from it: in TL-C a master only ever talks to the agent at the other end of its link. So a TileLink transfer is the course's four-hop, H-buffered route, never the three-hop direct one.
Take the MSI dirty read from MSI Protocol with the same roles and step numbers: C0 holds M / 1, C1 reads. The course trace ended with an assumed delivery. TileLink makes it a fifth message.
Step | TileLink message | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|---|
Checkpoint | - | M / 1 (T) | I / - (N) | exclusive(C0) | 0 | C0: 1 |
1. at H | AcquireBlock NtoB | M / 1 (T) | IS^D / - (N) | exclusive(C0), pend AcquireBlock C1 | 0 | C0: 1 |
2. at C0 | ProbeBlock toB | S / 1 (B) | IS^D / - (N) | exclusive(C0), pend AcquireBlock C1 | 0 | C0: 1, Data(1) in flight to H |
3. at H | ProbeAckData TtoB | S / 1 (B) | IS^D / - (N) | exclusive(C0), pend AcquireBlock C1 | 0 | C0 and H buffer: 1 |
H writes memory | - | S / 1 (B) | IS^D / - (N) | S{C0}, pend AcquireBlock C1 | 1 | C0 and memory: 1, Data(1) in flight to C1 |
4. at C1 | GrantData toB | S / 1 (B) | S / 1 (B) | S{C0}, pend AcquireBlock C1 | 1 | C0, C1 and memory: 1 |
5. at H | GrantAck | S / 1 (B) | S / 1 (B) | S{C0,C1} | 1 | C0, C1 and memory: 1 |
Two points to notice. At step 3 the TtoB parameter states C0's new permission, so a TileLink manager may record C0 as a Branch at once. The table follows the course's own rule instead: H keeps exclusive(C0) until it has written memory, because S{C0} in the course notation claims memory is current, and records S{C0} in the "H writes memory" row. At step 4 H's entry does not change, because nothing reached H; only GrantAck at step 5 lets H record C1 and start the next transaction for X. Where H keeps the dirty data (memory or an outer cache) is the implementation's coherence policy; the specification defines messages, not policy. The write is shown to keep this an MSI trace.
Section 9.2 states the rule this enforces: once the Grant is issued, the slave should not issue Probes on that block until it receives GrantAck. TileLink does not assume point-to-point ordered delivery, so without GrantAck a Probe for C1 could overtake its GrantData. That is exactly the race in Racing Requests at the Home, and GrantAck is its trace c remedy.
An S-to-M upgrade is AcquireBlock BtoT. If C0 has not been probed since it sent the Acquire, H may answer with Grant (no data), like the permission-only Data in Upgrade from Shared. Section 9.2 requires an up-to-date copy of the data, GrantData, in any other case: if a ProbeBlock toN removed C0's Branch while its Acquire was queued, C0 no longer has the bytes. That is the "lost its copy while waiting" case the course upgrade lesson excluded, resolved by a rule at the home.
Now the eviction race from Eviction Versus Intervention, order B, with the same roles: C0 holds M / 1 and evicts with ReleaseData TtoN while C1's AcquireBlock NtoB wins at H. In the course, C0 in MI^A answers the Fwd at once from its writeback buffer. TileLink chooses the opposite rule (section 9.2): a master with an outstanding Release should not issue ProbeAcks until it receives ReleaseAck, and section 9.2 repeats that it cannot respond to the Probe before then. The slave must therefore accept the Release while its Probe is outstanding, because the ProbeAck could be stuck behind that Release in the network.
Step | TileLink message | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|---|
Checkpoint | - | M / 1 (T) | I / - (N) | exclusive(C0) | 0 | C0: 1 |
C0 evicts | - | MI^A / 1 (in WB) | I / - (N) | exclusive(C0) | 0 | C0 WB: 1, ReleaseData(1) in flight to H |
1. at H | AcquireBlock NtoB | MI^A / 1 (in WB) | IS^D / - (N) | exclusive(C0), pend AcquireBlock C1 | 0 | C0 WB: 1, ReleaseData(1) in flight to H |
2. at C0, held | ProbeBlock toB | MI^A / 1 (in WB) | IS^D / - (N) | exclusive(C0), pend AcquireBlock C1 | 0 | C0 WB: 1, ReleaseData(1) in flight to H |
3. at H | ReleaseData TtoN | MI^A / 1 (in WB) | IS^D / - (N) | U, pend AcquireBlock C1, acks 0/1 | 0 | C0 WB and H buffer: 1 |
H writes memory | - | MI^A / 1 (in WB) | IS^D / - (N) | U, pend AcquireBlock C1, acks 0/1 | 1 | C0 WB, H buffer and memory: 1 |
4. at C0 | ReleaseAck | I / - (N) | IS^D / - (N) | U, pend AcquireBlock C1, acks 0/1 | 1 | H buffer and memory: 1 |
5. at H | ProbeAck NtoN | I / - (N) | IS^D / - (N) | U, pend AcquireBlock C1, acks 1/1 | 1 | H buffer and memory: 1, Data(1) in flight to C1 |
6. at C1 | GrantData toB | I / - (N) | S / 1 (B) | U, pend AcquireBlock C1, acks 1/1 | 1 | C1 and memory: 1 |
7. at H | GrantAck | I / - (N) | S / 1 (B) | S{C1} | 1 | C1 and memory: 1 |
Both designs are correct; they put the merge in different places. The course lets the cache answer from its buffer and makes H treat the late PutM as a Put from a non-holder. TileLink keeps the cache simple (hold the Probe) and makes the home merge the two flows: it accepts the Release on channel C, acknowledges it, collects the ProbeAck, and only then sends the Grant. Since C0 ends with nothing, H could also grant toT here; toB keeps the comparison with the course trace.
Section 9.2: the slave should not issue a Probe on the block while the GrantAck is pending. Without ordered delivery, a ProbeBlock toN could reach C1 before its GrantData, and C1 would later install a stale Branch after acknowledging the Probe. GrantAck proves the Grant arrived, so the Probe is safely ordered after it.