Skip to content

AMBA CHI · Module 6 · CHI Channels

The Four CHI Channels

CHI carries every transaction on four channels: REQ for requests, RSP for responses without data, DAT for data, and SNP for snoops. Module 4 named them; this chapter opens Module 6 by detailing each — what it carries, which way it flows, and why they are orthogonal. Orthogonal means independent: each channel is a distinct message class with its own flow control, so a large DAT transfer never blocks a REQ, and an RSP always flows regardless of request congestion. A single transaction uses several channels — a read touches REQ, SNP, RSP, and DAT — and their packets can arrive in any order. This chapter is the foundation of Module 6. Representative model, not the specification.

Foundation15 min readAMBA CHIChannelsREQRSPDATSNP

Module 6 · Chapter 6.1 · CHI Channels — module opener

Project thread — Module 5 built the nodes; Module 6 opens the channels they exchange. This chapter surveys all four; 6.2 onward details each in turn.

1. Learning Outcomes

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

  • Name the four CHI channels — REQ, RSP, DAT, SNP — and what each carries.
  • State each channel's direction: REQ (RN→HN), SNP (HN→RN), RSP and DAT (both ways).
  • Explain channel orthogonality — independent message classes with independent flow control.
  • Trace how a single transaction uses several channels, whose packets may arrive in any order.
  • Recognize that assuming a cross-channel arrival order is a bug.
  • Implement a representative multi-channel completion tracker in SystemVerilog, Verilog-2001, and VHDL.

2. Why Should I Learn This?

The four channels are the alphabet of every CHI transaction. Once you can say which channel carries which message and which way it flows, any transaction flow — read, write, snoop, atomic — reads as a short score across four staves. The rest of Module 6 details each channel; this chapter is the map that makes them fit together.

The most important idea here is orthogonality, and it is where beginners stumble. The channels are independent: their packets arrive in whatever order the fabric delivers them, and a transaction completes when the required packets have all arrived — not in a fixed sequence. Internalize that and a whole class of ordering bugs disappears.

3. Key Terms

4. Previous Chapter Connection

Chapter 4.1 introduced the four channels as part of the CHI mental model, and Chapter 5.9 showed the fabric keeps them on separate virtual channels so they cannot deadlock one another. Both established that the channels are independent.

This chapter builds on that independence and details it. It says exactly what each channel carries, which way it flows, and how a single transaction spreads across several channels whose packets arrive in any order. Where 4.1 was the sketch and 5.9 was the fabric guarantee, 6.1 is the working definition of the four channels — and the launch point for the rest of Module 6.

5. Core Concept — four channels, orthogonal

CHI splits all traffic into four channels, each a distinct message class flowing independently.

  • REQ — requests. From a Request Node to a Home Node: ReadShared, ReadUnique, MakeUnique, WriteBack, and the rest. Carries opcode, address, SrcID, TgtID, TxnID. This is where transactions begin.
  • RSP — responses without data. Both directions: completions (Comp), completion acknowledgements (CompAck), snoop responses (SnpResp), buffer grants (DBIDResp), and retries (RetryAck). Control, no payload.
  • DAT — data. Both directions: read data (CompData), write data (WriteData), snoop data. Carries the actual payload plus a DBID and IDs. This is the only channel with bulk data.
  • SNP — snoops. From a Home Node to a Request Node: SnpShared, SnpUnique. Carries the snoop opcode, address, and IDs. This is how the home reaches cached copies.

And the property that ties them together:

The four channels are orthogonal — independent message classes, each with its own flow control (separate virtual channels, Chapter 5.9). So data never blocks control (a big DAT transfer does not stall a REQ or RSP), responses always flow (RSP is independent of REQ congestion — the anti-deadlock property), and a transaction's packets arrive in any order (its DAT and RSP are independent; it completes when both are in, whichever came first). Four separate lanes, not one shared road.

6. Engineering Mental Model — four independent conveyor belts

Picture a sorting facility with four separate conveyor belts, one per item type.

  • The orders belt (REQ) carries work requests in; the receipts belt (RSP) carries confirmations; the goods belt (DAT) carries the actual products; the inquiries belt (SNP) carries "does anyone have this?" checks out.
  • Each belt runs at its own speed and never jams the others: a flood of bulky goods (DAT) does not slow the paper receipts (RSP), and receipts keep moving no matter how backed up the orders belt is.
  • A single job rides several belts — an order in (REQ), an inquiry out (SNP), a confirmation and the goods back (RSP, DAT) — and the pieces arrive whenever their belt delivers them, in any order. The job is done when all its pieces are in, not when they arrive in a particular sequence.

Four belts, independent, a job spread across them — that is the four CHI channels.

7. Engineering Diagram — the four channels

