AMBA AXI 协议学习笔记

本文基于 ARM AMBA AXI Protocol Specification v1.0 (ARM IHI 0022B) 编写,面向固件/驱动开发者。文中用 DMA 描述符、内存屏障、scatter-gather 等软件概念做类比,帮助快速建立对 AXI 总线协议的直观理解。

1. Introduction: What is AXI?

1.1 AMBA 协议演进

ARM AMBA (Advanced Microcontroller Bus Architecture) 是 ARM 定义的片上总线标准,经历了多代演进:

协议 发布年代 定位 架构特征
APB ~1996 低速外设总线 简单的地址/数据/选通,无流水线
AHB ~1999 高性能系统总线 流水线、burst、单地址/数据总线共享
AXI 2003 超高性能总线 5 个独立通道、out-of-order、DMA 友好
AXI4 2010 AXI 增强版 QoS 信号、区域标识、burst 可达 256 拍
CHI 2013 一致性总线 支持缓存一致性、多核/多 cluster 通信

演进主线:APB(简单外设)→ AHB(高性能,但共享总线阻塞)→ AXI(通道分离 + 乱序 + 多未完成事务)→ AXI4(QoS + 长 burst)→ CHI(缓存一致性)。

1.2 AXI 解决了什么?

AHB 的核心局限性:

  • 地址和数据共享同一总线(地址阶段必须等前一个数据阶段完成)
  • Wait states 级联阻塞——一个慢 Subordinate 拖慢整个总线
  • 无法乱序完成——后续事务必须等前面慢的完成

AXI 的解决方案:

  • 地址和数据分离:5 个独立通道(Read Address / Read Data / Write Address / Write Data / Write Response)
  • 多未完成事务:Master 可以连续发出多个地址而不等前面的完成
  • Out-of-order 完成:不同 ID 的事务可以乱序返回

1.3 五通道架构

AXI 协议的核心创新是五通道分离设计

1783606509644_d

图 1-1:读事务的通道架构 — Read Address Channel (AR) + Read Data Channel (R)

1783606522096_d

图 1-2:写事务的通道架构 — Write Address Channel (AW) + Write Data Channel (W) + Write Response Channel (B)

五个通道一览

通道 方向 缩写前缀 核心信号 角色
Read Address M→S AR ARADDR, ARVALID, ARREADY 传递读地址 + burst 控制
Read Data S→M R RDATA, RVALID, RREADY, RLAST 返回读数据 + 响应
Write Address M→S AW AWADDR, AWVALID, AWREADY 传递写地址 + burst 控制
Write Data M→S W WDATA, WVALID, WREADY, WLAST 发送写数据
Write Response S→M B BRESP, BVALID, BREADY 写事务完成确认

软件类比:五个通道 = 五个独立的 FIFO 队列。就像多核 CPU 各自有独立的指令队列一样,各自推进互不阻塞。

1.4 In-Order vs Out-of-Order

AXI 引入了 Transaction ID 机制:

  • 相同 ID 的事务 → 必须按序完成(等价于 AHB 的行为)
  • 不同 ID 的事务 → 可以乱序完成

这意味着一个 Master 可以同时发起多个独立的读事务,先完成的先返回数据——即使它的请求顺序靠后。

软件类比:就像 HTTP/2 的多路复用——可以并发发送多个请求,响应不需要按请求顺序返回,性能远高于 HTTP/1.1 的串行模型。


2. Signal & Channel Descriptions

2.1 全局信号

信号 说明
ACLK Clock source 全局时钟,所有信号在上升沿采样
ARESETn Reset source 全局复位,低有效(和 AHB 的 HRESETn 一样)

2.2 Write Address Channel (AW)

