AMBA AHB 协议学习笔记

本文基于 ARM AMBA 5 AHB Protocol Specification (IHI 0033C) 编写,面向有软件开发背景、需要理解 SoC 总线协议的读者。文中用 CPU 流水线、内存总线等概念做类比,帮助快速建立直观理解。

1. AHB 协议概述与 Manager 接口信号

1.1 什么是 AHB

AHB (Advanced High-performance Bus) 是 ARM AMBA 总线家族中的高性能总线,用于连接 SoC 内部的高速组件,如 CPU、DMA 控制器、片上内存、外部内存接口等。

AHB 的核心特性:

特性 说明
单时钟沿操作 所有信号在 HCLK 上升沿采样/驱动
非三态实现 使用独立读写总线 + 多路复用器,而非三态门
流水线传输 地址阶段与上一传输的数据阶段重叠(类似 CPU 流水线)
Burst 传输 支持 1/4/8/16 拍的突发传输
可配置数据宽度 8/16/32/64/128/256/512/1024 位
Split 事务 支持 Subordinate 在未就绪时释放总线

1.2 系统组成

AHB 系统由三种组件构成:

1
2
3
4
┌──────────┐      ┌──────────────────┐      ┌──────────────────┐
│ Manager │ ──── │ Interconnect │ ──── │ Subordinate │
│ (CPU/DMA)│ │ Decoder + Mux │ │ (RAM/peripheral) │
└──────────┘ └──────────────────┘ └──────────────────┘
  • Manager(管理器):发起读写传输,提供地址和控制信号(CPU、DMA)
  • Subordinate(从设备):响应传输,返回数据或完成状态(RAM、外设控制器)
  • Interconnect(互连):地址译码器 + 读数据多路复用器,将 Manager 的请求路由到正确的 Subordinate

1783606814399_d

图 1-1:AHB 系统框图 — 一个 Manager 连接三个 Subordinate,Decoder 根据地址选择目标,Multiplexor 汇集读取数据

1.3 Manager 接口

Manager(管理器)是发起传输的组件,负责提供地址和控制信息。下图展示了 Manager 与总线交互的完整接口:

1783606867401_d

图 1-2:Manager 接口 — 左侧为全局/反馈信号(输入),右侧为 Manager 驱动到 Subordinate 的地址、控制和写数据信号

Manager 输出侧(M→S):地址 HADDR、控制信号(HWRITE/HSIZE/HBURST/HTRANS/HPROT/HMASTLOCK)、写数据 HWDATA。

Manager 输入侧(S→M):HCLKHRESETn 为全局信号,HREADYHRESP 为传输完成与状态反馈,HRDATA 为读回的数据。

1.4 Subordinate 接口

Subordinate(从设备)响应 Manager 发起的传输。它通过 HSELx 选通信号来判断当前传输是否寻址到自己:

1783606923614_d

图 1-3:Subordinate 接口 — Subordinate 接收 Manager 的地址/控制/数据信号,返回读数据和状态

Subordinate 输出侧(S→M):HREADYOUT(通过 Interconnect 合并为全局 HREADY)、HRESP(传输状态)、HRDATA(读数据)。

Subordinate 输入侧(M→S):除全局时钟复位外,还包括选通信号 HSELx、地址 HADDR、所有控制信号,以及写数据 HWDATA。

对比记忆:Manager 主动发起(输出地址+控制),Subordinate 被动响应(输出状态+读数据)。Manager 不知道有多少个 Subordinate,是 Interconnect 的 Decoder 通过 HSELx 信号完成寻址路由。

1.5 传输的两个阶段

每个 AHB 传输分为两个阶段,重叠执行(这是理解 AHB 性能的关键):

阶段 耗时 说明
Address Phase(地址阶段) 1 个 HCLK 周期 Manager 驱动地址 + 控制信号
Data Phase(数据阶段) 1+ 个 HCLK 周期 Subordinate 返回/接收数据,可用 HREADY 延长

核心流水线特性:当前传输的地址阶段与上一个传输的数据阶段发生在同一个时钟周期内。这意味着 AHB 可以在每个时钟周期启动一个新传输,同时完成前一个传输的数据收发。

