Skip to content

AMBA CHI · Module 6 · CHI Channels

The Snoop Channel (SNP)

Three channels down; SNP is the fourth — the only one that flows from the Home Node to the requesters. This chapter opens the snoop channel: its packet fields — a snoop opcode, the address, the Home Node as source, a transaction ID, and RetToSrc; the snoop request types — SnpShared, SnpUnique, SnpOnce, and the clean/invalidate variants; and its two defining behaviors. First, home-to-RN routing: the Home Node consults its directory and snoops exactly the holders, by Node ID — targeted, not broadcast. Second, RetToSrc tells the snooped cache whether to return data, so data moves only when needed. This chapter details SNP and completes the four-channel tour. Representative model, not the specification.

Intermediate15 min readAMBA CHISNPSnoopsRetToSrcDirectory

Module 6 · Chapter 6.5 · CHI Channels

Project thread — 6.2–6.4 covered REQ, RSP, and DAT. This chapter takes SNP, the last channel, and closes the four-channel tour. 6.6 looks at the fields they share.

1. Learning Outcomes

By the end of this chapter you should be able to:

  • List the key fields of a SNP packet — snoop opcode, Addr, SrcID (the HN), TxnID, RetToSrc.
  • Name the snoop request types — SnpShared, SnpClean, SnpUnique, SnpOnce, SnpCleanInvalid.
  • Explain why SNP is the only channel that flows Home Node → Requester.
  • Describe directory-driven routing: the HN snoops exactly the holders, by Node ID.
  • State what RetToSrc controls and why dirty data must be returned regardless.
  • Implement a representative snoop data-return decision in SystemVerilog, Verilog-2001, and VHDL.

2. Why Should I Learn This?

SNP is how the Home Node reaches into caches — the channel that makes coherency happen at the requesters. Reading it is how you know what a snoop is asking of a cache: share, invalidate, or peek. And it is the only channel flowing home-to-requester, which shapes how the fabric routes and buffers it.

Its practical subtlety is RetToSrc and dirty data. A snoop can ask for data or not, to avoid needless movement — but a dirty line must return its data whichever way RetToSrc points, or the only current copy is lost. Getting that interaction right is the correctness lesson of this chapter.

3. Key Terms

4. Previous Chapter Connection

Chapters 6.2–6.4 covered REQ (requests, RN→HN), RSP (responses), and DAT (payload). The snoop responses those chapters kept referring to — SnpResp on RSP, SnpRespData on DAT — answer something: the snoop itself.

That snoop travels on SNP, this chapter's subject and the fourth channel. It is the one channel that flows the other way — Home Node to requester — and it is how the directory (Chapters 3.5, 5.3) reaches the exact caches that hold a line. With SNP, the four-channel picture is complete.

5. Core Concept — the home reaching into caches

SNP is the Home Node's channel for querying and changing cached copies.

  • The packet. A SNP flit carries the snoop opcode (what to do), the Addr (which line), SrcID (the Home Node), a snoop TxnID (which the snooped cache echoes in its response), and RetToSrc (whether to return data). No payload — snoop data comes back on DAT.
  • The snoop request types. SnpShared (become Shared — downgrade), SnpClean (become Shared-Clean), SnpUnique (invalidate — the requester wants exclusive), SnpOnce (read the current value without changing state — for ReadOnce), SnpCleanInvalid (write back dirty, then invalidate), SnpMakeInvalid (invalidate, data discarded). Each maps to a cache-side transition (Chapters 5.1, 5.7).
  • Home-to-RN routing. SNP is the only channel flowing Home Node → Requester. The HN consults its directory, finds exactly which caches hold the line, and sends a SNP to each of those by Node ID — targeted, not broadcast (Chapters 3.5, 5.3).
  • RetToSrc — data only when needed. The RetToSrc field tells the snooped cache whether to return the line's data (SnpRespData on DAT) or only its state (SnpResp on RSP). This avoids moving data the Home Node does not need — but a dirty line must return its data regardless, or the current value is lost.

The synthesis:

SNP is the home reaching into caches — the one channel that flows Home-to-RN, carrying a snoop opcode (share / invalidate / clean / peek) to exactly the holders the directory names. RetToSrc trims data movement to what is needed, with one hard exception: a dirty line always returns its data. Read SNP to know what the home is asking of a cache, and to whom.

6. Engineering Mental Model — the registrar's callbacks

Return to the registrar (the Home Node). REQ was citizens filing requests; SNP is the registrar's callbacks to the people who hold copies.

  • The registrar checks the ledger (directory) to see exactly who holds a record, and rings only those people (targeted, by name) — never a mass announcement.
  • Each call carries an instruction: "make your copy read-only" (SnpShared), "return and destroy yours" (SnpUnique), "just tell me the current value" (SnpOnce).
  • The registrar also says whether it needs the document back (RetToSrc) — to save effort, it often only needs a status. But if the person's copy is marked up (dirty), they must hand it back regardless, because theirs is the only up-to-date version and it cannot be lost.

