第2章 AHB协议详解:总线架构、传输操作、仲裁机制与从机接口设计

AHB(Advanced High-performance Bus)是AMBA总线体系中的核心。说白了,它就是SoC内部的高速公路。我做了这么多年芯片,见过太多因为AHB没用好导致性能翻车的案例。今天咱们就把AHB的里里外外讲透。

2.1 AHB总线架构

AHB总线采用共享总线架构。什么意思?就是所有主设备共享一套地址、数据和控制信号。你想想看,这就像一条多车道的高速公路,多个入口(主设备)共用同一条路。

一个典型的AHB系统包含以下组件:

  • AHB主设备(Master):发起传输的模块,比如CPU、DMA控制器
  • AHB从设备(Slave):响应传输的模块,比如SRAM、外设寄存器
  • AHB仲裁器(Arbiter):决定哪个主设备获得总线使用权
  • AHB译码器(Decoder):根据地址选择对应的从设备
  • 多路选择器(Mux):将选中从设备的响应信号路由回主设备

核心要点:AHB的地址和数据总线是分离的。地址总线是单向的(主→从),数据总线是双向的。这个设计让流水线操作成为可能。

我在项目中遇到过一个问题:有人把AHB的地址总线和数据总线混在一起处理,结果时序收敛不了。记住,地址总线和数据总线在物理实现上要分开布线。

2.2 AHB传输操作

AHB传输分为两个阶段:地址阶段和数据阶段。地址阶段只占一个时钟周期,数据阶段可能需要多个周期(比如等待从设备响应)。

2.2.1 基本传输流程

一个完整的AHB传输包含以下信号交互:

// AHB单次传输时序示例
// 时钟上升沿采样
always @(posedge HCLK) begin
  if (HTRANS == NONSEQ) begin
    // 地址阶段:HADDR、HWRITE、HSIZE在此时有效
    // 数据阶段:HWDATA(写)或HRDATA(读)在下一个周期有效
  end
end

传输类型由HTRANS[1:0]控制:

HTRANS[1:0] 传输类型 说明
00 IDLE 空闲传输,主设备不请求总线
01 BUSY 主设备忙,插入空闲周期
10 NONSEQ 非连续传输,新地址
11 SEQ 连续传输,地址递增

个人经验:我建议新手在设计主设备时,尽量少用BUSY传输。BUSY会让总线利用率下降,而且很多从设备对BUSY的处理并不完善。能用NONSEQ和SEQ搞定的事,别整花活。

2.2.2 突发传输

AHB支持多种突发传输模式,由HBURST[2:0]控制:

  • SINGLE:单次传输,最常用
  • INCR:不定长递增突发
  • WRAP4/8/16:回环突发,常用于Cache line fill
  • INCR4/8/16:定长递增突发

为什么要用突发传输?举个例子:CPU从内存加载一段连续数据,如果用单次传输,每次都要重新仲裁。用突发传输,一次仲裁就能传多个数据,效率高得多。

我曾经优化过一个视频处理芯片,把DMA的传输从单次改成INCR16突发,总线利用率从40%提升到了85%。嗯,这就是突发传输的魅力。

2.3 AHB仲裁机制

仲裁是AHB的核心。多个主设备都想用总线,谁先上?仲裁器说了算。

2.3.1 仲裁流程

  1. 主设备通过HBUSREQ信号请求总线
  2. 仲裁器在下一个周期通过HGRANT信号授权
  3. 获得授权的主设备在HMASTER上输出自己的ID
  4. 主设备开始传输,同时拉低HBUSREQ

注意:仲裁发生在地址阶段。也就是说,当前主设备还在传输数据时,下一个主设备的仲裁已经开始了。这就是AHB的流水线特性。

2.3.2 仲裁算法

常见的仲裁算法有两种:

  • 固定优先级:谁优先级高谁先上。简单,但低优先级设备可能饿死。
  • 轮询(Round-Robin):轮流使用。公平,但高优先级设备可能等太久。