信号 方向 说明
AWID[3:0] M→S 写事务 ID 标签(乱序排序用)
AWADDR[31:0] M→S 写 burst 的起始字节地址
AWLEN[3:0] M→S Burst 长度:1~16 拍(见 §5)
AWSIZE[2:0] M→S 每拍传输字节数:1/2/4/8/16/32/64/128
AWBURST[1:0] M→S Burst 类型:FIXED/INCR/WRAP(见 §5/§6)
AWPROT[2:0] M→S 保护类型:Privileged/Secure/Data
AWCACHE[3:0] M→S 缓存属性:Bufferable/Cacheable/Allocate
AWVALID M→S 地址有效(握手发起方)
AWREADY S→M 地址就绪(握手响应方)

关键命名规律:所有写地址通道信号以 AW 开头(Address Write)。

2.3 Write Data Channel (W)

信号 方向 说明
WID[3:0] M→S 写数据 ID(必须与对应 AWID 一致)
WDATA[31:0] M→S 写数据总线
WSTRB[3:0] M→S 字节选通(bit 级掩码,类似 AHB 的 HWSTRB)
WLAST M→S 最后一拍标志
WVALID M→S 数据有效
WREADY S→M 数据就绪

2.4 Write Response Channel (B)

信号 方向 说明
BID[3:0] S→M 响应 ID(必须与 AWID 一致)
BRESP[1:0] S→M 写响应状态:OKAY/EXOKAY/SLVERR/DECERR
BVALID S→M 响应有效
BREADY M→S 响应就绪

重要:写响应是一次 burst 一个响应,不是每拍一个响应。这是 AXI 和 AHB 的重要区别——AHB 可以直接在 HRESP 上逐拍给反馈。

2.5 Read Address Channel (AR)

信号 方向 说明
ARID[3:0] M→S 读事务 ID 标签
ARADDR[31:0] M→S 读 burst 起始地址
ARLEN[3:0] M→S Burst 长度:1~16
ARSIZE[2:0] M→S 每拍字节数
ARBURST[1:0] M→S Burst 类型
ARPROT[2:0] M→S 保护类型
ARCACHE[3:0] M→S 缓存属性
ARVALID M→S 地址有效
ARREADY S→M 地址就绪

2.6 Read Data Channel (R)

信号 方向 说明
RID[3:0] S→M 读数据 ID(必须与 ARID 一致)
RDATA[31:0] S→M 读数据总线
RRESP[1:0] S→M 读响应状态(每拍可以不同)
RLAST S→M 最后一拍标志
RVALID S→M 数据有效
RREADY M→S 数据就绪

2.7 信号前缀速记

前缀 含义 方向 通道
AW Address Write M→S Write Address
W Write data M→S Write Data
B Response (Backward) S→M Write Response
AR Address Read M→S Read Address
R Read data S→M Read Data

记忆技巧:AW → W → B 是写流程三步走(地址→数据→响应);AR → R 是读流程两步走(地址→数据)。B 通道之所以叫 B 是因为它是”反向”的(Slave→Master)。


3. Read & Write Transfers Walkthrough

3.1 Read Burst 示例

1783606535317_d

图 1-4:4 拍读 burst — 地址 + 4 拍数据返回,最后一拍 RLAST=HIGH

逐周期解析

时刻 事件
T1 Master 驱动 ARADDR=A + ARVALID=HIGH
T2 Slave 接受地址(ARREADY=HIGH)
T4-T7 Slave 按序返回 4 拍数据 RDATA=D(A0)~D(A3),每拍 RVALID=HIGH
T7 最后一拍 RLAST=HIGH,burst 结束

关键点:

  • 地址 ARVALID 持续到 ARREADY 握手完成(T1→T2)
  • 读数据在地址接受后才返回(T4 开始,T7 结束)
  • RLAST 标志 burst 的结束

3.2 Overlapping Read Burst 示例

1783606544671_d

图 1-5:重叠读 burst — 地址 B 在地址 A 的数据未完成前就发出

逐周期解析

时刻 事件
T1 ARADDR=A 被接受
T2 ARADDR=B 被接受(不等 A 的数据返回!)
T4-T6 A 的数据 D(A0)~D(A2) 返回
T8-T9 B 的数据 D(B0)~D(B1) 返回

这就是多未完成事务(Multiple Outstanding Transactions):Master 可以在前一个读事务数据还没返回前就发出新的读地址。