软件类比:就像 CPU 的五级流水线——取指的同时,前一条指令正在执行。地址阶段是”前端”,数据阶段是”后端”。

1.6 Manager 接口核心信号一览

所有 AHB 信号以 H 为前缀。Manager 输出的关键信号

信号 宽度 方向 说明
HCLK 1 全局 总线时钟,所有信号在上升沿采样
HRESETn 1 全局 异步复位,低有效(唯一低有效信号)
HADDR 10-64 M→S 字节地址。地址阶段信号
HWRITE 1 M→S HIGH = 写传输,LOW = 读传输
HSIZE[2:0] 3 M→S 传输宽度:8/16/32/64/128/256/512/1024 bit
HBURST[2:0] 3 M→S 突发类型(见第 6 章)
HTRANS[1:0] 2 M→S 传输类型:IDLE/BUSY/NONSEQ/SEQ(见第 5 章)
HPROT[3:0] 4/7 M→S 保护控制:cacheable/bufferable/privileged/data
HMASTLOCK 1 M→S 锁定传输指示(原子操作)
HWDATA 8-1024 M→S 写数据总线
HRDATA 8-1024 S→M 读数据总线
HREADY 1 S→M 传输完成指示。LOW = 插入等待
HRESP 1 S→M 传输响应:LOW = OKAY,HIGH = ERROR

软件类比:HADDR + HWRITE + HSIZE ≈ 一次函数调用参数;HREADY ≈ 返回值就绪信号;HWDATA/HRDATA ≈ 调用/返回的数据。


2. 无等待状态的读写传输

2.1 最简单的读传输

当一个 Subordinate 足够快时,传输在 2 个时钟周期内完成(无等待):

1783606886089_d

图 3-1:无等待读传输 — 注意 HADDR(A) 和 HRDATA(A) 差一个时钟周期

时序步骤

时钟沿 事件
T0 上升沿后 Manager 驱动地址 A + HWRITE=LOW + 控制信号到总线
T1 上升沿 Subordinate 采样地址和控制信息
T1 上升沿后 Subordinate 驱动 HREADYOUT + HRDATA(A)
T2 上升沿 Manager 采样 HREADY=HIGH + HRDATA(A),传输完成

关键点:地址 A 在 T1 采样,数据 A 在 T2 采样——地址和数据的时钟周期不同

2.2 最简单的写传输

1783606886089_d

图 3-2:无等待写传输 — Manager 同时驱动 HADDR + HWDATA

时序步骤

时钟沿 事件
T0 上升沿后 Manager 驱动地址 A + HWRITE=HIGH + HWDATA(A)
T1 上升沿 Subordinate 采样地址和数据
T1 上升沿后 Subordinate 驱动 HREADYOUT=HIGH
T2 上升沿 Manager 采样 HREADY=HIGH,写传输完成

读写关键区别

  • 读:数据由 Subordinate 驱动(T1-T2 之间),Manager 在 T2 采样
  • 写:数据由 Manager 驱动(T0-T2 之间,因为提前一个周期),Subordinate 在 T1 采样

2.3 流水线本质

从时序图可以清楚地看到:地址 T0→T1 的地址阶段与上一个传输 T0→T1 的数据阶段同时进行。AHB 正是利用这种重叠实现了”每周期一个传输”的高吞吐量。

软件类比:这就像 HTTP pipelining — 不等上一个响应返回就发出下一个请求。每个请求(地址)和上个请求的响应(数据)在同一条总线上交错传输。


3. 带等待状态的读写传输

3.1 Wait States 的机制

当 Subordinate 需要更多时间处理传输时,通过 HREADY 信号插入等待:

  • 每个 Subordinate 有自己的 HREADYOUT 信号
  • Interconnect 将所有 HREADYOUT 组合成一个全局 HREADY
  • HREADY = LOW → 当前传输未完成,Manager 和所有 Subordinate 必须等待

软件类比:HREADY ≈ 内存控制器的 ready 信号。就像 DDR 控制器在未就绪时向 CPU 插入 stall 周期,AHB 通过 HREADY 实现同样的流控。

3.2 带等待的读传输

