APB总线信号详解与状态机实战
各位同学,今天我们来啃一块硬骨头——APB从设备接口的信号和状态机。说实话,APB在AMBA家族里算是最简单的了,但简单不代表不重要。我见过太多工程师在APB接口上翻车,原因往往就是没把这几个信号和状态转换吃透。
咱们先看一张总览图,把APB从设备的核心逻辑串起来。
APB从设备接口信号——逐个拆解
APB从设备一共10个信号,不多不少。我习惯把它们分成三组来记:控制组、数据组、响应组。咱们一个一个过。
1. 全局信号
| 信号 | 方向 | 说明 |
|---|---|---|
| PCLK | 输入 | 总线时钟,所有信号在上升沿采样 |
| PRESETn | 输入 | 异步复位,低有效,把从设备状态机拉回IDLE |
PCLK和PRESETn是所有从设备共享的。嗯,这里要注意:PRESETn是异步复位,但复位释放必须同步到PCLK。我踩过这个坑——曾经有个设计直接用异步复位清寄存器,结果在复位释放时出现了亚稳态,仿真怎么都跑不过。
2. 控制信号
| 信号 | 方向 | 说明 |
|---|---|---|
| PSEL | 输入 | 从设备选择,高有效。只有PSEL为高时,该从设备才参与传输 |
| PENABLE | 输入 | 传输使能,在ACCESS阶段拉高,表示当前是有效数据周期 |
| PWRITE | 输入 | 读写指示:1=写操作,0=读操作 |
PSEL和PENABLE的组合决定了传输阶段。你想想看,PSEL单独拉高时,从设备只做地址译码,不采样数据。只有PSEL和PENABLE同时为高,才真正进行读写。这个逻辑在状态机里会体现得很清楚。
3. 地址与数据信号
| 信号 | 方向 | 说明 |
|---|---|---|
| PADDR | 输入 | 32位地址总线,在SETUP阶段有效 |
| PWDATA | 输入 | 写数据总线,在ACCESS阶段由主控驱动 |
| PRDATA | 输出 | 读数据总线,由从设备在ACCESS阶段驱动 |
PADDR在SETUP阶段就稳定了,但数据只在ACCESS阶段才有效。这个时序关系很多人搞混。我建议你画波形图的时候,把PADDR和PWDATA/PRDATA分开画,一眼就能看出谁先谁后。
4. 响应信号
| 信号 | 方向 | 说明 |
|---|---|---|
| PREADY | 输出 | 从设备准备好信号。高表示传输完成,低表示需要插入等待周期 |
| PSLVERR | 输出 | 传输错误指示。仅在PREADY为高时有效 |
PREADY是APB从设备最重要的信号,没有之一。它直接控制传输能否结束。我曾经做过一个外设,内部FIFO满了之后需要等待,PREADY拉低一个周期,主控就会自动延长ACCESS阶段。这个机制非常实用。
APB状态机——三态转换的艺术
APB主控端的状态机只有三个状态:IDLE、SETUP、ACCESS。简单吧?但越简单的东西,越容易在细节上出问题。
状态详解
- IDLE状态:总线空闲,PSEL和PENABLE都为低。从设备不参与任何传输。
- SETUP状态:主控拉高PSEL,地址PADDR和方向PWRITE在此时稳定。这个状态只持续一个时钟周期。
- ACCESS状态:主控拉高PENABLE,真正的数据传输发生。如果从设备来不及响应,可以拉低PREADY,让ACCESS延长。
为什么SETUP只持续一个周期?说白了,APB的设计哲学就是简单高效。地址和方向在SETUP阶段准备好,下一个周期直接进入ACCESS做数据交换。不需要握手,不需要等待——除非从设备主动要求。
典型传输时序——写操作与读操作
咱们用两个例子把状态机和信号串起来看。
APB写操作(无等待)
时钟周期: T1 T2 T3 T4
PCLK : __|‾|____|‾|____|‾|____|‾|__
状态 : IDLE SETUP ACCESS IDLE
PSEL : 0 1 1 0
PENABLE : 0 0 1 0
PWRITE : 0 1 1 0
PADDR : ---- Addr Addr ----
PWDATA : ---- ---- Data ----
PREADY : 1 1 1 1
你看,T1是IDLE,T2进入SETUP,地址和方向就绪。T3进入ACCESS,PENABLE拉高,数据写入从设备。T4回到IDLE。整个过程干净利落。
APB读操作(带等待)
时钟周期: T1 T2 T3 T4 T5
PCLK : __|‾|____|‾|____|‾|____|‾|____|‾|__
状态 : IDLE SETUP ACCESS ACCESS IDLE
PSEL : 0 1 1 1 0
PENABLE : 0 0 1 1 0
PWRITE : 0 0 0 0 0
PADDR : ---- Addr Addr Addr ----
PRDATA : ---- ---- ---- Data ----
PREADY : 1 1 0 1 1
这里T3进入ACCESS后,从设备PREADY拉低,表示数据还没准备好。T4继续ACCESS,PREADY拉高,数据才出现在PRDATA上。T5回到IDLE。
从设备接口设计要点
最后,我总结几个从设备接口设计的核心原则:
- 地址译码要快:PADDR在SETUP阶段就稳定了,从设备必须在进入ACCESS前完成译码。我建议用组合逻辑做地址比较,不要等到时钟沿。
- PREADY不能有毛刺:PREADY是组合输出,但必须保证在PCLK上升沿前后稳定。我曾经因为PREADY的glitch导致主控误判传输结束,查了两天才找到原因。
- PSLVERR只在PREADY为高时有效:这是协议明确规定的。不要在等待周期里改变PSLVERR,否则主控会采样到错误的状态。
- 寄存器更新时机:写寄存器应该在PCLK上升沿且PSEL&PENABLE&PWRITE&PREADY都为高时更新。读寄存器则用组合逻辑输出到PRDATA。