软件类比:就像 DMA 多通道——可以同时排队多个 descriptor,引擎逐个处理,不用等第一个传输结束后才开始准备第二个。

3.3 Write Burst 示例

1783606554055_d

图 1-6:写 burst — 地址 + 4 拍数据 + 写响应

逐周期解析

时刻 地址通道 数据通道 响应通道
T1 AWADDR=A, AWVALID=HIGH
T2 AWREADY=HIGH, 地址接受 WDATA=D(A0), WVALID=HIGH
T3-T5 WDATA=D(A1)~D(A3), T5 时 WLAST=HIGH
T9-T10 BRESP=OKAY, BVALID=HIGH, 写完成

写事务三阶段

  1. 地址阶段(AW 通道)— 传递起始地址和 burst 控制
  2. 数据阶段(W 通道)— 按拍发送数据,WLAST 标记最后一拍
  3. 响应阶段(B 通道)— Slave 确认整个 burst 完成

关键区别:B 通道的响应是整个 burst 一个响应(不是每拍)。这意味着如果你的 DMA 写了一个 16 拍的 burst,你只会收到一个 BVALID。


4. Handshaking: The VALID-READY Mechanism

4.1 握手流程

AXI 的五个通道都使用相同的 VALID-READY 二向流控机制:

  • VALID:由信源驱动,表示”我有数据/地址/控制信息要传”
  • READY:由信宿驱动,表示”我可以接收”
  • 传输发生时:VALID=HIGH READY=HIGH 的时钟周期

4.2 三种握手场景

场景 1:VALID before READY(源等宿)

1783606562539_d

图 3-1:VALID 先于 READY — 源先准备好,等待目的地就绪

源先驱出 VALID 和数据,等待 READY 拉高后完成传输。数据在等待期间保持稳定。

场景 2:READY before VALID(宿等源)

1783606574091_d

图 3-2:READY 先于 VALID — 目的地提前准备好,源驱动数据后立即传输

目的地提前示好”我准备好了”,一旦源驱动了 VALID,同一个周期即可完成传输(零等待)。

场景 3:VALID with READY(同时就绪)

1783606605718_d

图 3-3:VALID 和 READY 同时拉高 — 单周期完成传输

最快的握手方式——双方同时就绪,一个周期完成。

软件类比:VALID-READY ≈ 生产者-消费者模型的单槽 buffer。VALID 表示”buffer 有数据”,READY 表示”消费者空闲”。只有同时为 true 才发生传递。

4.3 死锁避免规则

核心原则:VALID 不能依赖于 READY,但 READY 可以依赖于 VALID。

1783606605718_d

图 3-4:读事务握手依赖图

1783606605718_d

图 3-5:写事务握手依赖图

依赖关系 规则
ARVALID / AWVALID / WVALID 不能等待对应的 READY 信号
ARREADY / AWREADY / WREADY 可以等待 VALID(推荐提前拉高 READY)
RVALID 必须等待 ARVALID + ARREADY 都完成
BVALID 必须等待 WVALID + WREADY 最后一拍完成后

关键死锁避免:Master 在写事务中不能先等 AWREADY 再驱动 WVALID。如果 Slave 同时等着 WVALID 才给 AWREADY,就会形成死锁。正确做法是 Master 独立驱动 AWVALID 和 WVALID。


5. Burst Length, Size & Type — INCR Deep Dive

5.1 Burst Length(AWLEN/ARLEN)

AXI 的 burst 长度是 1-16 拍(比 AHB 的 1/4/8/16 更灵活):

AWLEN[3:0] 拍数
b0000 1
b0001 2
b0010 3
b1111 16

核心规则

  • 一旦开始不能提前结束——即使 Master 不需要数据也必须完成所有拍(可以 discard 读数据,或 deassert 写 strobe)
  • 对于 WRAP burst,长度必须为 2/4/8/16
  • 4KB 边界不能跨越——这是硬件实现的硬限制

