3、AXI传输机制:突发传输、乱序传输与交织传输

各位同学,今天我们来聊聊AXI总线里最核心的几个传输机制。说实话,我刚接触AXI的时候,也被这些概念绕得头晕。突发、乱序、交织,还有地址对齐问题——每个都够喝一壶的。但等你真正在项目里踩过几次坑,就会明白这些东西有多重要。

3.1 突发传输(Burst)——一次握手,批量干活

突发传输,说白了就是一次发起请求,连续传好几笔数据。我习惯把它比作「批发」——你不需要每传一个数据就重新走一遍握手流程。

AXI的突发传输由三个信号控制:

  • ARLEN/AWLEN:突发长度,表示这次突发要传多少笔数据。注意,实际传的笔数是 ARLEN + 1。比如 ARLEN = 3,那就传4笔。
  • ARSIZE/AWSIZE:每笔数据的字节数。2的幂次,比如 SIZE = 2 表示每笔4字节。
  • ARBURST/AWBURST:突发类型,有3种——FIXED、INCR、WRAP。

我当年第一次做DMA控制器的时候,就栽在突发长度上。我以为 ARLEN = 8 是传8笔,结果仿真发现只传了7笔。查了半天协议才发现,实际笔数是 ARLEN + 1。嗯,这种细节,手册里写得明明白白,但人一忙就容易忽略。

3.1.1 三种突发类型

类型 地址变化 典型用途
FIXED 地址不变 FIFO操作、状态寄存器轮询
INCR 地址递增 内存连续读写、DMA传输
WRAP 地址递增,到边界回绕 Cache Line填充、环形缓冲区

FIXED突发:每次访问同一个地址。我在项目中用它来读FIFO——FIFO的读地址是固定的,每次读都从同一个地址取数据。简单粗暴,但效率高。

INCR突发:最常用的一种。地址每次增加 2^ARSIZE 字节。比如 ARSIZE = 2(4字节),地址就每次加4。你想想看,读写内存数组,基本都是这种模式。

WRAP突发:这个稍微绕一点。地址递增到某个边界后,会回绕到起始地址。边界由突发长度决定——比如4笔WRAP,边界就是4 * 数据宽度。我做过一个Cache控制器,Cache Line填充用的就是WRAP突发。为什么?因为Cache Line的起始地址不一定对齐到Line大小,但数据必须按顺序填满整个Line。WRAP正好解决这个问题。

关键点:WRAP突发的起始地址必须对齐到「突发总字节数」。比如4笔4字节的WRAP,总字节16字节,起始地址必须是16字节对齐的。否则,协议规定这是未定义行为——说白了,别这么干。

3.2 地址对齐与未对齐传输

地址对齐,指的是传输的起始地址是数据宽度的整数倍。比如32位总线,地址0x1000是对齐的,0x1001就是未对齐的。

AXI协议本身支持未对齐传输。但你要知道,底层硬件不一定支持。我见过一个SoC,CPU发了个未对齐的写请求,结果总线直接把数据写到错误的位置去了。查了两天才发现是地址译码逻辑没处理好未对齐的情况。

未对齐传输的处理方式:

  • 硬件自动拆分:总线把一次未对齐传输拆成多次对齐传输。比如读地址0x1001的4字节,拆成读0x1000的4字节(取后3字节)和读0x1004的1字节。效率低,但兼容性好。
  • 软件保证对齐:编译器或程序员确保所有访问都是对齐的。ARM的 __attribute__((aligned)) 就是干这个的。
  • 异常处理:遇到未对齐访问直接触发异常,由软件处理。RISC-V就是这么干的。

我的建议:除非你明确知道自己在做什么,否则尽量保证地址对齐。未对齐传输不仅效率低,还容易引入bug。我在一个视频编解码项目里,就因为一个未对齐的DMA配置,导致图像数据错位,调试了整整三天。

3.3 乱序传输(Out-of-Order)——谁先准备好谁先走