Targeted callbacks with per-call instructions, and a rule that marked-up copies always come back — that is SNP.

7. Engineering Diagram — the SNP packet

Fields of a CHI SNP packet: a snoop Opcode such as SnpShared or SnpUnique; the Addr of the line being snooped; SrcID the Home Node that issued the snoop; a snoop TxnID the responding cache echoes in its SnpResp; and RetToSrc, a flag saying whether the snooped cache should return the data. The SNP packet carries no data payload.OpcodeSnpShared · SnpUniqueAddrline snoopedSrcIDthe Home NodeTxnIDechoed in SnpRespRetToSrcreturn data?12
Figure 1 — the fields of a SNP packet. A snoop Opcode (SnpShared, SnpUnique…); the Addr of the line; SrcID, the Home Node that issued it; a snoop TxnID the responding cache echoes; and RetToSrc, whether the cache should return data. No payload — snoop data returns on DAT.

Five fields, no payload. The opcode says what to do; Addr says to which line; SrcID/TxnID tie the response back to the home; RetToSrc says whether to send data.

8. Snoop Request Types

The opcode tells the cache what to do with its copy. A representative set, mapped to the cache-side effect:

SnoopAsks the cache toCache effect
SnpSharedbecome SharedUnique → Shared (downgrade)
SnpCleanbecome Shared-Cleanclean + downgrade
SnpUniquegive up the lineany → Invalid (requester wants exclusive)
SnpOncereveal the value, keep your stateno state change (for ReadOnce)
SnpCleanInvalidwrite back dirty, then invalidatedirty → memory, then Invalid
SnpMakeInvalidinvalidate, data discardedany → Invalid, no data

Two facts to carry: the snoop opcode selects the cache's transition (Chapters 5.1, 5.7), and SnpOnce is special — it reads the current value without changing the cache's state, exactly what a cacheless ReadOnce needs (Chapter 5.2). The home picks the snoop that matches the requester's intent.

9. Home-to-RN Routing and RetToSrc

Two behaviors set SNP apart from the other channels.

  • It flows home-to-requester, targeted. SNP is the only channel from the Home Node to a Request Node. The HN reads its directory, learns exactly which caches hold the line, and sends a SNP to each by Node ID. No broadcast — only the actual holders are snooped (the directory payoff, Chapters 3.5, 5.3).
  • RetToSrc trims data movement. The RetToSrc field tells the snooped cache whether to return the line's data. If the home already has the data (or memory is current and clean), it sets RetToSrc = 0 and the cache replies SnpResp only (state, no data). If it needs the data, RetToSrc = 1 and the cache replies SnpRespData.
  • The dirty exception. RetToSrc is an optimization for clean lines. A dirty line holds the only current value, so a snoop that removes or downgrades it must return that data — regardless of RetToSrc — or the value is lost.

The point to carry:

The home snoops only the holders (directory-driven, Node-ID routed), and asks for data only when needed (RetToSrc) — two efficiencies. But the one non-negotiable: a dirty line always returns its data on a removing/downgrading snoop, because it is the sole current copy. RetToSrc controls clean data movement; dirty data is never optional.

10. The Snoop Handshake

A snoop of a dirty line shows SNP with its RSP/DAT responses.

A snoop: SnpShared out, SnpResp + SnpRespData back

6 cycles
A snoop: SnpShared out, SnpResp + SnpRespData backsnoop sent (SNP)snoopsent…response + dataresponse + dataSnpShared: home snoops the holderSnpShared: home snoops theholderSnpResp: cache's resulting stateSnpResp: cache's resultingstateSnpRespData: dirty data returnedSnpRespData: dirty datareturnedCLKSNPSnpSharedSnpSharedSnpSharedSnpSharedSnpSharedSnpSharedRSP00SnpRespSnpRespSnpRespSnpRespDAT000SnpRespDataSnpRespDataSnpRespDatat0t1t2t3t4t5
Figure 2 — a SnpShared to a cache holding the line dirty. The Home Node sends the snoop on SNP; the cache responds on RSP with its snoop response (state) and, because the line is dirty, supplies the data on DAT as SnpRespData. SNP flows home-to-cache; the response flows cache-to-home on RSP and DAT.

The snoop went out on SNP; the response came back on RSP (state) and DAT (the dirty data). Had the line been clean with RetToSrc = 0, there would be a SnpResp on RSP and no DAT beat.

11. RTL / Hardware View — the snoop data-return decision