软件类比:4KB 边界规则 ≈ 操作系统的 page boundary。DMA buffer 分配时必须注意:如果起始地址 + burst_size × burst_len > 下一个 4KB 边界,硬件将报错。这与 malloc 返回的 buffer 可能跨 page 边界是类似的问题。

5.2 Burst Size(AWSIZE/ARSIZE)

AWSIZE[2:0] 每拍字节数 常见用途
b000 1 (byte) 字符设备
b001 2 (halfword) 16-bit 外设
b010 4 (word) 32-bit 内存(最常用)
b011 8 (doubleword) 64-bit DDR
b100 16 128-bit 宽总线
b101 32 256-bit
b110 64 512-bit
b111 128 1024-bit

每拍传输大小不能超过数据总线宽度。例如 32-bit 总线,SIZE 只能用 b000~`b010`。

5.3 Burst Type(ARBURST/AWBURST)

ARBURST[1:0] 类型 地址行为 典型用途
b00 FIXED 每拍地址不变 FIFO 端口读写
b01 INCR 每拍递增 addr += size 顺序内存复制
b10 WRAP 递增,到边界回绕 Cache line 填充
b11 Reserved

FIXED burst:地址始终不变。用于访问同一 FIFO 端口——每拍都是同一个地址,但读取的是 FIFO 中不同位置的数据。

INCR burst:标准顺序访存。每次地址递增 Number_Bytes(2^SIZE)。

5.4 地址计算方法

1
2
3
4
5
6
7
Start_Address  = ADDR
Number_Bytes = 2^SIZE
Burst_Length = LEN + 1
Aligned_Address = (Start_Address / Number_Bytes) × Number_Bytes // 向下对齐

Address_1 = Start_Address // 第一拍
Address_N = Aligned_Address + (N - 1) × Number_Bytes // 第 N 拍 (N≥2)

示例:INCR4 word burst,起始地址 0x104,每拍 4 字节:

1
2
3
4
Address_1 = 0x104
Address_2 = 0x100 + 1×4 = 0x104 → 0x104(已对齐)
Address_3 = 0x100 + 2×4 = 0x108
Address_4 = 0x100 + 3×4 = 0x10C

6. Wrapping Burst Explained

6.1 回绕机制

Wrapping burst 在地址到达回绕边界后跳到边界起始地址,进行”环状”访问。

回绕边界Wrap_Boundary = Burst_Length × Number_Bytes

对于 4 拍 word burst,边界 = 16 字节;8 拍 word burst,边界 = 32 字节。

回绕条件:当 Address_N = Wrap_Boundary + (Number_Bytes × Burst_Length) 时,地址回绕到 Wrap_Boundary

WRAP 限制

  • burst 长度必须是 2/4/8/16
  • 起始地址必须对齐到传输大小

6.2 示例

WRAP4 word burst,起始地址 0x38

  • 回绕边界 = 4 × 4 = 16 字节 → 边界范围 [0x30, 0x3F]
  • 第 1 拍:0x38
  • 第 2 拍:0x3C
  • 第 3 拍:0x30 ← 回绕!(0x3C+4=0x40 超出边界 0x3F)
  • 第 4 拍:0x34

WRAP vs INCR 对比(起始地址 0x38,4 拍 word burst):

拍号 INCR WRAP
1 0x38 0x38
2 0x3C 0x3C
3 0x40 0x30 ← 回绕
4 0x44 0x34

软件类比:WRAP ≈ 环形缓冲区的 (head + offset) % buffer_size。Cache 控制器用 WRAP burst 实现 critical-word-first 填充——先返回 CPU 需要的关键数据(0x38),再回绕补全 cache line 剩余部分(0x30, 0x34)。


7. Response Signaling

7.1 四种传输响应

AXI 定义了四种传输响应,编码在 RRESP[1:0] 和 BRESP[1:0] 中:

编码 响应 含义 产生方
b00 OKAY 正常访问成功(或独占访问失败) Slave
b01 EXOKAY 独占访问成功 Slave
b10 SLVERR Slave 内部错误 Slave
b11 DECERR 地址译码错误(无目标 Slave) Interconnect / Default Slave

