什么是APB协议/总线
APB的全称为Advanced Peripheral Bus。顾名思义,其设计之初的主要目的就是用该协议连接外设。但由于APB总线发布已经20多年,以现在的眼光看,该总线连接的外设往往也是低俗且低功率的外设,如I2C,SPI等,除了连接低速外设之外,APB总线还广泛用于配置各种IP的寄存器。
下图为一个典型的AMBA总线的系统架构,其中APB总线是AHB总线的扩展,方便外设连接到系统总线上,其中AHB和APB之间有一个转接桥来进行连接。
此外为了使得APB能够容易的被整合进大部分设计流程中,APB规定所有的信号必须在时钟的上升沿进行传递。
APB2协议
APB2信号列表
对于AMBA协议,APB的信号都是以P开头,AHB的信号都是以H开头,而AXI的信号都是以A开头。APB2的信号列表如下表所示:
Signal name | direction | description |
PCLK | global | 时钟信号,上升沿同步 |
PRESETn | global | APB总线复位信号为低有效并且通常将该信号直接连接到系统总线的复位信号 |
PADDR | M-->S | 地址总线,最多可以高达32位 |
PSEL | M-->S | 选通信号,当该信号拉高意味着要发起一次传输了 |
PENABLE | M-->S | 使能信号,用于便是一次APB传输的第二个周期(在阻塞情况下为第二个及以上的周期) |
PWRITE | M-->S | 该信号为高标志这次是写传输,反之则为读传输 |
PWDATA | M-->S | 写数据总线,有master在写周期进行持续性驱动,最高可达32位 |
PRDATA | S-->M | 读数据总线,有slave在读周期进行持续性驱动,最高可达32位 |
写操作时序
可以看到写操作非常的简单:
·T2->T3这个周期
·PSEL拉高,意味着要发起一次新的传输了。
·PWRITE信号为1,因此这次传输为写操作
·PWDATA为要传输的数据,PADDR为要写的地址,二者都应该保持不变,知道此次传输结束
·PSEL拉高的第一个时钟周期,PENABLE应该为0
·T3->T4这个周期
·PSEL信号继续拉高
·PWRITE,PADDR,PWDATA应该保持不变,
·PENABLE信号拉盖,用于代表这已经是写传输的第二个周期了
至此一次传输结束,可以看到,APB对每一笔数据的传输,需要华为两个时钟周期,且APB的数据传输不支持流水线操作,即不可以重叠,因此APB是非常低效的。
理论上写数据完全可以同时给出写地址和写数据,一拍搞定,但是那个年代芯片本身的支撑工艺以及片上互联导致一个周期可能无法完成从master向slave写入数据的整个操作流程,因此采用两拍的方式。
如果master想要马上发起一次新的传输,可以不拉低PSEL,但是必须要将PENABLE拉低,否则slave的判断逻辑就会出现问题。
由于APB向下兼容,这一历史问题延续至今,好在APB的应用场景本身就是配置寄存器等操作,因此多花一个时钟周期也没什么大不了的。
读操作时序
可以看到读操作非常的简单,和写几乎一样。需要特别注意的是,T3以后,也就是进入enable周期后,APB的slave设备必须要将m所读取的数据准备好,以便m可以在enable的周期末也就是T4的上升沿触发时将数据读取。
APB的状态机
APB2的状态机如下所示:
·IDLE:此时为默认状态,PSEL和PENABLE都为0,没有通信请求。
·SETUP:当需要发起传输的时候,会进入该状态,此时PSEL为1,PENABLE为0。
PSEL从0到1说明要发起一次传输了,而PENABLE为0表示这是传输的第一个时钟周期
·ENABLE:这个状态PENABLE需要拉高,进而完成数据的传输。
这个状态机只是便于我们理解,并且这个状态机时针对整个传输过程而言的。对于实际的master或者slave的设计完全可以不用状态机来实现。甚至slave都可以用纯粹的组合逻辑来实现。
APB2速问速答
Q:APB slave是否真的需要penable信号?
A:分两种情况讨论:
·如果APB slave 有PCLK时钟信号的话,那么确实不需要penable信号,检测到PSEL为高,即进入到access阶段,然后在第二个时钟周期完成数据传输即可。
·如果APB slave 是纯粹的组合逻辑,也就是没有PCLK的情况下,这个时候是需要penable信号的。
APB3协议
新增两个信号
APB3在APB2的基础上增加了两个信号,PREADY和PSLVERR,这两个信号都是由slave产生的。
对于写操作而言,PREADY信号用于标志slave设备是否已经准备好接收这一笔数据。而对于读操作而言,PREADY信号用于标志slave设备是否已经准备好了要返回给Master数据。
有了PREAY信号,从机就可以反压主机。因此PREADY这个信号可以说是非常的好,它让主从之间的通信更加的可靠,也增加了从机的控制能力,不至于出现主机写的数据从机压根没有收到或者从机没有准备好读数据,进而主机读到错误数据的情况。
此外我再讲解一下为什么会出现从机没有准备好的情况。对于读操作而言,非常好理解,你要读的数据我还没有准备好(可能正在计算),当然不能拉高PREADY,而写的话,这种情况往往出现在写特定的地址,这个时候外设本身要进行判断是否可以写,因此两个周期完成不了,就不能拉高PREADY。
PSLVERR,(apb slave error)顾名思义,用于从slave向master返回传输错误,这个错误是slave自己定义的,比如写了不允许写的地址,即非法地址访问。或者是访问超时了,slave回应不了,就可以拉高这个信号,避免总线锁死。
上图是没有wait state的情况,两拍完成写操作。和APB2的区别在于多了个PREADY,需要在传输的第二排也就是真正发生数据传输的那一拍拉高。
我们再看看有wait state的情况,上图4拍才完成写操作。此时setup还是一个周期(从T1->T2),而access是三个周期(从T2->T5)。可以看到主机信号应该保持不变,一直持续到从机的PREADY信号拉高以后的一拍完成传输,才可以改变其他信号。
我们直接看复杂的情况,可以看到PREADY信号和PRDATA信号在同一拍发生变化。此时的PREADY信号也可以理解为从机此时提供的PRDATA才是有效的数据。进而完成了一次完成的传输过程。
以写为例,实际上就是在真正发起传输的那一排(也就是PREADY拉高的那一拍)顺势拉高PSLVERR,用于标志这次传输失败。
为什么需要APB4?
APB4在APB3的基础上又增加了PPORT和PSTRB信号。
PPORT信号有三个比特,含义分别如下:
对于CPU而言,可以工作在用户模式下也可以工作在特权模式下,对于支持trustzone的cpu,可以工作在secure world下,也可以工作在normal mode下。又由于现在的系统越来越复杂了,以前的外设是随意读写都可以,现在的一些外设或memory要求只能在secure下或者privilege模式下访问,因此就需要PPROT信号。
而PSTRB信号则比较好理解,它允许稀疏的写。其中的没有给比特对应于PWDATA的每一个字节。用1代表PWDATA的这一字节是否有效,其对应关系如下图:
至于读的话PSTRB随便让它是啥就行,不反转最好以减少功耗。这个信号是针对写而言的,读的话无所谓。
APB4和APB3以及APB3和APB2的兼容性问题
以APB4的slave和APB3的master为例,这时候应该吧PSTRB信号固定为全1,PPROT信号则取决于slave如何使用该信号,根据不同的场景固定为不同的值。
而APB3的slave和APB4的master相连接,这个时候实际上需要一个转接桥,因为本身可能只想写某一个字节,而slave此时也不知道,那就需要一个中间逻辑将pwdata变成想要的值。实际上写起来也很麻烦,因此此时最好将APB3的slave改成APB4协议 。
至于APB3和APB2不建议一起用,因为APB2没有PREADY反压机制,因此实际使用起来完全不一样。