The cache-side rule for returning data: supply it when the snoop asks (RetToSrc) or when the line is dirty (must not be lost). Here is that decision. Representative and combinational.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Representative snoop data-return decision, RN side (educational).
// A snooped cache returns data (SnpRespData on DAT) when the snoop's RetToSrc
// requests it, OR when the line is DIRTY (its data is the only current copy and
// must not be lost). Otherwise it returns SnpResp only. A snoop always responds.
module snp_data_return (
  input  logic dirty,        // this cache holds the line dirty (UD/SD)
  input  logic ret_to_src,   // snoop RetToSrc: the requester/home needs the data
  output logic send_data,    // send SnpRespData on DAT
  output logic send_resp     // send SnpResp on RSP (always)
);
  assign send_data = dirty || ret_to_src;   // dirty MUST supply; RetToSrc requests
  assign send_resp = 1'b1;                    // every snoop gets a response
endmodule

The same behavior in Verilog-2001:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Representative snoop data-return decision (Verilog-2001).
module snp_data_return (
  input  dirty, ret_to_src,
  output send_data, send_resp
);
  assign send_data = dirty | ret_to_src;
  assign send_resp = 1'b1;
endmodule

And in VHDL:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- Representative snoop data-return decision (VHDL).
library ieee;
use ieee.std_logic_1164.all;
 
entity snp_data_return is
  port (
    dirty, ret_to_src    : in  std_logic;
    send_data, send_resp : out std_logic
  );
end entity;
 
architecture rtl of snp_data_return is
begin
  send_data <= dirty or ret_to_src;   -- dirty must supply, or RetToSrc requests
  send_resp <= '1';                    -- every snoop responds
end architecture;

All three return data when the line is dirty or RetToSrc is set, and always send a response. The dirty || term is the safety net — it makes dirty data supply even when RetToSrc is 0 — and dropping it is the DebugLab.

12. Verification View — dirty always supplies; clean follows RetToSrc

Two properties: a dirty line always returns data, and every snoop gets a response.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Bind to snp_data_return.
// 1. A dirty line always returns its data — regardless of RetToSrc.
property p_dirty_supplies;
  @(*) dirty |-> send_data;
endproperty
 
// 2. A clean line returns data iff RetToSrc requests it.
property p_clean_follows_rettosrc;
  @(*) (!dirty) |-> (send_data == ret_to_src);
endproperty

The system point, beyond the two checks:

RetToSrc is an optimization, not a licence to drop data. Its purpose is to avoid moving a clean copy the home does not need — clean data is identical to memory, so returning it is often wasteful. But a dirty line is the only place the current value lives, so a snoop that removes or downgrades it must return that data whatever RetToSrc says. Conditioning data return on RetToSrc alone silently loses dirty data — a no-lost-update violation (Chapters 5.1, 5.3). Two rules, both required: clean follows RetToSrc; dirty always supplies.

  • What it proves: dirty always supplies; clean follows RetToSrc.
  • What it does not prove: the cache's state transition (Chapters 5.1, 5.7).
  • Bug signature: dirty data not returned when RetToSrc is 0 — a lost update (the DebugLab).

13. Testbench — data-return across dirty and RetToSrc