7.2 OKAY — 正常成功

绝大多数事务的响应。同时也是独占访问失败的响应(因为 Slave 不支持独占传输时返回 OKAY 表示独占操作未成功)。

7.3 EXOKAY — 独占访问成功

只用于独占访问(Exclusive Access,类似 AHB 的 locked transfer 但基于 ID 机制),表示读-修改-写过程的独占操作成功。见 Chapter 6 Atomic Accesses。

7.4 SLVERR — Slave 错误

Slave 收到事务后无法处理时的响应。典型场景:

  • FIFO/buffer overflow 或 underrun
  • 不支持的传输大小
  • 写入只读区域
  • Slave 内部超时
  • 访问未实现寄存器的地址
  • 访问已关闭/掉电的功能模块

重要:即使返回 SLVERR,剩余的 burst 拍数也必须完成(不能提前终止)。

7.5 DECERR — 译码错误

由 Interconnect 或 Default Slave 产生,表示当前地址没有任何 Slave 对应。在地址映射不完整的系统中,Interconnect 将访问路由到一个 Default Slave,由它返回 DECERR。

软件类比

  • OKAY = 内存访问正常返回
  • SLVERR = 设备驱动访问了设备不支持的寄存器偏移
  • DECERR = 访问了物理地址空间中不存在任何设备/内存的空洞区域(类似 Linux 的 data abort / bus error)
  • EXOKAY = 原子 CAS (Compare-and-Swap) 操作成功

7.6 读写响应的区别

特性 Read Response (RRESP) Write Response (BRESP)
粒度 每拍可以不同 整个 burst 一个
携带通道 Read Data Channel (R) Write Response Channel (B)
Burst 中出错 某拍返回 SLVERR,剩余拍继续 整个 burst 返回 SLVERR

软件注意:这意味着读 burst 中某一拍出错后 Master 必须继续接受剩余拍的数据(即使数据无效),不能中止 burst。


8. Out-of-Order Transactions

8.1 Transaction ID 机制

AXI 最重要的创新之一是基于 ID 的乱序传输

ID 信号 所属通道 用途
AWID Write Address 写事务标识
WID Write Data 写数据标识(必须匹配 AWID)
BID Write Response 写响应标识(必须匹配 AWID/WID)
ARID Read Address 读事务标识
RID Read Data 读数据标识(必须匹配 ARID)

8.2 排序规则

1
2
3
相同 ID  →  严格按序完成
不同 ID → 可以乱序(来自同一 Master 或不同 Master)
读写之间 → 无排序约束

具体规则

  1. 写事务:相同 AWID 的写数据必须按地址发出顺序被 Slave 接收
  2. 读事务:相同 ARID 的读数据必须按 Master 发出地址的顺序返回
  3. 不同 ID:任何顺序均可
  4. 读写之间:无约束。如果 Master 需要先写后读,必须等 BVALID 返回后才发新的读地址

8.3 Interconnect 的 ID 处理

在多 Master 系统中,Interconnect 会在 ID 字段前面追加 master port number:

1
2
Master 0 ARID = 0x3  →  Interconnect ARID = {0, 0x3} = 0x03
Master 1 ARID = 0x3 → Interconnect ARID = {1, 0x3} = 0x13

这样不同 Master 的相同 ID 经过 Interconnect 后自动变成不同的唯一 ID,不会冲突。Interconnect 在返回读数据时再把这几位剥离。

8.4 Write Data Interleaving

写数据交织(Write Data Interleaving)是指 Slave 可以交替接收不同 AWID 的写数据流

  • 交织深度 = 1(默认):Slave 必须按地址顺序接收写数据
  • 交织深度 > 1:Slave 可以交替接收前 N 个不同 AWID 的写数据

软件类比:交织深度 = 1 相当于单车道——必须一个车走完才能走下一个。交织深度 > 1 相当于多车道——不同来源的车可以交替通行。

注意:即使有交织,相同 AWID 的写数据不能交织——同一个 ID 内的数据必须严格按拍序。

