上一篇文章简单讲解了什么是AMBA总线,简单来说,AMBA总线是一系列协议。定义了适用于不同场景的总线家族。今天我们就来讲AMBA总线中最简单的APB总线。
什么是APB协议/总线
APB的全称为Advanced Peripheral Bus。顾名思义,其设计之初的主要目的就是用该协议连接外设。但由于APB总线自发布至今已经过去了20多年了,因此以现在的眼光看,该总线没有什么高级一说,其连接的外设也往往是低速且低功率的外设,如I2C、UART、SPI等,除了连接低速外设之外,APB总线还广泛用于配置各种IP的寄存器(这些IP预留用户控制信号,由软件进行配置,这个时候就可以选择使用APB总线来配置这些寄存器)。
下图为一个典型的AMBA总线的系统架构:其中APB总线是AHB总线的扩展,方便外设连接到系统总线上,其中AHB和APB之间有一个转接桥来进行连接。
此外为了使得APB能够容易的被整合进大部分的设计流程中,APB规定所有的信号必须在时钟的上升沿进行传递。
下面简单介绍一下APB的发展历史,ARM公司于1998年发布了APB2,又于2003年发布了APB3,在2010年又发布了APB4。目前最常见的为APB3或APB4,其主要区别如下:
APB2:APB总线的基础版本。
APB3:
增加PREADY信号:用于反压master(其在读和写两个场景中含义略有不同,过会讲解)。
增加PSLVERR:用于代表传输是否发生错误。
APB4:
增加PPROT保护信号。
增加PSTRB代表字节选通。
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在写周期进行持续性驱动(PWRITE为高),最高可达32位。 |
PRDATA | S-->M | 读数据总线,由Slave在读周期进行持续性驱动(PWRITE为低),最高可达32位。 |
写操作时序
可以看到写操作非常的简单:
T2->T3这一个周期
PSEL信号拉高,意味着要发起一次新的传输了。
PWRITE信号为1,因此此次传输为写操作。
PWDATA为要传输的数据,PADDR为要写的地址。二者都应该保持不变,直到此次传输结束。
而PSEL拉高的第一个时钟周期,PENABLE应该为0。
T3->T4这一个周期
PSEL信号继续拉高
PWRITE、PADDR、PWDATA应该保持不变
PENABLE信号拉高,用于代表这已经是写传输的第二个周期了
至此一次传输结束。可以看到,APB对每一笔数据的传输,需要花费两个时钟周期。且APB的数据传输不支持流水线操作(即不可以重叠)。因此APB是非常低效的。
理论上写数据完全可以同时给出写地址和写数据,一拍就搞定,为什么APB要大费周章弄成两拍呢?这主要是那个年代的芯片本身的制程工艺以及片上互连线导致的。一个周期可能无法完成从Master向Slave写入数据的整个操作流程。因此采用两拍的方式,第一拍告诉你,我要开始传输啦!(称为setup phase)第二拍才真正的完成数据的传输。(称为access phase)。
如果Master想要马上发起一次新的传输,可以不拉低PSEL让其继续为1,但是必须要将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表示这是传输的第一个时钟周期。(这个状态也就是setup phase)
ENABLE:这个状态PENABLE需要拉高,进而完成数据的传输。
这个状态机模型只是便于我们的理解。并且这个状态机模型是针对整个传输过程而言的。对于实际的master或者slave的设计完全可以不用状态机实现。甚至slave都可以用纯粹的组合逻辑来实现,下面会讲到如何实现。
APB2速问速答
Q:貌似根据上面的状态机模型以及读写时序图。有没有PENABLE信号实际上都可以完成APB传输,那么APB slave是否真的需要penable信号?
A:分两种情况讨论:
如果APB slave有PCLK时钟信号的话,那么确实是不需要penable信号的。检测到PSEL为高,即进入到access阶段。然后在第二个时钟周期完成数据传输即可。相应的代码如下所示(这段代码是网上找到的)
`timescale 1ns/1ps `define DATAWIDTH 32 `define ADDRWIDTH 8 `define IDLE 2'b00 `define W_ENABLE 2'b01 `define R_ENABLE 2'b10 module APB_Slave ( input PCLK, input PRESETn, input [`ADDRWIDTH-1:0] PADDR, input PWRITE, input PSEL, input [`DATAWIDTH-1:0] PWDATA, output reg [`DATAWIDTH-1:0] PRDATA, ); reg [`DATAWIDTH-1:0] RAM [0:2**`ADDRWIDTH -1]; reg [1:0] State; always @(negedge PRESETn or posedge PCLK) begin if (PRESETn == 0) begin State <= `IDLE; PRDATA <= 0; end else begin case (State) `IDLE : begin PRDATA <= 0; if (PSEL) begin if (PWRITE) begin State <= `W_ENABLE; end else begin State <= `R_ENABLE; end end end `W_ENABLE : begin if (PSEL && PWRITE) begin RAM[PADDR] <= PWDATA; end State <= `IDLE; end `R_ENABLE : begin if (PSEL && !PWRITE) begin PRDATA <= RAM[PADDR]; end State <= `IDLE; end default: begin State <= `IDLE; end endcase end end endmodule
当PSEL & !PENABLE为1的时候,代表是setup stage,实际上此时slave什么都不用干
当PSEL & PENABLE为1的时候,代表是access stage,slave顺势完成数据传输即可
如果APB slave是纯粹的组合逻辑,也就是没有PCLK的情况下。这个时候是需要penable信号的。
APB3协议
新增的两个信号
APB3在APB2的基础上增加了两个信号,PREADY和PSLVERR,这两个信号都是由slave产生的。
对于写操作而言,PREADY信号用于标志slave设备是否已经准备好接收这一笔数据。而对于读操作而言,PREADY信号用于标志slave设备是否已经准备好了要返回给Master的数据。
有了PREADY信号,从机就可以反压主机。因此PREADY这个信号可以说是非常的棒啊,它让主从之间的通信更加的可靠,也增加了从机的控制能力,不至于出现主机写的数据从机压根没收到或者从机没有准备好读数据,进而主机读到错误的数据的情况。
此外我再讲解一下为什么会出现从机没有准备好的情况。对于读操作而言,非常好理解,你要读的数据我还没准备好呢(可能正在运算),那我当然不能拉高PREADY,不然就给了你错误的数据了。只有我数据准备好的时候,我拉高PREADY,这样才能确保读不出问题。而写的话,这种情况往往出现在写特定的地址,这个时候外设本身要进行判断是否可以写,因此两个周期就完成不了,就暂时不能拉高PREADY,你的Master就必须要维持住。当PREADY拉高代表这一拍能够写进去了。因此主机也就可以不再维持原有的状态了。
PSLVERR,(apb slave error)顾名思义。用于从slave向master返回传输错误,这个错误是slave自己定义的,比如写了不允许写的地址,即非法地址访问。或者是访问超时了,slave回应不了了。就可以拉高这个信号,从而避免总线锁死。
写操作时序
上图是没有wait states的情况。两拍完成写操作。和APB2的区别在于多了个PREADY,需要在传输的第二拍也就是真正发生数据传输的那一拍拉高。其它的和上面的写时序是一模一样的,因此不再讲解。
我们再看看有wait states的情况,上图四拍才完成写操作。此时setup还是一个周期(从T1->T2),而access是三个时钟周期(从T2->T5)。可以看到主机的信号应该保持不变,一直持续到从机的PREADY信号拉高以后,等待拉高以后的这一拍完成传输,才可以改变其它的信号。(即T1->T5这段过程,PADDR、PWRITE、PSEL、PWDATA都应该保持不变)。
读操作时序
我们直接看复杂点的情况,可以看到PREADY信号和PRDATA信号在同一拍发生变化。此时的PREADY信号也可以理解为从机此时提供的PRDATA才是有效的数据。进而完成了一次完整的传输过程。
Error response
以写为例,实际上就是在真正发起传输的那一拍(也就是PREADY拉高的那一拍)顺势拉高PSLVERR,用于标志这次传输失败。
为什么需要APB4?
APB4在APB3的基础上又增加了PPROT和PSTRB信号。
PPROT信号有三个比特,含义分别如下:
对于CPU而言,可以工作在用户模式下也可以工作在特权模式下(比如RISC-V的USM三种模式)。对于支持trustzone的CPU,可以工作在secure world下,也可以工作在normal mode下。又由于现在的系统越来越复杂了,以前的外设是随意读写都可以,现在的一些外设或memory(比如一些CSR寄存器,Trusted RAM等)要求只能在secure下或者privileged模式下访问,因此就需要PPROT信号。
而PSTRB信号则比较好理解,它允许稀疏的写。其中的每一个比特对应于PWDATA的每一个字节。用1代表PWDATA的这一字节是否有效,其对应关系如下图所示:
至于读的话把PSTRB随便让它是啥就行,不翻转最好以减少功耗。这个信号是针对写而言的,读的话无所谓。
APB4和APB3以及APB3和APB2的兼容性问题
以APB4的slave和APB3的master为例,这个时候应该把PSTRB信号固定为全1,PPROT信号则取决于Slave是如何使用该信号的,根据不同的场景固定为不同的值。
而APB3的slave和APB4的master相连接,这个时候实际上需要一个转接桥,因为本身可能只想写某一个字节,而slave此时不支持也不知道,那就需要一个中间逻辑将pwdata变成想要的值。(比如读回来时32'h2345,想将最高字节改写为6,此时只写一个32'h6000,PSTRB为1000,标志别的字节不要动。这个时候就需要一个中间逻辑将写的数据变成32'h6345)。实际上写起来也很麻烦,因此此时最好将APB3的slave改成APB4协议。
至于APB3和APB2不建议一起用,因为APB2没有PREADY反压机制,因此实际使用起来完全不一样,强行一起用会有巨大的坑。
审核编辑:刘清
-
RAM
+关注
关注
8文章
1367浏览量
114517 -
AMBA总线
+关注
关注
0文章
35浏览量
9529 -
状态机
+关注
关注
2文章
492浏览量
27470
原文标题:【芯片设计】深入理解AMBA总线(一)APB总线入门
文章出处:【微信号:IC修真院,微信公众号:IC修真院】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论