The four CHI channels. REQ carries requests from Request Node to Home Node. RSP carries responses without data in both directions, such as Comp and CompAck. DAT carries data in both directions, such as CompData and WriteData. SNP carries snoops from Home Node to Request Node. Each channel is an independent message class with its own flow control.REQ · RequestRN -> HN · opcode, addr,IDsRSP · Responseboth ways · no data (Comp,CompAck)DAT · Databoth ways · payload + DBIDSNP · SnoopHN -> RN · snoop opcode,addr12
Figure 1 — the four CHI channels as a map: REQ (requests, RN to HN), RSP (responses without data, both ways), DAT (data, both ways), and SNP (snoops, HN to RN). Each is an independent message class with its own flow control; a transaction uses several of them, and their packets arrive in any order.

Read it as a legend: four message classes, four directions, one payload channel (DAT). Every transaction is built from these four, used in whatever combination it needs.

8. The Four Channels in Detail

Each channel's role, direction, and representative messages.

ChannelCarriesDirectionExamples
REQrequestsRN → HNReadShared, ReadUnique, MakeUnique, WriteBack
RSPresponses without databoth waysComp, CompAck, SnpResp, DBIDResp, RetryAck
DATdataboth waysCompData, WriteData, SnpRespData
SNPsnoopsHN → RNSnpShared, SnpUnique, SnpClean

Two facts to carry: only DAT carries payload — the other three are control — and the directions differ (REQ and SNP are one-way opposites; RSP and DAT are bidirectional). Knowing which channel a message rides, and which way, is the first step in reading any transaction.

9. A Transaction Across All Four

A single ReadShared can touch all four channels. CPU0 (RN0) reads a line RN1 holds.

A ReadShared across all four CHI channels. RN0 sends a REQ ReadShared to the Home Node. The Home Node sends a SNP SnpShared to RN1. RN1 sends a RSP SnpResp and a DAT SnpRespData to the Home Node. The Home Node sends a DAT CompData to RN0. RN0 sends a RSP CompAck to the Home Node.ReadShared — one transaction, four channelsRN0 · requesterHN · homeRN1 · holderREQ: ReadSharedSNP: SnpSharedRSP: SnpRespDAT: SnpRespDataDAT: CompDataRSP: CompAck
Figure 2 — a ReadShared using all four channels. RN0 sends the request on REQ; the Home Node snoops RN1 on SNP; RN1 responds on RSP and supplies data on DAT; the Home Node returns data on DAT and RN0 acknowledges on RSP. Four channels, one transaction — and the RSP and DAT packets are independent.

Every arrow names its channel. The transaction is a choreography across all four — and the key point is that its packets on different channels are independent, as the timing view shows next.

10. The Four Channels in Time

Seeing the channels on a waveform makes their independence concrete: control (RSP) and data (DAT) proceed on their own lanes, concurrently.

Four channels carrying one ReadShared; RSP and DAT run concurrently

6 cycles
Four channels carrying one ReadShared; RSP and DAT run concurrentlyREQREQSNP + RSP (snoop)SNP + RSP (snoop)DAT + RSP (data + complete)DAT + RSP (data +complete)REQ: request issuedREQ: request issuedRSP + DAT concurrent — control + dataRSP + DAT concurrent —control + dataCLKREQRdSharedRdSharedRdSharedRdSharedRdSharedRdSharedSNP0SnpSharedSnpSharedSnpSharedSnpSharedSnpSharedRSP00SnpRespSnpRespCompAckCompAckDAT000SnpDataCompDataCompDatat0t1t2t3t4t5
Figure 3 — the four channels over time. REQ issues the request; SNP carries the snoop; RSP and DAT carry the snoop response, data, and completion. At the delivery, RSP (completion) and DAT (data) are active in the same window — control and data on independent lanes, the essence of orthogonality.

Note cycle 4: RSP and DAT are both active. Control and data ride their own channels and do not wait for each other — which is exactly why a transaction must treat its channel packets as arriving in any order.

11. RTL / Hardware View — a multi-channel completion tracker

Orthogonality has a direct consequence in RTL: a transaction that needs packets from two channels must wait for both, in either order. Here is a read's completion tracker — it needs data (DAT) and a completion response (RSP). Representative and simplified.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Representative multi-channel completion tracker (educational).
// A read completes when BOTH its data (DAT: CompData) and its completion
// response (RSP: Comp) have arrived. The channels are ORTHOGONAL, so these may
// arrive in ANY order — the tracker latches each independently and completes
// when both are in.
module txn_complete (
  input  logic clk,
  input  logic rst_n,
  input  logic start,          // transaction issued (clears the tracker)
  input  logic dat_rcvd,       // CompData arrived on DAT
  input  logic rsp_rcvd,       // Comp arrived on RSP
  output logic complete        // both received -> done
);
  logic got_dat, got_rsp;
  always_ff @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
      got_dat <= 1'b0; got_rsp <= 1'b0;
    end else if (start) begin
      got_dat <= 1'b0; got_rsp <= 1'b0;      // new transaction
    end else begin
      if (dat_rcvd) got_dat <= 1'b1;          // latch DAT independently
      if (rsp_rcvd) got_rsp <= 1'b1;          // latch RSP independently
    end
  end
  assign complete = got_dat && got_rsp;       // done when BOTH, any order