8.5 为什么 Out-of-Order 重要?

场景 1:快慢 Slave 混合

1
2
3
4
5
Master → Slave_A (快速 SRAM)    地址: 0x1000, ARID=0
Master → Slave_B (慢速 Flash) 地址: 0x8000, ARID=1
Master → Slave_A (快速 SRAM) 地址: 0x2000, ARID=2

ARID=0 和 ARID=2 针对快 Slave,它们可以不等 ARID=1 的慢速数据就返回

场景 2:DMA 多通道

一个 DMA 控制器可以给每个通道分配不同的 ARID,让它们的数据互不阻塞,最大化总线利用率。

软件类比:就像操作系统中的 IO 调度器——不同优先级的 IO 请求使用不同的 tag,调度器可以对它们乱序处理,提高吞吐量。


9. 总结:AXI 核心要点回顾与 AHB 对比

9.1 AXI 核心知识点回顾

知识点 一句话总结
五通道架构 地址和数据分离(AHB 合并),读写分离,各自独立握手
VALID-READY 二向流控,VALID 不能等 READY,READY 可以等 VALID
Burst 地址 只发起始地址,Slave/Interconnect 负责计算后续地址
INCR burst 顺序递增,1~16 拍,不跨 4KB 边界
WRAP burst 边界回绕,专为 cache line 填充设计
FIXED burst 每拍地址不变,专为 FIFO 设计
Transaction ID 相同 ID 保序,不同 ID 乱序
Multiple Outstanding Master 不等前一个事务完成就发下一个地址
写响应粒度 一个 burst 一个响应(B 通道),不是每拍
读响应粒度 每拍可以有不同的 RRESP

9.2 AHB vs AXI 对照表

维度 AHB AXI
通道数量 1 条共享总线(地址+数据复用) 5 条独立单向通道
地址/数据阶段 重叠但共享总线,不能乱序 完全解耦,可同时传输不同事务的地址和数据
流控机制 HREADY(全局,影响所有组件) VALID-READY(每通道独立,互不阻塞)
Out-of-Order 不支持 支持(基于 Transaction ID)
Multiple Outstanding 不支持(AHB 是 pipelined 但串行) 支持(Master 可连续发多个地址)
Burst 长度 SINGLE / 4 / 8 / 16 / 不限(INCR) 1-16 拍(每拍数可任意),AXI4 可达 256
写响应 HRESP 逐拍返回 BRESP 整个 burst 一个响应
FIXED burst 不支持 支持(专门为 FIFO 设计)
写数据交织 不支持 支持(可配置交织深度)
Wait States HREADY 拉低 → 全局阻塞 READY 拉低 → 只阻塞该通道
独立时钟 不推荐 各通道可插入 register slice,独立时序收敛
ID 标签 有(AWID/WID/BID/ARID/RID),支持虚拟多端口
信号前缀 H A(全局) / AW / W / B / AR / R
地址空间保护 HPROT (4-bit) ARPROT/AWPROT (3-bit) + ARCACHE/AWCACHE (4-bit)
低功耗接口 可选 CSYSREQ/CACTIVE/CSYSACK

9.3 选型建议

场景 推荐 原因
简单外设(GPIO, UART, I2C) APB 超低开销,无需 burst
Cortex-M 系统(单核, ≤200MHz) AHB 简单够用,无 ID 开销
Cortex-A 系统 / 高性能 DMA AXI 多通道、乱序、高带宽
多核 + Cache 一致性 AXI4/CHI 需要 QoS + 一致性协议

9.4 一句话对比

1
2
3
4
5
6
AHB:  一条双向马路,只有一个红绿灯(HREADY),
所有车(传输)排队通过,不能超车。

AXI: 五条单向高速路,各有独立入口,
快车可以超过慢车(out-of-order),
收费站各自独立(per-channel handshake)。

参考资料:ARM AMBA AXI Protocol Specification v1.0 (ARM IHI 0022B, Issue B, March 2004)

本文中所有时序图均来自规范原文截图。