我个人习惯用混合策略:高优先级设备用固定优先级,其他设备用轮询。比如CPU用最高优先级,DMA和GPU用轮询。这样既保证了CPU的实时性,又不会让其他设备饿死。

2.4 AHB从机接口设计

从机接口设计是AHB中最容易出问题的地方。我见过太多从机接口因为时序问题导致整个芯片无法工作。

2.4.1 从机接口信号

一个标准的AHB从机需要实现以下信号:

// AHB从机接口模板
module ahb_slave (
    input         HCLK,
    input         HRESETn,
    input         HSEL,
    input  [31:0] HADDR,
    input         HWRITE,
    input  [2:0]  HSIZE,
    input  [2:0]  HBURST,
    input  [3:0]  HPROT,
    input  [1:0]  HTRANS,
    input  [31:0] HWDATA,
    input         HREADY,
    output        HREADYOUT,
    output [31:0] HRDATA,
    output        HRESP
);

2.4.2 关键设计要点

1. HREADYOUT信号

从机通过HREADYOUT告诉主设备是否准备好。如果从机需要等待(比如访问慢速外设),就拉低HREADYOUT插入等待周期。

2. 地址译码

从机必须正确译码HADDR。注意:AHB的地址是以字节为单位的,但传输宽度由HSIZE决定。比如HSIZE=2(4字节传输),地址必须是4字节对齐的。

3. 错误响应

当从机遇到非法地址或操作时,通过HRESP返回ERROR响应。主设备收到ERROR后应该终止当前传输。

避坑指南:我曾经设计过一个从机接口,忘记处理HSEL信号。结果所有从机都响应同一个地址,总线冲突导致数据完全错乱。记住:HSEL是门控信号,没有HSEL选中时,从机必须保持高阻态。

2.4.3 从机状态机

从机接口的核心是一个状态机:

// 简化的从机状态机
typedef enum {IDLE, ACCESS, WAIT, ERROR} slave_state_t;

always @(posedge HCLK or negedge HRESETn) begin
    if (!HRESETn)
        state <= IDLE;
    else case (state)
        IDLE:   if (HSEL & HREADY) state <= ACCESS;
        ACCESS: if (!HREADYOUT)    state <= WAIT;
                else if (error)    state <= ERROR;
                else               state <= IDLE;
        WAIT:   if (ready)         state <= ACCESS;
        ERROR:                     state <= IDLE;
    endcase
end

这个状态机看起来简单,但实际项目中要考虑很多细节。比如:在WAIT状态下,地址信号可能变化吗?答案是:不会。AHB协议保证在等待周期内地址保持不变。

2.5 本章小结

AHB协议说复杂也复杂,说简单也简单。核心就三点:

  • 流水线操作:地址阶段和数据阶段重叠,提高吞吐量
  • 集中仲裁:仲裁器统一管理总线使用权
  • 从机响应:从机通过HREADYOUT控制传输节奏

嗯,把这些搞明白,AHB就算入门了。下一章咱们讲AHB的高级特性,包括分块传输、锁定传输和总线矩阵。这些在实际项目中非常有用。

最后说一句:学AHB最好的方法就是动手写代码。找个开源SoC项目,看看里面的AHB总线是怎么实现的,比自己闷头看书强一百倍。

AHB总线架构核心知识体系 主设备1 主设备2 主设备3 仲裁器 地址译码器 从设备1 从设备2 从设备3 Mux HGRANT/HBUSREQ HSEL/HADDR HRDATA AHB总线核心特征 • 流水线操作:地址阶段与数据阶段重叠,提高总线利用率 • 集中仲裁:仲裁器统一管理多个主设备的总线请求 • 地址译码:译码器根据地址选择对应的从设备 • 多路选择:Mux将选中从设备的响应数据路由回主设备 • 支持突发传输:单次仲裁可传输多个数据,提升效率

专注资料整理