第二章:CHI协议基础——Channel、Flit、Layer概念、协议栈分层、Node与Agent类型
好,咱们正式开始啃CHI协议这块硬骨头。
说实话,我第一次看CHI规范的时候,脑子里就一个感觉——这玩意儿怎么这么绕?又是Channel又是Flit,还分层,还分Node和Agent。但后来做项目做多了,我发现一个规律:CHI其实没那么玄乎,它就是一套把“谁跟谁说话、怎么说话、说话时要注意什么”规定得死死的规则集。
这一章,咱们就把这些基础概念掰开揉碎,一个一个说清楚。
2.1 从宏观到微观:CHI协议栈分层
我个人习惯,看任何协议先看它的分层结构。CHI协议栈分三层,从下往上分别是:
- 物理层(Physical Layer):管信号的电气特性、时钟、复位这些“硬”东西。说白了就是线怎么连、电平怎么判。
- 链路层(Link Layer):管数据怎么在链路上可靠传输。包括流控、CRC校验、重传机制。嗯,这里有个坑,我后面会讲。
- 协议层(Protocol Layer):管事务怎么发起、怎么完成。比如读请求、写请求、 snoop 请求,都在这一层定义。
你想想看,这三层分工非常明确。物理层只管“能不能传”,链路层只管“传得对不对”,协议层只管“传的是什么”。每一层只关心自己的事,不越界。这种设计思想,在复杂SoC里特别重要。
核心要点:CHI的分层设计,让不同模块的工程师可以并行工作。做物理层的不用管协议细节,做协议层的不用管电气特性。我在一个7nm的项目里,就因为分层清晰,RTL和验证团队几乎没扯过皮。
2.2 Channel:数据流动的“高速公路”
CHI协议里,通信是通过Channel(通道)来完成的。每个Channel都是单向的,要么发要么收,绝不混用。
一共有五个Channel:
| Channel名称 | 方向 | 作用 |
|---|---|---|
| TXREQ | 请求节点 → 家庭节点 | 发送请求(读、写、原子操作等) |
| TXRSP | 响应节点 → 请求节点 | 发送响应(数据、完成信号等) |
| TXDAT | 数据节点 → 请求节点 | 发送数据(读回的数据、写的数据) |
| RXREQ | 家庭节点 → 请求节点 | 接收请求的确认/重试信号 |
| RXRSP | 请求节点 → 响应节点 | 接收响应的确认/重试信号 |
为什么搞这么复杂?因为要解耦。请求和数据走不同的通道,意味着请求还没处理完,数据就可以先回来。这在乱序执行、多流水线的场景下,性能提升非常明显。
我的经验:刚开始设计RTL时,我总想把所有通道合并成一个,觉得省线。结果发现流控逻辑复杂到爆炸,而且时序收敛困难。后来老老实实按CHI规范来,反而简单了。记住:CHI的通道设计是经过无数项目验证的,别自作聪明去“优化”它。
2.3 Flit:数据的最小传输单元
Flit(Flow Control Unit)是CHI协议里数据在链路上传输的最小单位。你可以把它理解成“数据包”。
一个Flit包含:
- Header:描述这个Flit的类型、长度、目标地址等控制信息。
- Payload:实际的数据内容。
- CRC:校验码,保证传输正确性。
Flit的大小是固定的,CHI规范里定义了几种标准宽度:32字节、64字节、128字节。具体用哪种,取决于你的带宽和面积权衡。
我曾经在一个项目中,为了省面积选了32字节的Flit,结果发现带宽不够,CPU跑分上不去。后来改成64字节,面积只多了5%,性能提升了20%。这个取舍,得根据你的实际场景来定。
注意:Flit的CRC校验在链路层完成。如果CRC出错,链路层会发起重传。但协议层并不知道这件事——它只负责发Flit和收Flit。这就是分层的好处:协议层不需要关心链路层的错误恢复。
2.4 Layer:协议栈的“层级视图”
除了前面说的三层协议栈,CHI还定义了另一种视角——Layer(层)。这个Layer不是协议栈的层,而是事务处理的阶段。
一个完整的事务,会经历以下几个Layer:
- Request Layer:发起请求。
- Snoop Layer:如果需要,向其他缓存发送监听请求。
- Response Layer:接收响应。
- Data Layer:传输数据。
你可能会问:这不就是流水线吗?对,CHI的Layer本质上就是事务的流水线阶段。每个Layer可以独立处理不同的事务,从而实现高吞吐。
举个例子:
- 事务A在Request Layer刚发出去。
- 事务B已经在Snoop Layer被处理了。
- 事务C的Data Layer正在传数据。
这三个事务互不干扰,同时进行。这就是CHI高性能的秘诀之一。
关键理解:Layer不是物理上的层级,而是逻辑上的阶段。你在RTL里实现时,每个Layer对应一组状态机和FIFO。我见过有人把Layer和协议栈分层搞混,结果设计出来的接口乱成一锅粥。记住:协议栈分层是“纵向”的,Layer是“横向”的。
2.5 Node与Agent:谁在说话?
CHI协议里,通信的实体叫Node(节点)。每个Node可以包含一个或多个Agent(代理)。Agent是真正发起或响应事务的单元。
Node类型主要有三种:
- Request Node (RN):发起请求的节点。通常是CPU核心、GPU、DMA等。
- Home Node (HN):管理一致性域的节点。负责处理请求、维护缓存一致性。
- Subordinate Node (SN):响应请求的节点。通常是内存控制器、外设等。
Agent类型则更细:
| Agent类型 | 所属Node | 作用 |
|---|---|---|
| RNF (Request Node F) | RN | 全功能请求代理,支持所有CHI事务 |
| RNI (Request Node I) | RN | 简化版请求代理,不支持snoop |
| HNF (Home Node F) | HN | 全功能家庭代理,管理一致性 |
| HNI (Home Node I) | HN | 简化版家庭代理,用于IO一致性 |
| SNF (Subordinate Node F) | SN | 全功能从属代理,支持所有响应 |
| SNI (Subordinate Node I) | SN | 简化版从属代理,用于简单外设 |
为什么分这么细?为了灵活。一个CPU核心可以是RNF,一个GPU可以是RNI,一个内存控制器可以是SNF。不同的Agent类型,决定了它能做什么、不能做什么。你在设计RTL时,需要根据实际需求选择合适的Agent类型。
避坑指南:我曾经在一个项目中,把GPU配成了RNF,结果发现它根本不需要snoop功能,白白浪费了面积和功耗。后来改成RNI,一切正常。所以,选Agent类型时,一定要搞清楚你的设备到底需要哪些功能。
2.6 知识体系总览
说了这么多,咱们用一张图来总结一下本章的核心内容。这张图展示了CHI协议的基础概念和它们之间的关系。
这张图把咱们今天讲的内容串起来了。你看,协议栈分层是纵向的,Channel是横向的,Flit是传输的载体,Layer是处理的阶段,Node和Agent是通信的实体。这五个概念,构成了CHI协议的基础骨架。
嗯,说实话,这些概念刚接触时确实有点多。但别急,后面咱们会反复用到它们。等你真正开始写RTL代码时,就会发现这些概念就像工具箱里的螺丝刀——用对了地方,事半功倍。
本章小结:
- CHI协议栈分物理层、链路层、协议层,各层职责清晰。
- 五个Channel(TXREQ、TXRSP、TXDAT、RXREQ、RXRSP)实现单向、解耦的数据传输。
- Flit是链路层传输的最小数据单元,包含Header、Payload、CRC。
- Layer是事务处理的流水线阶段,包括Request、Snoop、Response、Data。
- Node(RN、HN、SN)和Agent(RNF、RNI、HNF、HNI、SNF、SNI)定义了通信实体的能力和角色。
公众号:蓝海资料掘金营,微信deep3321