1783606893625_d

图 3-3:带两个等待状态的读传输 — HREADY 在数据阶段拉低两次

时钟沿 HREADY 事件
T0→T1 HIGH 地址阶段:Manager 驱动 A
T1→T2 LOW 第 1 个等待:Subordinate 未就绪
T2→T3 LOW 第 2 个等待:Subordinate 仍未就绪
T3→T4 HIGH 数据阶段完成:Manager 采样 HREADY=HIGH + HRDATA(A)

读传输等待时的规则:Subordinate 不需要在等待期间提供有效数据,只有在 HREADY 即将拉高的那个周期才必须提供有效的 HRDATA。

3.3 带等待的写传输

1783606973043_d

图 3-4:带一个等待状态的写传输

写传输等待时的规则(与读不同):

  • Manager 必须在整个等待期间保持 HWDATA 稳定不变
  • Subordinate 在 HREADY=HIGH 的那个上升沿采样数据

记忆技巧:写 = Manager 保持数据不变(”我等你,数据不会跑”);读 = Subordinate 最后关头给数据(”你别催,好了就给你”)。


4. 多传输下的流水线 (Multiple Transfers)

4.1 连续传输示例

当一个传输被延长时,它会影响下一个传输的地址阶段

1
地址 A(读, 0 wait) → 地址 B(读, 1 wait) → 地址 C(写, 0 wait)

1783606874546_d

4.2 级联效应

时间槽 地址阶段 数据阶段 HREADY
T0→T1 A HIGH
T1→T2 B A HIGH
T2→T3 B(保持) B(等待) LOW
T3→T4 C(等待!) B LOW
T4→T5 C B(完成) HIGH
T5→T6 C HIGH

关键观察:T3→T4 时,地址 C 本应进入地址阶段,但因为 HREADY=LOW,地址阶段被被迫延长。这是 AHB 流水线的核心行为:

  1. B 的数据阶段延长(HREADY=LOW)
  2. 导致 C 的地址阶段不能开始(因为 AHB 的地址信号只有在数据阶段进行时才更新)
  3. C 的地址阶段随着 B 的数据阶段延长而一起延长

软件类比:就像 CPU 流水线的 stall 会级联到后续指令。一条 load 指令 cache miss → 后续 add 等依赖指令被 stall → 再后续的非依赖指令也可能被阻塞。


5. HTRANS 信号与传输类型

5.1 四种传输类型

HTRANS[1:0] 指示当前传输的类型:

HTRANS[1:0] 类型 含义 Subordinate 行为
0b00 IDLE 无数据需要传输 必须返回 OKAY(0 等待),忽略该传输
0b01 BUSY 在 burst 中间插入空闲周期 必须返回 OKAY(0 等待),忽略该传输
0b10 NONSEQ 单次传输 / burst 的第一拍 正常处理,地址与上次无关
0b11 SEQ burst 中的后续拍 正常处理,地址 = 上一地址 + size

软件类比:SEQ ≈ 数组顺序访问(ptr++);NONSEQ ≈ 随机访问(新地址);BUSY ≈ NOP(占位但后续关联);IDLE ≈ 真正的 NOP(无关联)。

5.2 综合示例

1783606930357_d

图 3-6:一个 4-beat 读 burst 中的 HTRANS 使用示例

逐周期分析(从 T0 到 T7):

时间段 HTRANS HADDR 说明
T0→T1 NONSEQ 0x20 burst 第一拍
T1→T2 BUSY 0x24 Manager 还没准备好第二拍,插入 BUSY
T2→T3 SEQ 0x24 第二拍开始(地址 0x24)
T3→T4 SEQ 0x28 第三拍开始(地址 0x28)
T4→T5 SEQ 0x2C 第四拍开始(地址 0x2C),但 Subordinate 插入等待
T5→T6 SEQ(保持) 0x2C(保持) HREADY=LOW,信号不变
T6→T7 最后一拍完成

重要规则

  • IDLE 和 BUSY 传输阶段,Subordinate 必须返回零等待 OKAY 响应
  • BUSY 只能出现在 burst 的中间拍(不能是第一拍或最后一拍,INCR 除外)
  • NONSEQ 启动一个新的传输序列