endmodule

The same behavior in Verilog-2001:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Representative multi-channel completion tracker (Verilog-2001).
module txn_complete (
  input  clk, rst_n,
  input  start, dat_rcvd, rsp_rcvd,
  output complete
);
  reg got_dat, got_rsp;
  always @(posedge clk or negedge rst_n)
    if (!rst_n)      begin got_dat <= 1'b0; got_rsp <= 1'b0; end
    else if (start)  begin got_dat <= 1'b0; got_rsp <= 1'b0; end
    else begin
      if (dat_rcvd) got_dat <= 1'b1;
      if (rsp_rcvd) got_rsp <= 1'b1;
    end
  assign complete = got_dat && got_rsp;
endmodule

And in VHDL:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- Representative multi-channel completion tracker (VHDL).
library ieee;
use ieee.std_logic_1164.all;
 
entity txn_complete is
  port (
    clk, rst_n, start, dat_rcvd, rsp_rcvd : in  std_logic;
    complete                              : out std_logic
  );
end entity;
 
architecture rtl of txn_complete is
  signal got_dat, got_rsp : std_logic := '0';
begin
  process(clk, rst_n)
  begin
    if rst_n = '0' then
      got_dat <= '0'; got_rsp <= '0';
    elsif rising_edge(clk) then
      if start = '1' then
        got_dat <= '0'; got_rsp <= '0';
      else
        if dat_rcvd = '1' then got_dat <= '1'; end if;
        if rsp_rcvd = '1' then got_rsp <= '1'; end if;
      end if;
    end if;
  end process;
 
  complete <= got_dat and got_rsp;
end architecture;

All three latch each channel independently and complete when both are set — never assuming which arrives first. That independence is the whole design; assuming an order is the DebugLab.

12. Verification View — completion needs both, in any order

Two properties: completion requires both channels, and it is reached regardless of arrival order.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Bind to txn_complete.
// 1. Complete only when both DAT and RSP have been received.
property p_both_required;
  @(posedge clk) disable iff (!rst_n) complete |-> (got_dat && got_rsp);
endproperty
assert property (p_both_required);
 
// 2. Order independence: DAT-then-RSP and RSP-then-DAT both reach complete.
//    (Checked with two directed sequences in the testbench.)
property p_latches_are_independent;
  @(posedge clk) disable iff (!rst_n) (dat_rcvd && got_rsp) |=> complete;
endproperty
assert property (p_latches_are_independent);

The system point, beyond the two checks:

The channels are orthogonal, so a transaction must be order-agnostic across them. A read's CompData (DAT) and Comp (RSP) may arrive in either order — the fabric makes no promise about which lane is faster. Latch each independently and complete on the conjunction, and the logic is correct for every interleaving. Wait for a specific order and you will hang the moment the fabric delivers the other order first — which it eventually will. Orthogonality is a permission the hardware takes; your logic must not assume it away.

  • What it proves: completion needs both channels and tolerates either order.
  • What it does not prove: the full transaction protocol (this is one completion condition).
  • Bug signature: a transaction that hangs when responses arrive in an unexpected order (the DebugLab).

13. Testbench — complete in both channel orders

Runs the tracker with DAT-first and RSP-first and confirms both complete.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
module tb_txn_complete;
  logic clk = 0, rst_n, start, dat_rcvd, rsp_rcvd, complete;
  int errors = 0;
 
  txn_complete dut (.*);
  always #5 clk = ~clk;
 
  task automatic pulse(output logic sig); sig = 1; @(posedge clk); #1; sig = 0; endtask
 
  initial begin
    rst_n = 0; start = 0; dat_rcvd = 0; rsp_rcvd = 0; @(posedge clk); rst_n = 1;
 
    // Order A: DAT then RSP.
    start = 1; @(posedge clk); #1; start = 0;
    pulse(dat_rcvd); pulse(rsp_rcvd);
    if (!complete) begin errors++; $display("FAIL DAT-then-RSP did not complete"); end
    else $display("PASS DAT-then-RSP completed");
 
    // Order B: RSP then DAT.
    start = 1; @(posedge clk); #1; start = 0;
    pulse(rsp_rcvd); pulse(dat_rcvd);
    if (!complete) begin errors++; $display("FAIL RSP-then-DAT did not complete"); end
    else $display("PASS RSP-then-DAT completed");
 
    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 DAT-then-RSP completed
