QoS[3:0](Quality of Service)
- 约束
-- 固定4bit
-- 由RN节点生成transaction时指定
-- 到达目标节点前,QoS只会被传输,不会被修改
QoS的作用
- 通过设置QoS,ICN可以保证该transaction的最大访问延迟,即可以保证其最晚不晚于某个时间被响应
- 通过设置QoS,可以保证ICN为该transaction提供对应的带宽
QoS数值
- QoS数值越大,transaction的优先级越高
- QoS数值一般由RN节点类型、transaction的类型决定
- RN节点可以为transaction设置不同的QoS值
典型场景-retry-with-higher-QoS
RN节点发送一个transaction后,可以重复多次发送相同的transaction,只有QoS值不同,QoS值会增大。
这种情况下,如果其中一个transaction收到了RetryAck,RN节点可以直接丢弃该tranasaction,通过PCrdrant受到的Credit,可以直接通过PCrdReturn进行归还。
这种场景的作用有:
- 在资源紧张时,通过retry-with-higher QoS,可以更快得到P-Credit
- 系统可为不同业务预先定义 多档 QoS 阈值; 同一事务先以低档 QoS 尝试,失败后再升档,既 节省高优先级带宽,又 确保在资源紧张时仍有后路 可走完事务
TgtID
- 约束
-- 位宽可配,范围为7bits~11bits
- 用来表示当前transaction的目标节点的ID。
- ICN会根据该数值进行路由;
SrcID
- 约束
-- 位宽可配置,范围为7bits~11bits(所有ID的位宽要保持一致)
- 用来表示当前transaction的源节点ID
- 目标节点回复data或resp时,会将SrcID作为TgtID
TxnID[11:0]
- 每个RN节点发出的transaction,都会分配一个当前RN内唯一的一个ID,用来标记transaction
- PrefetchTgt请求,TxnID可以设置为任意值(可以和其他TxnID重复),因为PrefetchTgt请求,不会回复响应(同理,PrefetchTgt请求,也不能使能RetryAck)
- 固定12bit位宽,运行RN节点outstanding深度为1024
- 以下情况下,TxnID数值可以被回收重复使用
-- 已经收到transaction的所有响应
-- 收到了RetryAck响应(Retry的transaction,不要求使用与之前相同的TxnID,可以重新分配一个,也可以使用之前的TxnID)
ReturnNID
- 位宽可配,范围为7bits~11bits
- 只用在REQ flit中(可以是HN、RN节点的ID);
- 该域用来指示SN的CompData、DataSepResp、Persist response应该发给哪个节点;当DoDWT=1时,也指示SN的DBIDResp要发给谁
- 约束
-- 只用于DMT模式,非DMT模式时该值无效;
-- 只用在HN节点发出的以下请求:ReadNoSnp、ReadNoSnpSep、CleanSharedPersistStep、WriteNoSnp、WriteNoSnpDef、Combined Write、Atomic请求。
-- RN节点发出的请求中ReturnNID必须为0
-- HN节点发出的其他请求中ReturnNID必须为0
StashNID
- 位宽可配,范围为7bits~11bits
- 只用于REQ + Stash。其他请求中StashNID必须为0
- 与StashNIDValid配合使用
- Stash请求中,支持指定StashNID,也支持不指定StashNID
- 指定StashNID时,HN sends the snoop with a stash hint to the specified target。
- HN收到WriteUniquePtlStash、WriteUniqueFullStash,且未指定StashNID时,HN做如下判断动作
-- 如果某个RN中对应数据为Unique态,HN直接认定该RN为stash target
-- 如果对应cache不是unique态,HN需要发送SnpUnique,而不是SnpUniqueStash
-- 对于WriteUniquePtlStash,如果数据没有cache,HN可以读数据并存储在system cache
-- 对于WriteUniqueFullStash,如果数据没有cache,HN可以缓存数据在shared system cache
- HN如果收到StashOnce、StashOnceSep,且未指定StashNID
-- 如果没有被cache,建议cache在shared system cache
-- 如果被其他RN cache,是否发送snoop将数据copy到shared system cache,由具体实现决定。
StashNIDValid
| StashNIDValid |
Description |
| 0 |
StashNID不使用,必须固定为0 |
| 1 |
StashNID有效,表示目标Stash的ID |
DataTarget[6:0]
-
因为RN节点对cache如何使用最了解,因此RN发起的请求中,可以通过DataTarget来暗示应该将数据放在哪个存储层级。
-
约束
-- 固定7bit
-- 只有RN节点发给HN-F的REQ flit中有效,其他请求中固定为0
-
包含3个子区域