6. AHB Burst 传输

6.1 Burst 概念

Burst(突发)是一次传输多个连续数据单元的机制。**HBURST[2:0]** 控制 burst 类型。

软件类比:Burst ≈ DMA 传输中的 scatter-gather。一次设置地址和长度,硬件自动完成多拍数据搬运,开销远低于逐拍单独发起。

6.2 Burst 类型编码

HBURST[2:0] 类型 拍数 地址行为
0b000 SINGLE 1 单次传输
0b001 INCR 不限 递增,地址连续
0b010 WRAP4 4 边界回绕
0b011 INCR4 4 递增
0b100 WRAP8 8 边界回绕
0b101 INCR8 8 递增
0b110 WRAP16 16 边界回绕
0b111 INCR16 16 递增

6.3 Incrementing vs Wrapping

类型 地址行为 用途
Incrementing (INCR) 每一拍地址 = 前一拍地址 + 传输大小 顺序访问内存块
Wrapping (WRAP) 到达边界时地址回绕到边界起点 Cache line 填充

计算回绕边界boundary = burst_beats × transfer_size

  • 4-beat word burst(每拍 4 字节):boundary = 4 × 4 = 16 字节
  • 8-beat word burst:boundary = 8 × 4 = 32 字节

6.4 关键约束

  • 1KB 地址边界:递增 burst 不能跨过 1KB 地址边界
  • 地址对齐:每拍的地址必须对齐到传输大小(word 传输 → 4 字节对齐,HADDR[1:0]=0b00)
  • 固定长度 burst 必须使用 SEQ 结束(不能用 BUSY)

7. Wrap Burst 详解

7.1 地址回绕机制

Wrapping burst 是 AHB 中一个独特的设计。当地址到达 burst 边界时,下一个地址会回绕到 burst 的起始边界,而非继续递增。

回绕地址公式

1
wrap_addr = start_addr + ((start_addr + N × transfer_size) % boundary)

其中 boundary = burst_beats × transfer_sizeN 是当前拍号(0 起始)。

7.2 WRAP4 示例

1783606856374_d

图 3-8:WRAP4 word burst,起始地址 0x38,16 字节边界回绕

**起始地址 0x38,word 传输,boundary = 4 × 4 = 16 (0x10)**:

拍号 地址 计算
第 0 拍 (NONSEQ) 0x38 = start_addr
第 1 拍 (SEQ) 0x3C = 0x38 + 4
第 2 拍 (SEQ) 0x30 = 0x38 + 8 - 16(回绕!跨过 0x40 边界)
第 3 拍 (SEQ) 0x34 = 0x38 + 12 - 16

注意 0x3C → 0x30 的跳变:0x3C + 4 = 0x40,超过 16 字节边界 0x30-0x3F,所以回绕到 0x30

软件类比:Wrap ≈ ring buffer 中的索引回绕。就像 (head + offset) % buffer_size,AHB 的 wrap 在硬件层面实现了同样的循环寻址。

7.3 WRAP8 示例

1783606841177_d

图 3-10:WRAP8 word burst,起始地址 0x34,32 字节边界回绕

**起始地址 0x34,word 传输,boundary = 8 × 4 = 32 (0x20)**:

1
地址序列: 0x34 → 0x38 → 0x3C → 0x20 → 0x24 → 0x28 → 0x2C → 0x30

到达 0x3C 后,0x3C + 4 = 0x40 超过 32 字节边界,回绕到 0x20

为什么用 Wrap Burst? 当 CPU 需要从地址 0x34 开始加载一个 cache line(32 字节),如果顺序递增会访问 0x340x54,这意味着跨了两个 cache line 边界。Wrap burst 从 0x34 开始填充 cache line 的后半部分 0x300x3F,然后回绕到 0x20 填充前半部分——先返回”关键数据”(0x34)

软件类比:就像 HTTP Range 请求中的 multipart 响应——先返回用户请求的偏移量对应的数据,再补全前后的数据块。

7.4 INCR4 对比

1783606846674_d

图 3-9:INCR4 — 与 WRAP4 相同的起始地址,但不回绕