乱序传输,指的是多个事务可以同时发出,返回的顺序可以和发出的顺序不同。每个事务都有一个ID标签,返回时带上这个ID,主设备就知道哪个事务完成了。

为什么会需要乱序?你想想看,一个主设备发了两个读请求:一个去DDR,一个去片上SRAM。DDR延迟几十个周期,SRAM只要几个周期。如果必须按顺序返回,那SRAM的数据就得等DDR的数据一起回来。这不是浪费吗?

乱序传输的核心机制:

  • ARID/AWID:事务ID,每个事务一个唯一ID。
  • RID/BID:返回ID,和请求ID对应。
  • 从设备支持:从设备可以乱序返回数据,但同一个ID的事务必须按顺序返回。

我记得有一次做多核处理器互联,四个核同时发内存请求。如果不支持乱序,一个核的Cache Miss就会阻塞其他核的访问。开了乱序之后,性能提升了将近40%。当然,代价是互联逻辑复杂了不少——你得维护一个ID映射表,跟踪每个事务的状态。

注意:乱序传输虽然好,但不能滥用。每个主设备能发出的未完成事务数量是有限的,由 ARID 的位宽决定。如果ID用完了,新事务就得等。我曾经见过一个设计,只给了4位ID,结果16个事务就把ID池占满了,后面的请求全部被阻塞。嗯,这种坑,设计阶段就要想好。

3.4 交织传输(Interleaving)——数据层面的乱序

交织传输和乱序传输有点像,但粒度更细。乱序传输是事务级别的——整个事务可以乱序。交织传输是数据级别的——同一个事务的多笔数据可以乱序返回。

举个例子:一个INCR突发要传4笔数据。正常情况下,数据按地址顺序返回:data0, data1, data2, data3。但如果从设备支持交织,它可以先返回data2,再返回data0,只要它高兴。

交织传输有什么用?

  • 提高总线利用率:某个从设备的数据准备好一笔就发一笔,不用等所有数据都准备好。
  • 降低延迟:主设备可以提前处理先到的数据。
  • 支持多通道:多个从设备可以同时向同一个主设备返回数据,数据在总线上交织传输。

但说实话,我在实际项目中很少用交织。为什么?因为大多数从设备不支持,而且实现起来太复杂。你需要一个重排序缓冲区,把乱序到达的数据重新排好。这个缓冲区的大小、管理逻辑,都是开销。

一句话总结:乱序传输是事务级别的乱序,交织传输是数据级别的乱序。乱序传输很常用,交织传输用得少。如果你不是在做高性能互联网络,建议先别碰交织。

3.5 知识体系总览

下面这张图,把本章的核心逻辑串起来了。我画图的时候习惯用颜色区分不同机制——蓝色是突发,绿色是乱序,橙色是交织。这样一看就明白它们之间的关系。

AXI传输机制知识体系 AXI传输机制 突发传输 (Burst) 乱序传输 (OoO) 交织传输 (Interleaving) FIXED INCR WRAP ID标签机制 事务级乱序 ID复用与限制 数据级乱序 重排序缓冲 多通道交织 地址对齐与未对齐传输 硬件自动拆分 软件保证对齐 异常处理 性能影响 突发 乱序 交织 地址对齐

这张图里,突发传输是基础,乱序和交织是在其上的优化。地址对齐则是贯穿所有传输的一个约束条件。我个人建议你先把突发传输吃透,再去看乱序和交织。地基不牢,后面容易塌。

实战建议:如果你刚开始做AXI设计,先实现一个支持INCR突发的从设备。不要一上来就搞乱序和交织。等INCR跑通了,再逐步加上乱序支持。我带的团队里,新人都是这么练的——从简单到复杂,一步一个脚印。

好了,这一章的内容就到这里。突发、乱序、交织、地址对齐——这四个概念是AXI传输机制的基石。理解它们,你就能看懂大部分AXI总线的行为。下一章我们会聊AXI的握手协议和通道信号,那是实现这些传输机制的基础设施。

可可精品资料库