The course model let H assume it knew when a grant had been delivered. CHI makes that a message: CompAck. Sections 2.8.3 and 4.11.2 of the AMBA 5 CHI Architecture Specification, Arm IHI 0050, Issue E.a say that an HN-F waits for CompAck (except for ReadOnce* and ReadNoSnp) before sending another snoop to the same address, and that for CopyBack writes the WriteData acts as an implicit CompAck. That is trace c of Racing Requests at the Home. The three walkthroughs below reuse earlier traces and keep their roles.
This extends the direct variant of Dirty Intervention: C0 holds UD / 7 (the course's M / 7), memory = 0, C1 reads. With DCT the snooped RN-F sends CompData straight to the requester, the three-hop route of Three-Hop Versus Four-Hop. The flow follows the spec's Figure 5-4, where C0 keeps SC and passes the dirty line to the home.
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
Checkpoint | UD / 7 | I / - | exclusive(C0) | 0 | C0: 7 |
1. ReadShared at H | UD / 7 | IS^D / - | exclusive(C0), pend ReadShared C1 | 0 | C0: 7 |
2. SnpSharedFwd at C0 | SC / 7 | IS^D / - | exclusive(C0), pend ReadShared C1 | 0 | C0: 7, Data(7) in flight to C1 and to H |
3. CompData_SC at C1 | SC / 7 | SC / 7 | exclusive(C0), pend ReadShared C1 | 0 | C0 and C1: 7, Data(7) in flight to H |
4. SnpRespData at H | SC / 7 | SC / 7 | exclusive(C0), pend ReadShared C1 | 0 | C0, C1 and H buffer: 7 |
H writes memory | SC / 7 | SC / 7 | S{C0}, pend ReadShared C1 | 7 | C0, C1 and memory: 7 |
5. CompAck at H | SC / 7 | SC / 7 | S{C0,C1} | 7 | C0, C1 and memory: 7 |
Messages 3 and 4 travel on different channels and may arrive in either order (the spec says so for Figure 5-3). CompAck may be sent as soon as the first CompData packet arrives. Row 5 replaces the course's '(assumed) grant delivered' row. Table 4-34 also permits C0 to keep SD and send only SnpResp_SD_Fwded_SC with no data to the home, leaving memory stale: the MOESI ending, with no memory write.
Start from Upgrade from Shared: C0 and C1 hold SC / 0, H S{C0,C1}, memory = 0, and C0 wants to store. CleanUnique asks for unique permission without data. The snoop is the one Table 4-5 expects, as for RN-F2 in Figure 5-12.
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
Checkpoint | SC / 0 | SC / 0 | S{C0,C1} | 0 | C0, C1 and memory: 0 |
1. CleanUnique at H | SM^D / 0 | SC / 0 | S{C0,C1}, pend CleanUnique C0, acks 0/1 | 0 | C0, C1 and memory: 0 |
2. SnpCleanInvalid at C1 | SM^D / 0 | I / - | S{C0,C1}, pend CleanUnique C0, acks 0/1 | 0 | C0 and memory: 0 |
3. SnpResp_I at H | SM^D / 0 | I / - | S{C0}, pend CleanUnique C0, acks 1/1 | 0 | C0 and memory: 0 |
4. Comp_UC at C0 | UC / 0 | I / - | S{C0}, pend CleanUnique C0, acks 1/1 | 0 | C0 and memory: 0 |
5. CompAck at H | UC / 0 | I / - | exclusive(C0) | 0 | C0 and memory: 0 |
L. Local store | UD / 1 | I / - | exclusive(C0) | 0 | C0: 1 |
SM^D is the course's transient label; CHI does not name transient states. Comp_UC gives UC, the CHI name for E, and the store makes it UD silently, like E to M. If C0's SC copy is invalidated by a competing request before Comp_UC arrives (the race in Simultaneous Upgrades), CHI still completes the CleanUnique, and C0 ends in UCE: unique permission with no valid bytes (section 4.1.1). A partial store then makes it UDP. Issue E.a also adds MakeReadUnique, which returns data if the requester's copy was lost.
From Dirty Writeback: C0 holds UD / 3 (the course's M / 3), memory = 0, and evicts X. CHI reverses the course order: the home answers first with a buffer identifier, then the data follows (Figure 5-17).
Step | C0 state / value | C1 state / value | H directory | Memory | Newest data |
|---|---|---|---|---|---|
0. Warm start | UD / 3 | I / - | exclusive(C0) | 0 | C0: 3 |
C0 evicts X | MI^A / 3 (in WB) | I / - | exclusive(C0) | 0 | C0 WB entry: 3 |
1. WriteBackFull at H | MI^A / 3 (in WB) | I / - | exclusive(C0), pend WriteBackFull C0 | 0 | C0 WB entry: 3 |
2. CompDBIDResp at C0, data sent | I / - | I / - | exclusive(C0), pend WriteBackFull C0 | 0 | Data(3) in flight to H |
3. CopyBackWrData at H | I / - | I / - | exclusive(C0), pend WriteBackFull C0 | 0 | H buffer: 3 |
H writes memory | I / - | I / - | U | 3 | memory: 3 |
After step 2 C0 holds nothing, so the home's buffer holds the only copy, as in the early Put-Ack variant: the home must keep its tracker and serve or stall any new request for X until memory is written. If a snoop for X reaches C0 between steps 1 and 2, C0 answers it normally, and the CopyBackWrData then reports the state after the snoop, possibly with no valid data (section 4.11.1).
Course message | CHI in these flows | Note |
|---|---|---|
GetS | ReadShared | Also ReadClean and ReadNotSharedDirty |
Fwd-GetS | SnpSharedFwd (DCT) or SnpShared (data to home) | Fwd variants carry FwdNID and FwdTxnID |
GetM from S | CleanUnique | ReadUnique from I, MakeUnique for full-line stores |
Inv, Inv-Ack | SnpCleanInvalid, SnpResp_I | Acks collected at the home |
Data | CompData_xx or Comp_xx | The suffix names the state granted |
PutM, Put-Ack | WriteBackFull, CompDBIDResp, CopyBackWrData | Ack before data |
(assumed) grant delivered | CompAck | Or the write data for copy-backs |
No. CompAck says C1 has its data, but the dirty copy and responsibility are still in flight to H and memory = 0. H must wait for the snoop response, write memory (or record the dirty holder), and only then close the transaction.