INCR4 从 0x38 开始:0x38 → 0x3C → 0x40 → 0x44(简单递增,不回绕)。


8. 等待状态下的传输类型变化

当 HREADY = LOW 时,Manager 禁止改变 HTRANS,但以下三种场景是例外:

8.1 场景一:IDLE → NONSEQ

1783606956096_d

图 3-13:等待状态下,从 IDLE 切换到 NONSEQ 启动新传输

规则:Manager 可以在 wait 期间将 HTRANS 从 IDLE 改为 NONSEQ,然后保持 NONSEQ 直到 HREADY=HIGH。

场景:完成一个 SINGLE burst 后,Manager 想在等待期间立即发起一个新 burst,不等当前传输完成就可以”预告”下一个传输。

8.2 场景二:固定长度 Burst 中 BUSY → SEQ

1783606948231_d

图 3-14:固定长度 burst 中,BUSY 切换到 SEQ

规则:在 INCR4/8/16 或 WRAP4/8/16 中,BUSY → SEQ 是合法的。改为 SEQ 后保持直到 HREADY=HIGH。

场景:burst 中 Manager 本来需要 BUSY 暂停,但 Subordinate 也拉低了 HREADY。在等待期间 Manager 准备好了,可以直接改为 SEQ 开始下一拍。

8.3 场景三:不定长度 Burst 中 BUSY → 任意类型

1783606941582_d

图 3-15:INCR burst 中,BUSY 切换到 NONSEQ 提前结束 burst

规则:仅在 INCR(不定长度)burst 中,BUSY 可以改为 SEQ(继续)、NONSEQ(新 burst)或 IDLE(结束)。

场景:Manager 发起了 INCR burst,但在中途决定不再需要更多数据,直接切换到 NONSEQ 开始新的传输。

8.4 规则总结

当前 HTRANS 允许改为 适用范围
IDLE NONSEQ 任意场景
BUSY SEQ 固定长度 burst(INCR4/8/16, WRAP4/8/16)
BUSY SEQ / NONSEQ / IDLE 不定长度 burst(INCR)
其他情况 禁止改变

关键原则:一旦 HTRANS 改为非 IDLE/BUSY 的有效传输类型,就必须保持该类型直到 HREADY=HIGH。


9. 其他特性简介

9.1 Locked Transfers(锁定传输)

通过 HMASTLOCK 信号实现。当 Manager 需要在多个传输之间保持对总线的独占访问时(例如原子 RMW 操作),断言 HMASTLOCK。总线在锁定的第一个传输完成后被锁住,直到 HMASTLOCK 取消断言。

典型用途:实现信号量(semaphore),确保 read-modify-write 的原子性。

软件类比:相当于数据库的行锁(SELECT … FOR UPDATE)— 读取 → 修改 → 写入期间,其他 Manager 无法访问同一资源。

9.2 Transfer Size(传输大小)

HSIZE[2:0] 控制每拍传输的数据宽度:8/16/32/64/128/256/512/1024 位。传输大小必须小于等于数据总线宽度。HSIZE 在整个 burst 中保持不变。

9.3 Write Strobes(写字节使能)

HWSTRB 信号允许 Manager 在写传输中只更新部分字节而非整个数据宽度。每 bit 对应 HWDATA 的 8 位。这是可选特性(Write_Strobes 属性控制)。

软件类比:相当于 C 语言的 bitfield 写入 — 通过掩码控制哪些字节被真正写入内存。

9.4 Protection Control(保护控制)

HPROT[3:0] 提供传输的访问属性:

名称 说明
HPROT[0] Data/Opcode 数据访问 / 指令取指
HPROT[1] Privileged 特权模式 / 用户模式访问
HPROT[2] Bufferable 是否允许缓冲
HPROT[3] Cacheable/Modifiable 是否可缓存 / 修改

9.5 Memory Types(内存类型)

AHB5 扩展了 HPROT 到 7 位(HPROT[6:0]),增加了 Allocate、Lookup 和 Shareable 属性,支持更精细的缓存策略:

  • Device-nE / Device-E:设备内存(不可缓存,不可合并)
  • Normal Non-cacheable:普通不可缓存内存
  • Write-through / Write-back:透写 / 回写缓存策略
  • Shareable:多核共享内存

