本系列我想深入探寻 AXI4 总线。不过事情总是这样,不能我说想深入就深入。当前我对 AXI总线的理解尚谈不上深入。但我希望通过一系列文章,让读者能和我一起深入探寻 AXI4。
声明:部分时序图以及语句引用或翻译自 ARM AMBA 官方手册
(有的时候感觉手册写得太好了,忍不住就直接翻译了。。)
声明2:AXI 总线是 ARM 公司的知识产权
本文讨论 AXI 总线中的多传输事务(Multiple Transaction)相关机制,对应于协议手册的第五章(A5)
本文为下篇,讨论多个主机产生的多传输事务场景。并讨论了多机通信中起到关键作用的 Interconnect 组件的功能与基本构成。
多主机场景
书接上回,多传输事务场景指系统中存在多个进行中的 AXI 传输事务,这可能是由于
- 系统中存在多个主机
- 单个主机产生多个事务
上篇中讨论了单个主机因为超前传输机制产生的多事务场景,而本文作为下篇讨论多主机的场景。
首先构造场景 B 用于后续讨论。场景 B 包括两个主机以及两个存储控制器从机,通过一个拥有 2 主 2 从接口的 AXI Interconnect 互联,多机互联中 AXI Interconnect 起到了最重要的作用。
多主机场景中,单个主机特性与本文上篇中的内容一致,概括为以下几点:
- ID 相同的事务,从机需要按照主机发出事务的顺序执行,并按序返回数据或者回复信号
- ID 不同的事务,之间不存在顺序约束。从机可以按照任意的顺序返回数据或回复
- 读写事务之间不存在顺序约束
不同主机间事务独立
协议规定,不同主机间的事务是独立的,之间没有顺序约束。
那么从实现的角度出发,如何将多主机的事务独立开呢,有两种办法:
- 各主机保证自己的 ID 与其他主机不同
- 中间节点对不同主机的 ID 进行调整,即使主机发出的 ID 一致,也能使从机看到的 ID 不同
第一种方案看起来最为容易,一旦 ID 不同,事务之间自然独立,不需要增加其他机制来保证多主机事务间的独立性。
但是,协议并没有在主机之间设立消息共享机制,因此各主机并不知道其他主机所使用的 ID,也就无法保证 ID 不同。
第二种方案是 AXI 协议采用的方法,中间节点指 AXI Interconnect 组件。从场景 B 的拓扑连接可以发现两点:
- 任何主机的事务前往任何从机必定经过 interconnect
- Interconnect 可以从事务的来源端口,判断事务来自哪台主机
具体的实现方式是,Interconnect 接收主机事务后,会在原有的 ID 上附加一个表示来源端口的值,再发送给从机。对于从机返回的数据,Interconnect 再剥去附加值后再返回主机。
这样一来对于属于不同主机的事务,哪怕主机发出时的 ID 一致,从机看到的 ID 总是不同的。
接下来我们基于场景 B 构造一个例子 B1 来说明 Interconnect 的工作。
图中的 AXI Interconnect 连接有 2 个主机,因此可通过 1bit 额外 ID 来区分这两个主机。master1 产生的 trans1 原 ARID 为 4'b0001,自端口 S1 输入,Interconnect 为其增加 额外 ID:1'b1 后,从机端看到的 ARID 为 5'b10001。从机读数据 RID 匹配为 5'b10001,Interconnect 去除额外比特后返回 master1。
右图中的传输过程分别包括一个读写事务。其中,写事务经过 Interconnect 的 ID 调整机制与读事务基本相同,不同在于从机返回的是写回复,相应 ID 为 BID。
自然,从机端 ID 位宽需要设置地比主机端 ID 位宽更大。协议建议(而非强制):
- 主机端位宽不超过 4bit,Interconnect 为主机事务增加的 ID 位宽不超过 4bit
- 因此从机端的 ID 位宽不超为 8bit
Interconnect 的功能
转发功能
由此前有关 AXI 结构的文章可知,AXI 本身是一个单对单的协议,需要借助中间节点才能够实现多机通信。Interconnect 是一个具有多个主机与从机端口的 AXI 组件,可作为中间节点连接各 AXI 组件。
Interconnect 内部使用交叉总线连接每一个主机与从机端口,交叉总线的选通由其上的交换结构(switch fabric)控制,又称交叉开关(crossbar),结构如下图所示:
在接收主机发起的传输事务后,Interconnect 根据地址信号 AxADDR,转发至对应的从机,相当于将该主机与目的从机的通道选通。
从机的地址映射在设计阶段确定,实现后硬编码至 Interconnect 的转发逻辑。以图中情况为例,每个从机拥有 0x1000 地址空间,从机 0 的地址范围为 0x0000-0x0FFF,对于地址 AxADDR[8] = 1‘b1 的事务,模块将其路由转发至从机 0。
此外如上节所述,Interconnect 会在经过的事务 ID 上增加额外字段标识其主机端口信息。
在写传输事务中,Interconnect 将根据其写事务信息,将其写数据转发至从机。Interconnect 需要实现写数据的保序性,包括 2 点:
- 写数据顺序与写事务的顺序一致
- 同一事务内的写数据间,不能插入其他事务的数据
当接收到从机返回的数据后,Interconnect 根据其附加在其 RID/BID 上的主机端口信息,转发至发起事务的主机。
多机仲裁功能
由于不同主机间的传输事务互相独立,因此有可能不同主机会同时产生传输事务。
Interconnect 一方面需要为每个主机设计缓存通道,另一方面需要对多通道进行仲裁。
仲裁(arbiter)简单地说,就是决定当前从哪个非空的缓冲区读取事务,输入交换结构。仲裁根据策略进行,以 Xilinx 的 AXI Interconnect 实现为例,共有 2 种策略:
- 轮询(round-robin),轮流从各个主机的缓存通道读取事务。
- 优先级仲裁(priority),优先读取高优先级缓存通道中的事务。
同时,对于从机输入的数据,Interconnect 也有相同的缓存与仲裁结构。在 2 种策略之外,设计人员也可根据应用的需求设定策略。
读数据重排序功能
根据 AXI 读事务的保序要求,Interconnect 还需要具有对来自不同从机的数据重排序功能。
在单对单的拓扑中,由从机负责具有相同 ID 的传输事务的保序性。
但是在多机通信中,主机可能向多个从机发出了 ID 一致的传输事务,此时由 Interconnect 负责保证数据返回主机的顺序,与主机发出事务的顺序一致。这就要求 Interconnect 具有同从机类似的缓存功能以实现重排序,比如下图中的场景,由 Interconnect 对不同从机的数据进行重排序。
AXI4 不再支持写交织功能
在 AXI3 协议中支持的写数据交织(wirte data interleaving)功能在 AXI4 中不再支持。因此 Interconnect 实现也无需继续支持写交织。
何为写交织
写数据交织指来自不同事务的写数据可以被打散混合排列。如下图中有 2 个写事务,每个写事务共有 2 个写数据 A/B。
当不支持写交织时,写入数据的顺序必须保持为 0A 0B 1A 1B,即一个写事务的数据完成后再传输下一个事务的数据。而交织时顺序可以为 0A 1A 0B 1B 或者 0A 1A 1B 0B,在事务中插入另一事务的数据。
写交织的作用之一在于提高系统的效率,我们对上述场景增加一个假设,事务0 是一个较慢的数据流,每 2 个周期写一个数据。而事务 1 的数据速率更高,每个周期写一个数据。如下图所示,写交织能够减少总线传输中的气泡(空闲时间),提高系统的效率。
为什么不再支持
笔者在网上冲浪了一下,并没有找到直接的解释,个人总结有以下原因:
- 应用场景少
- 设计复杂
- 去除该功能能够简化实现
(1)首先是相较于读交织,写交织仅在多主机场景中有效,应用有限。在单个主机的情况下,可以由主机分拆事务提高效率,而无需应用写交织这一复杂特性。
上图中的场景,假设这 2 个事务来源于同一主机,如下图所示,主机将速度较慢的事务 0 分拆为 2 个事务,每个事务各包括 1 次传输,同样达到了写交织的效率。
由于应用场景有限,因此在 AXI3 实现中,写交织往往也不被支持。ARM 在手册中也承认了这一点:
Most AXI3 masters do not support write interleaving.
(2)写交织设计较为复杂,ARM 在协议中针对写交织做了许多约束,以避免出现死锁等现象。在 A5.3.3 中罗列了一大堆。
(3)既然写交织复杂又不常用,而砍掉该特性能够简化实现,并删去写通道中的 WID 信号,自然是一件喜闻乐见的事。
其他功能
Interconnect 实现中,比如 Xilinx 的相关 IP,还具有总线位宽转换、时钟域转换以及 AXI 协议转换等功能。详情可以参阅其 IP 文档,链接在本文底部。
补充阅读
详细地讨论 AXI Interconnect 的原理与构成
ARM论坛关于写乱序的讨论
Xilinx AXI Interconnect IP PG
摘录 Xilinx 实现中的几张图,如果读者有兴趣,可以再补充阅读下
多主机单从机时的仲裁结构
单主机多从机的解码结构