PASS RSP-then-DAT completed
ALL TESTS PASSED

14. DebugLab — assuming the data arrives before the response

1

Assuming the data arrives before the response

ASSUMED CHANNEL ORDER (RSP after DAT) -> DROPPED RSP -> HANG
Symptom

Occasional transaction hangs: a read never completes even though both its data and its completion were sent. It is timing-dependent and rare, appearing only when the completion response happens to arrive before the data.

Evidence

An RSP arriving before DAT and being ignored:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
cyc  event        got_dat  got_rsp  note
 10  RSP arrives     0         0     RSP gated on got_dat -> DROPPED
 12  DAT arrives     1         0     got_rsp still 0 -> never completes
 ..  (wait forever)  1         0     hang

At cycle 10 the RSP is discarded because the code only accepts RSP when got_dat is already set — but DAT has not arrived yet.

First Divergence

The RSP-latch condition was written as rsp_rcvd && got_dat — it only records the response after the data. From the cycle an RSP arrives first, it is lost, and the transaction can never reach completion.

Root Cause

The channels are orthogonal: DAT and RSP are independent lanes, and the fabric may deliver either first. Coding the RSP latch to depend on DAT assumes an ordering that does not exist. When the fabric legally delivers RSP before DAT, the response is dropped and the completion condition is never met.

Fix

Latch each channel's arrival independently — if (dat_rcvd) got_dat <= 1; if (rsp_rcvd) got_rsp <= 1; — and complete on got_dat && got_rsp. Then any interleaving completes. The rule is general: never make one channel's handling depend on another's having already happened. Orthogonal channels demand order-agnostic logic.

15. Common Mistakes

  • Assuming cross-channel order. Assumption: data before response (or vice versa). Bug: dropped packet, hang (the DebugLab). Prevention: latch each channel independently; complete on the conjunction.
  • Thinking DAT is just another control channel. Assumption: all four are alike. Bug: mis-sizing buffers. Prevention: only DAT carries payload; size it for bandwidth.
  • Confusing RSP and DAT. Assumption: responses carry data. Bug: looking for data on RSP. Prevention: RSP is data-less; data is on DAT.
  • Getting directions wrong. Assumption: any channel goes any way. Bug: mis-routing. Prevention: REQ (RN→HN), SNP (HN→RN); RSP/DAT both ways.
  • Sharing flow control across channels. Assumption: one credit pool. Bug: message-class deadlock (Chapter 5.9). Prevention: independent flow control per channel.
  • Expecting one channel per transaction. Assumption: a transaction is one message. Bug: missing the multi-channel choreography. Prevention: a transaction spans several channels.

16. Engineering Checklist

  • Place each message on its channel: REQ / RSP / DAT / SNP.
  • Track directions: REQ RN→HN, SNP HN→RN, RSP / DAT both ways.
  • Remember only DAT carries payload; the rest are control.
  • Treat the channels as orthogonal — independent flow control, any arrival order.
  • Write completion logic that latches each channel independently.
  • Never make one channel's handling depend on another's ordering.

17. Key Takeaways

  • CHI has four channels: REQ (requests, RN→HN), RSP (responses, no data, both ways), DAT (data, both ways), SNP (snoops, HN→RN).
  • Only DAT carries payload; REQ, RSP, and SNP are control.
  • The channels are orthogonal — independent message classes with independent flow control.
  • A single transaction spans several channels, and their packets may arrive in any order.
  • Completion logic must latch each channel independently and complete on the conjunction — never assume an order.
  • This is the foundation of Module 6; the model here is representative.

18. Quick Revision

The four CHI channels. REQ (requests, RN → HN: ReadShared, WriteBack…), RSP (responses without data, both ways: Comp, CompAck, SnpResp, DBIDResp, RetryAck), DAT (data, both ways: CompData, WriteData, snoop data — the only payload channel), SNP (snoops, HN → RN: SnpShared, SnpUnique). The channels are orthogonal: independent message classes with independent flow control (separate VCs, Chapter 5.9), so data never blocks control, responses always flow, and a transaction's packets on different channels arrive in any order. A read spans all four (REQ → SNP → RSP/DAT → CompData/CompAck). Completion logic must latch each channel independently and finish on the conjunction — assuming a cross-channel order (RSP after DAT) drops a packet and hangs. Representative model; 6.2 details the REQ channel.

Coming Next

Chapter 6.2 — The Request Channel (REQ). With the four channels mapped, Module 6 details each. The next chapter opens the REQ channel: its packet structure field by field, the full set of transaction kinds it carries, and the source-to-home routing that sends every request to the Home Node that owns its address. Where this chapter surveyed all four channels, 6.2 gives the first — the channel where every transaction begins — its full depth.