9.6 Secure Transfers(安全传输)

通过 HNONSEC 信号区分 SecureNon-secure 传输。这是 AHB5 的可选特性(Secure_Transfers 属性),用于 TrustZone 安全扩展——确保 Non-secure 的 Manager 不能访问 Secure 的地址空间。

软件类比:相当于操作系统的用户态/内核态内存隔离,但在硬件层面强制执行。


10. 内容回顾

本文从零开始介绍了 AHB 协议的核心概念,以下是关键知识点回顾:

10.1 总线基础

知识点 一句话总结
AHB 定位 SoC 内部的高性能总线,连接 CPU / DMA 与高速外设
三组件模型 Manager 发起传输 → Interconnect 路由 → Subordinate 响应
流水线特性 当前传输的地址阶段与上一传输的数据阶段同时进行,实现每周期一个传输

10.2 核心信号

信号 角色 记忆要点
HCLK 时钟 所有信号在上升沿采样
HADDR 地址 字节地址,地址阶段有效
HWRITE 方向 HIGH=写, LOW=读
HTRANS 传输类型 IDLE(00) / BUSY(01) / NONSEQ(10) / SEQ(11)
HREADY 流控 LOW = 插入等待;HIGH = 传输完成
HRESP 状态 LOW = OKAY;HIGH = ERROR
HWDATA/HRDATA 数据 写数据总线和读数据总线

10.3 传输与等待状态

知识点 一句话总结
无等待传输 地址阶段 1 周期 + 数据阶段 1 周期 = 2 周期完成
等待状态 Subordinate 拉低 HREADY → Manager 保持当前信号不变 → 等同 CPU pipeline stall
等待级联 前一个传输的等待会自动延长后一个传输的地址阶段
等待时 HTRANS 变化 仅三种例外:IDLE→NONSEQ、固定长度 burst 中 BUSY→SEQ、INCR 中 BUSY→任意

10.4 Burst 传输

类型 编码 拍数 地址行为
SINGLE 0b000 1
INCR 0b001 不限 递增
INCR4/8/16 0b011/101/111 固定 递增
WRAP4/8/16 0b010/100/110 固定 边界回绕

关键约束:递增 burst 不跨 1KB 边界;WRAP 边界 = beat数 × 传输大小

10.5 传输类型 (HTRANS)

HTRANS 含义 Subordinate 行为
IDLE 无传输 必须返回 OKAY,忽略
BUSY 暂停一拍 必须返回 OKAY,忽略(地址已指向下一拍)
NONSEQ 新序列第一拍 正常处理
SEQ 序列后续拍 地址 = 上一地址 + size

记忆技巧:一个 burst 的典型 HTRANS 序列 = NONSEQ → (BUSY?) → SEQ → SEQ → ... → SEQ

10.6 其他特性速查

特性 信号 用途
Locked Transfer HMASTLOCK 原子 RMW,相当于 SWP 指令的硬件锁
Write Strobes HWSTRB 按字节掩码写入,只更新部分数据位
Protection HPROT 标记 cacheable/bufferable/privileged 属性
TrustZone HNONSEC Secure / Non-secure 访问隔离

附录:关键术语速查

术语 说明
Manager 发起传输的组件(原 Master)
Subordinate 响应传输的组件(原 Slave)
Interconnect 地址译码 + 读数据多路复用
Address Phase 地址和控制信号有效的时钟周期
Data Phase 数据有效的时钟周期
HREADY 传输完成信号,LOW = 插入等待
HTRANS 传输类型:IDLE/BUSY/NONSEQ/SEQ
HBURST 突发类型:SINGLE/INCR/WRAP/INCR4/8/16/WRAP4/8/16
Burst 一次多拍连续传输
Beat Burst 中的单次传输
Wait State HREADY=LOW 时的扩展时钟周期
Wrapping 地址到达边界后回绕到起始处

参考资料:ARM AMBA 5 AHB Protocol Specification (ARM IHI 0033C, Issue C, September 2021)

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