4. CMN通道与协议:CHI协议简介、AXI协议对比、数据通道与控制通道
好,咱们今天聊聊CMN里的通道和协议。说实话,这部分是很多工程师的“拦路虎”。我自己刚接触CMN时,也被CHI和AXI的关系搞得有点懵。别急,咱们一步步拆开看。
4.1 为什么需要CHI?AXI不够用吗?
你可能会问:AXI协议用得好好的,ARM为什么要搞个CHI出来?
嗯,这个问题我当年也问过。说白了,AXI是“点到点”的协议,适合单核或少量核的场景。但到了多核、多集群、多加速器的时代,AXI的局限性就暴露了。
我举个例子。在AXI协议里,一个读请求发出去,总线必须等数据回来才能处理下一个。这就像你去食堂打饭,必须等前面的人打完,你才能点菜。效率可想而知。
CHI协议则完全不同。它引入了“分离事务”的概念。请求发出去后,总线可以立刻处理其他事务。数据回来时,通过“完成”通道通知你。这就像你点了外卖,不用在店里等,可以干别的事。
核心区别一句话:AXI是“同步等待”,CHI是“异步通知”。
4.2 CHI协议的核心要素
CHI协议里,我最看重的三个概念:事务、通道、协议层。
4.2.1 事务类型
CHI定义了多种事务类型,我挑几个常用的说说:
- ReadNoSnp:读请求,不监听其他缓存。适合DMA或外设访问。
- ReadOnce:读一次,数据可能被缓存。适合CPU读数据。
- WriteNoSnp:写请求,不监听。适合外设写操作。
- WriteBack:缓存回写。我调试缓存一致性时,这个事务用得最多。
- Atomic:原子操作。比如CAS(Compare And Swap),多核同步时必备。
我的经验:刚开始设计时,别贪多。先用ReadNoSnp和WriteNoSnp把通路调通,再逐步引入缓存一致性事务。我曾经一上来就搞缓存一致性,结果调试了两个月才稳定。
4.2.2 通道结构
CHI的通道设计很有意思。它不像AXI那样有独立的读地址、读数据、写地址、写数据通道。CHI把通道分成了三类:
| 通道类型 | 方向 | 作用 |
|---|---|---|
| 请求通道(REQ) | 请求节点 → 家庭节点 | 发送读、写、原子等请求 |
| 数据通道(DAT) | 双向 | 传输数据负载 |
| 响应通道(RSP) | 双向 | 传输协议响应(如完成、重试) |
| 监听通道(SNP) | 家庭节点 → 请求节点 | 缓存一致性监听请求 |
你看,CHI把控制(REQ、RSP、SNP)和数据(DAT)分开了。这样做的好处是:控制通道可以做得更窄(比如32位),数据通道可以做得更宽(比如512位)。
注意:CHI的通道是“虚拟”的。在物理实现上,你可以把多个虚拟通道复用到同一个物理通道上。但这样做会增加延迟。我建议,如果带宽允许,尽量让DAT通道独立。
4.3 AXI与CHI的对比
咱们用一张表来对比,这样更直观:
| 特性 | AXI | CHI |
|---|---|---|
| 事务模型 | 顺序事务 | 分离事务 |
| 通道数量 | 5个(AR, R, AW, W, B) | 4个(REQ, DAT, RSP, SNP) |
| 数据与控制 | 混合 | 分离 |
| 缓存一致性 | 不支持(需外部逻辑) | 原生支持 |
| 原子操作 | 有限支持 | 完整支持 |
| 典型延迟 | 低(但阻塞) | 中(但非阻塞) |
| 适用场景 | 外设、简单互联 | 多核、缓存一致性 |
说白了,AXI适合做“简单、低延迟”的连接。CHI适合做“复杂、高吞吐”的互联。我个人的习惯是:CPU集群内部用CHI,外设接口用AXI,中间加一个协议转换桥。
4.4 数据通道与控制通道的实战考量
这部分是干货。我直接说几个设计要点:
4.4.1 数据通道的宽度选择
数据通道宽度直接影响带宽。但宽度不是越大越好。
- 128位:适合低功耗、小面积场景。比如IoT芯片。
- 256位:主流选择。我做的多数项目都用这个。
- 512位:高性能场景。但布线压力大,时钟频率上不去。
我曾经在一个项目里,为了追求带宽,把数据通道设成了512位。结果后端反馈:时钟频率只能跑到1.2GHz,比预期的1.5GHz低了不少。后来改成256位,频率上去了,总带宽反而更高。
避坑指南:数据通道宽度不要超过缓存线大小(通常是64字节)。否则一次事务要拆成多个节拍,反而增加复杂度。
4.4.2 控制通道的深度
控制通道的深度(即FIFO深度)决定了系统能同时处理多少未完成事务。
我一般这样估算:
控制通道深度 = 最大未完成事务数 × 1.5(安全余量)
举个例子,如果系统最多允许16个未完成事务,那么控制通道深度设为24比较稳妥。
为什么?因为事务可能因为缓存未命中、仲裁等待等原因被阻塞。深度不够,就会导致死锁。我见过一个案例,设计者把深度设为8,结果在高负载下系统频繁卡死。后来改成16,问题解决。
4.4.3 通道间的时序关系
CHI协议对通道间的时序有严格要求。我总结了几条铁律:
- REQ必须在DAT之前:请求必须先发出去,数据才能回来。
- RSP必须在DAT之后:响应必须在数据到达之后才能发出。
- SNP可以随时插入:监听请求是异步的,任何时候都可能来。
嗯,这里要注意:CHI允许“乱序完成”。也就是说,你先发的请求,可能后得到数据。这给调试带来了麻烦。我建议在仿真阶段,打开CHI协议的“顺序检查”功能,确保所有事务都按预期完成。
4.5 一张图看懂CHI通道交互
下面我用一张SVG图,展示CHI通道的典型交互流程:
这张图展示了一个典型的读请求流程。你可能会问:为什么要有SNP这一步?嗯,这是因为CHI要保证缓存一致性。家庭节点需要先问问其他缓存,有没有这个地址的数据副本。如果有,需要先处理掉,才能返回最新数据。
4.6 协议转换桥的设计要点
实际项目中,我们经常需要把AXI转成CHI,或者CHI转成AXI。我分享几个设计要点:
- 事务拆分:AXI的一个突发写,可能拆成CHI的多个写事务。注意保持原子性。
- ID映射:AXI的ID和CHI的Transaction ID需要一一映射。我曾经因为ID映射错误,导致数据乱序,调试了整整一周。
- 超时处理:CHI事务可能长时间未完成。建议设置超时计数器,超时后重试或报错。
- 缓存一致性:AXI转CHI时,需要额外处理缓存一致性。最简单的方法:所有AXI事务都标记为“非缓存”的。
重要提醒:协议转换桥会引入额外的延迟。我建议,如果可能,尽量让IP直接支持CHI协议,避免转换。实在不行,也要把转换桥放在不关键的路径上。
好了,关于CHI通道与协议,我就讲这么多。记住一句话:CHI是为多核缓存一致性而生的,它的通道设计、事务模型都围绕这个目标展开。理解了这一点,你就能驾驭它。
公众号:蓝海资料掘金营,微信deep3321