CHI协议G版之前,名字不是DataTarget,而是SLCRepHint,G版CHI协议改了名字,同时增加了DataTarget[5:4],用来表示CacheLevel
UnusedPrefetch[0]
| UnusedPrefetch[0] |
Description |
| 0 |
预取的cache line可能已经被使用过 |
| 1 |
预取的cache line取过来后没有被使用过 |
- 如果RN节点不关心cache使用情况下,可以设置该位固定为0
- 当ICN支持存储UnusedPrefetch信息时,可以在后续的read请求中,通过DataSource域返回UnusedPrefetch信息,RN节点通过该信息,可以优化自己的预取算法
举例
- RN 在请求里置位 UnusedPrefetch=1,告诉 HN-F:“这行是我之前预取的,到现在 CPU 都没碰过”。
- HN-F 收到后把这一 bit 记到本地预取跟踪表(实现可选,协议不强制大小)。同时把同一笔事务的响应消息里的 DataSource[6:0] 回写成:
- bit6 = 1 表示“这行确实来自预取”
- bit5 = UnusedPrefetch 原始值(即 1)
- bit[4:0] = 实际数据源编码(如 0x01 指“HN-F 缓存”)
- RN 看到返回的 DataSource[5] == 1 且 bit6== 1,就知道“我之前那次预取确实白占了位置,CPU 一直没用到”。于是预取器可以:
- 降低该 Stream 的预取深度
- 或者把这条 stream 标记为“低置信度”,减少未来无谓的预取请求
Replacement[3:1]
RN节点通过Replacement[3:1],标记数据后续会被如何使用,cache收到该信息后,可以据此调整替换算法。
| Replacement[3:1] |
Description |
| 'b000 |
No recommendation(default) |
| 'b100 |
Most likely to be used again |
| 'b101 |
More likely to be used again |
| 'b110 |
Somewhat likely to be used again |
| 'b111 |
Least likely to be used againt |
| 其他 |
Unused |
CacheLevel[5:4]
该域用来建议当前数据存放的cache等级,以保证后续访问的最低延迟
| CacheLevel[5:4] |
Description |
MemAttr |
| 'b00 |
不提供暗示 |
MemAttr Allocation hint可以取任意值;MemAttr.CDE必须为'b1010 |
| 'b01 |
建议放在当前级的cache |
MemAttr.ACDE必须为'b1101 |
| 'b10 |
建议放在下一级的cache |
MemAttr.ACDE必须为'b1101 |
| 'b11 |
建议放在下两级的cache |
MemAttr.ACDE必须为'b1101 |
CacheLevel[5:4]等于'b10/'b11时,请求传输到下一级时,需要把CacheLevel的级别-1
具体实现,可以不支持CacheLevel功能,
Placement、UnusedPrefetch应用场景
- 常用在CopyBack请求中。
- 其他RN发给HN-F的请求也可以使用,除了以下请求
-- Atomics
-- Stash
-- PrefetchTgt
-- PCrdReturn
-- DVMOp
CacheLevel应用场景
- 以下CopyBack写请求中,CacheLevel可以取任何值(除此之外,必须固定为0)
-- WriteBackPtl
-- WriteBackFull
-- WriteCleanFull
-- WriteEvictFull
-- WriteEvictOrEvict
Endian
| Endian |
Description |
| 0 |
Little Endian |
| 1 |
Big Endian |
为什么Atomic请求需要使用Endian
CHI 协议里的 atomic 操作(ADD、MIN、MAX、CLR 等)都是“读-改-写”原语;HN-F 收到请求后,要先把整行数据读进算术逻辑单元,按字节粒度做运算,再把结果写回,如果字节序理解错,同一组 4 字节会被当成 0x01020304(LE)或 0x04030201(BE),加法结果完全不同。
因此,Atomic请求必须带endian
Deep
- 只用于CleanSharedPersist*、Combined Write request with CleanSharedPersistSep请求中;其他请求中必须固定为0
- Deep为1时,要求必须把数据写回final destination之后,才能回复response
-- Comp response for CleanSharedPersist
-- Persis or CompPersist for CleanSharedPersistSep
PregetchTgtHint
- 主要用于跨片提示,在跨片场景下用最小的报文开销把内存数据提前搬进对侧芯片,减少后续真正读请求的延迟
-- 发送端(Requester)在 Read 请求里置 1,相当于告诉对侧芯片的接收逻辑:“这行我稍后大概率会真正来读,请提前把它从内存抓到你们本地的 SN-F 缓冲/缓存里。”
-- 接收端(Chip-to-Chip receiver)看到这个 hint 后,可以在本地重建(recreate)一条内部的 PrefetchTgt 事务,提前把数据拉上来,而不必等到真正的读请求再触发 DRAM 访问
- 片上系统(单芯片)同样可以忽略该位——协议只要求 C2C 接收端“可见并可选使用”,片上互联或 SN-F 可选择完全不实现
- 只有RN向HN发起的以下请求中,可以设置PrefetchTgtHint(RN发起的其他请求&HN发起的所有请求,该位必须为0)
-- ReadNoSnp
-- ReadUnique
-- ReadShared
-- ReadPreferUnique
-- ReadOnce*
-- ReadNotSharedDirty
-- ReadClean
ReturnTxnID
- 固定12bit,仅用于DMT;
- 仅用于HN发给SN的以下请求中(除此之外,必须固定为0)
-- ReadNoSnp
-- ReadNoSnpSep
-- WriteNoSnP
-- WriteNoSnpDef
-- Combined Write
-- Atomic request
- SN必须将CompData、DataSepResp中的TxnID设置为对应请求中的ReturnTxnID
- ReturnTxnID,要么为HN自己产生的TxnID,要么为RN发出请求中的TxnID。
- 对于Non-store Atomics,ReturnTxnID必须为HN自己的TxnID
StashLPIDValid & StashLPID[4:0]
- 仅用于Stash请求中
- StashLPID用来识别StashNID内一个logical processor ID
- StashLPIDValid表示StashLPID是否有效(无效时,必须固定为0)
Opcode[6:0]
- 表示当前transaction的操作类型,比如0x000为ReqLCrdReturn、0x03为ReadOnce
- REQ支持的操作类型很多,具体参见SPEC
Size[2:0]
| Size[2:0] |
Bytes |
| 'b000 |
1 |
| 'b001 |
2 |
| 'b010 |
4 |
| 'b011 |
8 |
| 'b100 |
16 |
| 'b101 |
32 |
| 'b100 |
64 |
| 'b111 |
Reserved |
Addr
- 位宽范围:44~52bit
- 只用在REQ、SNP通道(SNP中位宽比REQ少3bit)
- REQ中的Addr[(43~51):0]表示要访问的address
- 对于Snp请求(除了SnpDVMOp)
-- Addr[(43~51):6]表示cache line地址
-- Addr[5:4]表示当前请求访问的critical chunk。
-- Addr[3]不实用
- 对于DVMOp、SnpDVMOp请求,Addr用来存放DVM相关信息
- PCrdReturn中,Addr必须为0
NS & NSE
- NS和NSE用来表示对PAS(Physical Address Space)的访问权限
- DVMOp、PCrdReturn中不使用,必须保持为0
| [NSE, NS] |
Description |
| 'b00 |
Secure |
| 'b01 |
Non-secure |
| 'b10 |
Root |
| 'b11 |
Realm |
LikelyShared
- 1bit,表示当前请求对应的数据是否可能会被其他RN节点shared
| LikelyShared |
Description |
| 0 |
可能不会被其他RN节点shared |
| 1 |
可能会被其他RN节点shared |
AllowRetry
- 当没有收到有效Credit时,可以先发送request,此时可通过AllowRetry,告诉target,是否允许回复RetryAck响应
| AllowRetry |
Description |
| 0 |
不允许回复RetryAck |
| 1 |
运行回复RetryAck |
Order[1:0]
- CHI为非缓存数据设置了4种order机制(可缓存数据由一致性保证)
- 只有 ReadNoSnp/ReadOnce/WriteNoSnp/WriteUnique/Atomic 等 non-snoopable 请求才能把 Order 设成非 0;
- 任何带 Snoop 的读(ReadClean、ReadShared…)必须保持 0b00
| Order[1:0] |
名称(缩写) |
作用 |
典型使用场景 |
| 0b00 |
No ordering |
不保证任何顺序;Completer 可任意重排 |
普通可缓存读、多数写 |
| 0b01 |
Request Accepted |
仅用于 HN-F→SN-F、HN-I->SN-I 的读;告诉 SN“收到后请回 ReadReceipt,我好发下一笔” |
DMT 读、Chip-to-Chip 透传 |
| 0b10 |
Request Order (RO) |
用于RN->HN & ExpCompAck=0或者HN-I->SN-I 同源+同地址 事务必须按发送顺序完成 |
Device-nGRE、NC 内存多次写 |
| 0b10 |
OWO |
用于RN->HN & ExpCompAck=1 同源+同地址 事务必须按发送顺序完成 |
Device-nGRE、NC 内存多次写 |
| 0b11 |
Endpoint Order (EP) |
RN->HN、HN-I->SN-I 同源+同 Endpoint 地址范围 保序;隐含 RO |
配置寄存器组、PCIe BAR 连续访问 |
- 设了 RO/EP 后,请求端要收到“保序点”响应才能发下一笔,“保序点”相应如下:
-- 读:等 ReadReceipt(或 RespSepData)
-- 写:等 DBIDResp
- 收到“保序点”响应,表明 Completer 内部已排好队,不会乱序
PCrdType[3:0]
- 表示提供或者收到的credit类型
- PCrdType(Protocol Credit Type)是 CHI 协议“重试(Retry)”机制里用来区分“资源种类”的 4-bit 标签
- 通过PCrdTye,实现对不同事务类别分配独立的缓存;让 Completer 能够“分类授信”——告诉 Requester 哪一类资源已就绪,可以重新发送请求
- 场景
-- 只存在于 Request 首次发送 和 RetryAck / PCrdGrant / PCrdReturn 三种 flit
-- 当 Completer 暂时没资源(tracker 满、数据缓冲区满等)就会回 RetryAck,并在同一 flit 里给出 PCrdType=n
-- 等对应类别的资源释放后, Completer 再发 PCrdGrant(同样携带 n),通知 Requester“这类资源现在有空位,可以重试”
MemAttr[3:0]
| MemAttr[3:0] |
Description |
0 |
1 |
| [3] |
Allocate hint |
建议不要cache当前数据 |
建议cache当前数据 |
| [2] |
Cacheable |
不能访问cache,只能访问final destination |
必须查找cache |
| [1] |
表示当前transaction对应的memory type是Device还是Normal |
Normal memory type |
Device memory type |
| [0] |
EWA(Early Write Acknowledge) |
不允许EWA |
允许EWA |
EWA(Early Write Acknowledge)
- EWA控制写请求的完成response来源,可选以下来源
-- 1:允许ICN中的中间节点回复响应,比如HN;也可由endpoint回复响应
-- 0:必须由final endpoint回复响应
Device
- Device Memeory Type
-- 读请求返回数据不能多
-- 不允许预取
-- 读数据必须来自endpoint,不能是未完成写入的数据
Cacheable
Allocate
SnpAttr
| SnpAttr |
Description |
| 0 |
不建议HN向其他RN-F发Snp(HN也可以发 |
| 1 |
建议HN向其他RN-F发Snp |
DoDWT
- Do Direct Write Transfer
- 只用在HN->SN的WriteNoSnpPtl、WriteNoSnpFull、WriteNoSnpDef、Combined Write;其他固定为0
| DoDWT |
DBIDResp.TgtID value |
DBIDResp.TxnID value |
| 0 |
等于REQ的SrcID |
等于REQ的TxnID |
| 1 |
等于REQ的ReturnNID |
等于REQ的ReturnTxnID |
PGroupID[7:0]
- Persistence Group ID
- 专用于 “持久化写” 、对应响应场景(WriteUniquePersist、WriteNoSnpPersist、CleanSharedPersist* 等)
- 它把“待刷持久存储”的多笔事务编进同一 持久组(persistence group),让 Completer 可以整组确认、整组回刷,从而保证 “全组数据 + 元数据” 原子落地到非易失介质
- 为什么需要“分组”
-- NVMe、SCM、CXL 内存扩展等场景,要求 “元数据 + 用户数据” 必须同时落盘;
-- 若逐笔回刷,中途掉电会出现 “半写” 状态;
-- 把多笔写划进同一 persistence group 后,Completer(通常是 HN-F 或 SN-F)可以:
---- 等组内最后一笔收到;
---- 一次性把组内所有行写回持久存储;
---- 统一回 PersistResp(Persistence Response),告知 Requester “整组已原子落地”。
StashGroupID[7:0]
- 同一 StashGroupID 的多笔 Stash 事务被 Completer(HN-F)视为 “同一批次预取”,可:
-- 合并分配缓存行;
-- 统一生成 Comp 响应;
-- 在回包里把 StashGroupID 原样带回,让发起 RN 知道“这一组 stash 全完成了
- 只用在StashOnceSep和StashDone响应
TagGroupID[7:0]
- 只现在 TagOp=Match 的写请求及其对应的 TagMatch 响应中,用来告诉互联“这条写属于哪一组标签匹配事务”
- RN 可以把多次标签匹配写划进同一组,HN-F 按组返回 TagMatch 结果,RN 据此知道“整组标签匹配是否全部通过”
LPID[4:0]
- 用于一个RN包含多个独立的processing agent;
- 通过SrcID + LPID可以定位到产生请求的logical processor
Excl
- 表示当前transaction是否为Exclusive transaction
- 只用在以下transaction中
-- ReadNotSharedDirty
-- ReadShared
-- ReadClean
-- ReadPreferUnique
-- CleanUnique
-- MakeReadUnique
-- ReadNoSnp
-- WriteNoSnp
SnoopMe
- 用于Atomic transaction,告诉HN是否需要向请求RN节点发送snoop
| SnoopMe |
Description |
| 0 |
HN可以,但不强制,向请求RN节点发送snoop |
| 1 |
如果请求RN中有对应cache line,必须向其发送snoop |
CAH(CopyAtHome)
- 作用
-- 来自HN/SN的response中:表示提供给RN节点的数据,HN是否存在copy
-- 发给HN的CopyBack请求中:表示RN是否修改过数据
- 只用在 CopyBack 家族(WriteBack、WriteClean、WriteEvict 等)请求及其响应中
-- 所有CopyBack、Combined CopyBack Write,除了WriteBackPtl(CAH必须为0)
-- 发给RN的响应:CompData、DataSepResp
-- SnpRespData、SnpRespDataFwded
ExpCompAck
- ransaction的顺序是由CompAck类决定。CompAck:completion acknowledge。CompAck由RN发出,RN节点在发出原始的读写transaction时,会设置ExpCompAck的值。
- 0:当前transaction不会回复ACK
- 1:当前transaction会回复ACK
- RN节点是否设置ExpCompAck的规则如下:
-- read请求中,除了ReadNoSnp、ReadOnce(共4种),其他所有read(共6种)请求中,必须设置ExpCompAck(read请求共11种,RN不会发出ReadNoSnpSep)
-- ReadNoSnp、ReadOnce请求中,也可以设置ExpCompAck,不强制要求
TagOp[1:0]
- TagOp用来表示将对DAT通道中的Tag做何种操作;
| TagOp[1:0] |
名称 |
作用 |
| 0b00 |
Invalid |
本次报文不涉及标签,Tag 与 TU 字段必须全 0 |
| 0b01 |
Transfer |
Tag是clean,不必进行Tag Match;把标签随数据一起搬移(读/写/回写都可用);Snp请求中,不支持partial tag transfer;TU必须为0 |
| 0b10 |
Update |
Tag被更新且为dirty;用报文里给出的 TU 位掩码 更新标签内容 |
| 0b11 +write |
Match |
先比对标签是否匹配,再决定写是否继续;BE使能对应的Tag必须做match;TU必须为0 |
| 0b11 +read |
Fetch |
取回标签供请求者检查 |
典型用法
| 事务 |
TagOp 值 |
目的 |
| ReadClean + Transfer |
0b01 |
读数据同时把干净标签搬回来 |
| ReadUnique + Update |
0b10 |
读回数据后,当场改写标签 |
| ReadNoSnp + Fetch |
0b11 |
非监听区,先取标签比对,再决定整行写 |
| WriteUnique + Match |
0b11 |
写前先标签匹配,失败则拒绝/报错 |
| MakeUnique |
0b10 |
仅允许 Update,把标签设为全 0 |
| Combined Write&CMO / Persist |
0b00 |
协议强制 Invalid,不允许 Match,因而不会产生 TagMatch 响应 |
TraceTag
- CHI 的 TraceTag 是一个 1-bit 事务染色位,由发起者置位后全程保持,用来告诉沿途组件“这笔事务需要被 trace”,为硬件 PMU、外部探针或软件 profiler 提供端到端可见性
| TraceTag |
Description |
| 0 |
告诉沿途所有组件“这笔事务/数据包需要被跟踪/记录” |
| 1 |
普通事务,不做特殊追踪 |
MPAM(Memory System Resource Partitioning and Monitoring)
PBHA
MECID
StreamID
SecSID1
RSVDC