Checks the four combinations of dirty and RetToSrc.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module tb_snp_data_return;
  logic dirty, ret_to_src, send_data, send_resp;
  int errors = 0;
 
  snp_data_return dut (.*);
 
  task automatic check(input logic d, input logic r, input logic exp_data, input string tag);
    dirty = d; ret_to_src = r; #1;
    if (send_data !== exp_data || send_resp !== 1'b1) begin
      errors++; $display("FAIL [%s] send_data=%b send_resp=%b", tag, send_data, send_resp);
    end else $display("PASS [%s] send_data=%b", tag, send_data);
  endtask
 
  initial begin
    check(1'b0, 1'b0, 1'b0, "clean, RetToSrc=0 -> no data");
    check(1'b0, 1'b1, 1'b1, "clean, RetToSrc=1 -> data");
    check(1'b1, 1'b0, 1'b1, "DIRTY, RetToSrc=0 -> data (must supply)");
    check(1'b1, 1'b1, 1'b1, "dirty, RetToSrc=1 -> data");
 
    if (errors == 0) $display("ALL TESTS PASSED");
    else             $display("%0d FAILURE(S)", errors);
    $finish;
  end
endmodule

Expected output:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
PASS [clean, RetToSrc=0 -> no data] send_data=0
PASS [clean, RetToSrc=1 -> data] send_data=1
PASS [DIRTY, RetToSrc=0 -> data (must supply)] send_data=1
PASS [dirty, RetToSrc=1 -> data] send_data=1

14. DebugLab — returning data only when RetToSrc is set

1

Returning data only when RetToSrc is set

DATA RETURN GATED ON RetToSrc ALONE -> DIRTY DATA LOST
Symptom

A value one core wrote disappears: another core's read of the same line returns the old data, even though the writer had it cached and modified. It only happens for lines that were dirty in a cache and then snooped.

Evidence

A dirty line snooped with RetToSrc = 0, returning no data:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
dirty  ret_to_src  send_data  note
  1        0          0        WRONG: dirty line returns no data

The line was dirty, but because RetToSrc was 0 the cache sent SnpResp only — the modified data was never returned.

First Divergence

The snoop-response computed send_data = ret_to_src — data return conditioned on RetToSrc alone. From a dirty-line snoop with RetToSrc = 0, the dirty data is dropped, and the Home Node has only stale memory to complete with.

Root Cause

RetToSrc governs whether a clean copy is worth returning — clean data equals memory, so it is often skipped. But a dirty line holds the only current value; a snoop that removes or downgrades it must return that data or it is lost. Gating data return on RetToSrc alone forgets the dirty case, so modified data vanishes — the classic no-lost-update violation.

Fix

Return data when the line is dirty OR RetToSrc is set: send_data = dirty || ret_to_src. Clean lines follow RetToSrc (the intended optimization); dirty lines always supply their data. Verify "dirty implies send_data" as an invariant so the dirty case can never be optimized away. RetToSrc trims clean-data movement; it never overrides the duty to preserve dirty data.

15. Common Mistakes

  • Gating data return on RetToSrc alone. Assumption: RetToSrc decides everything. Bug: dirty data lost (the DebugLab). Prevention: dirty or RetToSrc returns data.
  • Broadcasting snoops. Assumption: snoop everyone. Bug: wasted traffic (Chapter 3.5). Prevention: the directory names the holders; snoop only them.
  • Wrong snoop type. Assumption: any snoop works. Bug: sharing when you meant to invalidate. Prevention: SnpShared downgrades, SnpUnique invalidates, SnpOnce peeks.
  • Snooping the wrong direction. Assumption: snoops can flow any way. Bug: mis-routed. Prevention: SNP is Home Node → Requester only.
  • Ignoring SnpOnce's no-change rule. Assumption: every snoop changes state. Bug: needlessly downgrading on a peek. Prevention: SnpOnce reads without changing state.
  • Losing the response TxnID. Assumption: any correlation works. Bug: mis-matched snoop response. Prevention: echo the snoop's TxnID in SnpResp.

16. Engineering Checklist

  • Route SNP Home Node → Requester, to the directory's holders by Node ID.
  • Select the snoop opcode by intent (SnpShared / SnpUnique / SnpClean / SnpOnce).
  • Return data when the line is dirty OR RetToSrc is set.
  • Never drop dirty data on a removing/downgrading snoop.
  • Keep SnpOnce state-preserving (a peek).
  • Echo the snoop's TxnID in the SnpResp / SnpRespData.

17. Key Takeaways

  • SNP is the only channel that flows Home Node → Requester — the home reaching into caches.
  • Its fields: snoop opcode, Addr, SrcID (the HN), TxnID, RetToSrc.
  • Snoop types select the cache's transition: SnpShared (downgrade), SnpUnique (invalidate), SnpOnce (peek), and clean/invalidate variants.
  • The home snoops only the directory's holders, by Node ID — targeted, not broadcast.
  • RetToSrc trims clean-data movement; a dirty line always returns its data regardless.
  • Gating data return on RetToSrc alone loses dirty data; the model here is representative.

18. Quick Revision

The SNP channel. The only channel flowing Home Node → Requester — the home reaching into caches. Fields: snoop opcode, Addr, SrcID (the HN), snoop TxnID (echoed in the response), RetToSrc. Snoop types map to cache transitions: SnpShared (downgrade to Shared), SnpClean, SnpUnique (invalidate), SnpOnce (read without changing state — for ReadOnce), SnpCleanInvalid, SnpMakeInvalid. Routing is directory-driven: the HN snoops only the holders, by Node ID (targeted, not broadcast). RetToSrc says whether the cache returns data — an optimization for clean lines (clean data equals memory) — but a dirty line always returns its data (dirty OR RetToSrc), or the only current value is lost. The response is SnpResp (RSP) plus SnpRespData (DAT) when data is returned. Representative model; 6.6 covers packet common fields.

Coming Next

Chapter 6.6 — Packet Common Fields. The four channels are covered; the next chapter steps back to what they share. Several fields recur across REQ, RSP, DAT, and SNP — the TxnID that ties a transaction together, the Node IDs (SrcID/TgtID) the fabric routes on, and the Opcode that names each message. Chapter 6.6 details these common fields once, so you can read any packet on any channel by recognizing the shared skeleton beneath its channel-specific payload.