博客不是写书,基本的背景也不做什么介绍了,了解的人是不会介意这些东西的。
一、AHB的基本介绍
AHB是ARM退出的AMBA总线系列中的其中一种,它是一种高性能的pipe系统总线。
1. AHB总线有一下特性:
a.Burst 传输
b.Split 事务处理
c.单周期master移交
d.单一时钟沿操作
e.无三态
f.更宽的数据总线配置(64/128)
2. AHB总线系统的架构
AHB总线的强大之处在于它可以将微控制器(CPU)、高带宽的片上RAM、高带宽的外部存储器接口、DMA总线master、各种拥有AHB接口的控制器等等连接起来构成一个独立的完整的SOC系统,不仅如此,还可以通过AHB-APB桥来连接APB总线系统。AHB可以成为一个完整独立的SOC芯片的骨架。
下图是一个典型的AHB系统总线的结构示意图
3. AHB总线的组成
下图清楚的显示了AHB总线的各个组成部分:
总线中,有多个master和slave,一个仲裁器(arbiter)和一个译码器(decoder)组成。
如果再将AHB总线细分,可以分为三组总线:写数据总线(HWDATA),读数据总线(HRDATA)和地址控制总线(HADDR)。从上面的结构图中可以看出,这三组总线相互分离互不干扰。对于每一组总线来说,同时只能由一个master或者slave来独占,这时需要仲裁器来决定将总线的控制权交与哪个设备,并控制多路选择器来选择已经获得控制权的那个设备来传输数据和地址信息。译码器根据地址来选择让哪个slave的数据通过选择器。
一般来讲,我们称主动发起操作的设备为master,被动响应master的为slave。
二、AHB总线的信号
AHB总线的信号都是以H开头,以区别其他的AMBA总线信号
信号名 | 信号源 | 信号功能 |
HCLK Bus clock |
clock source | 总线时钟信号,都是上升沿有效 |
HRESETn Reset |
reset controller | 系统reset信号,低有效 |
HADDR[31:0] address bus |
master | 32位系统地址总线 |
HTRANS[1:0] transfer type |
master | transfer类型,一共有四种类型:NONSEQUENTIAL, SEQUENTAL, IDLE 或者BUSY |
HSIZE[2:0] transfer size |
master | 每一个transfer传输的数据大小。以字节为单位。最高支持1024位 |
HBURST[2:0] burst type |
master | transaction类型,一共有8种 |
HPROT[3:0] protection control |
master | 保护控制信号,一般不用 |
HWDATA[31:0] write data bus |
master | 这是写数据信号 |
HSELx slave select |
decoder | slave选择信号 |
HRDATA[31:0] read data bus |
slave | 这是读数据信号 |
HREADY transfer done |
slave | 当这个信号为高时,表示当前transfer完成。slave也可以通过拉低这个信号来延长一个transfer。注意:slave需要2个HREADY信号,一个作为输出,一个作为输入 |
HRESP[1:0] transfer response |
slave | slave给master的响应信号,一共有四种:OKAY,ERROR,RETRY和SPLIT |
下面是仲裁器的信号 | ||
HBUSREQx bus request |
master | 这时master给仲裁器的请求获得总线使用权的请求信号,最多支持16个master |
HLOCKx locked transfers |
master | 如果一个master希望自己在传输期间不希望丢掉总线,则需要向仲裁器发送这个锁定信号 |
HGRANTx bus grant |
arbiter | 授权信号,会传送给每一个master。当HREADY和HGRANTx同时为高时,master获取系统总线的权利 |
HMASTER[3:0] master number |
arbiter | 这个是仲裁器为每一个master分配的ID,用来给多路选择器提供选择信号和为SPLIT操作提供控制信号。 |
HMASTLOCK locked sequence |
arbiter | 表示当前的master正在执行Locked操作。这个信号和HMASTER有这相同的时序 |
HSPLITx[15:0] split completion request |
slave(SPLIT-capable) | 这个信号是具有SPLIT操作的slave提供, 作为仲裁器仲裁的一项控制信号 |
三、AHB的传输过程
1. AHB的传输类型
AHB一共有8种类型的传输模式,由HBURST[2:0]来决定
HBURST[2:0] | 类型 | 说明 |
000 | SINGLE | 单一传输,一次只有一个地址和控制信号,一组数据 |
001 | INCR | 次数不限的递增burst传输。地址根据每拍数据的大小递增,可以传输任意次数。唯一的限制是地址不能超过1K边界 |
010 | WRAP4 | 4拍的回环burst传输。一共传4拍,地址会在地址边界回环。地址边界根据burst传输的次数和每次传输的数据大小来计算 |
011 | INCR4 | 4拍的递增burst传输。一共传4拍,地址根据每一拍的数据大小递增 |
100 | WRAP8 | 8拍的回环burst传输 |
101 | INCR8 | 8拍的递增burst传输 |
110 | WRAP16 | 16拍的回环burst传输 |
111 | INCR16 | 16拍的递增burst传输 |
注释:1. AHB的所有操作,都要求给出的地址是对齐的。
2. 对于同一个burst来说,每次数据的宽度都是一样的。
下面重点来解释几个术语
a). 对齐地址(aligned address)。所谓的对齐地址,其实是对存储空间的一种划分,在读取或者存储数据时,要以这种划分为前提来进行。并且对于不同的情况,对齐地址是不一样的。下面来说明怎么来确定对齐地址。
对齐地址是由每拍传输的数据的宽度来决定的,如下表
传输数据的宽度 | 对齐地址(存储空间的划分) |
1-byte ( 8-bit) | 0x00 0x01 0x02 0x03 .... |
2-byte (16-bit) | 0x00 0x02 0x04 0x06 .... |
4-byte (32-bit) | 0x00 0x04 0x08 0x0c ... |
8-byte (64-bit) | 0x00 0x08 0x10 0x18 ... |
... | ... |
从表中可以看出,对齐地址都是所传输数据宽度(以byte为单位)的整数倍 。在AHB总线上,master所给出的地址,必须是对齐地址。
b). 地址边界(address boundary)。只有对于回环操作才有地址边界这一说法。地址边界跟对齐地址和拍数有关。下面举一个例子来说明边界怎么算。
AHB只支持3种类型的回环,4拍,8拍,和16拍。其实地址边界可以使用2张表来进行计算
第一张表就是对齐地址的那张表
第二张表更简单
拍数 | 地址边界 |
4拍 | 从0x00开始,每第4个对齐地址为一个边界 |
8拍 | 从0x00开始,每第8个对齐地址为一个边界 |
16拍 | 从0x00开始,每第16个对齐地址为一个边界 |
那么怎么来用这两张表呢?
举一个例子,比如是一个WRAP4 的burst,每一拍4-byte数据宽度。那么边界地址是
这个例子是一个4拍的回环操作,所以每第4个对齐地址为一个边界,因为每一拍是4-byte的数据宽度,所以它的对齐地址的序列为
0x00 0x04 0x08 0x0c
0x10 0x14 0x18 0x1c
0x20 0x24 0x28 0x2c
0x30 0x34 0x38 0x3c
0x40 0x44 0x48 0c4c
.........................................
根据我上面说的,每第4个对齐地址为一个边界,所以边界地址为0x0c 0x1c 0x2c 0x3c 0x4c .....
c). 地址回环。 上面知道了什么是地址边界,下面来介绍什么是地址回环。
在回环操作中,每当地址超过了地址边界,地址就会回环到较小的地址上继续进行。这里的较小地址是回环范围中的较小的地址。还以b)中的那个例子为例,
0x00 0x04 0x08 0x0c
0x10 0x14 0x18 0x1c
0x20 0x24 0x28 0x2c
0x30 0x34 0x38 0x3c
0x40 0x44 0x48 0c4c
.........................................
上面的每一行都是一个回环的范围,在一次回环操作中,地址只会在一行里发生变化,不会越行变化,并且每个地址都会用到并且只用到一次。比如,第一拍给出的地址是0x14, 那么接下来3拍的地址依次为 0x18 -> -x1c ->0x10。由于第三拍地址到达了边界,所以第四拍要返回到此次回环范围的最小的一个地址上。
通俗的讲,地址是这么来按照次序给出的
不管第一个地址怎么给出,地址总是按照这个次序依次发往总线。
d). 递增(incrementing)- 顾名思义,就是依次增加的意思。拿INCR4来说明地址如何递增。INCR4 表示一个4拍的burst地址递增操作。一共4拍,表示会有4个地址,且地址依次的加上一个常数,这个常数的大小是每一拍传输的字节数。比如给出的第一个地址是0x40,每一拍传输数据的字节数是2bytes,则后面3个地址依次为0x42、0x44和0x46。
2. AHB最基本的传输
a) 没有等待状态的Signal transfer
Signal transfer是AHB总线最最基本的传输类型,下面以时序图参考来解析它的传输过程
这个图中只给出了一部分的信号,但可以清楚的说明signal transfer的传输过程
1. 在第一个周期的上升沿过后,master将地址和控制信号打入总线。
2. 在第二个周期的上升沿处,slave将总线上的地址和控制信号接收下来,并且将HREADY信号拉高。
3. 在接下来的第二个周期里,分两种情况:
A). 如果是写操作,master会在第二个周期的上升沿过后将要写的数据打入总线。
B). 如果是读操作,slave会在HREADY信号拉高过后将读取的数据打入总线
4. 在第三个周期的上升沿处,分两种情况:
A). 如果是写操作,master获取HREADY高信号,表明slave已经成功接收数据,操作成功。
B). 如果是读操作,master获取HREADY高信号,表面此时的读数据有效并且接收下来,操作成功。
这里要注意一点,HREADY信号在数据有效期间必须为高,并且延续到第三个周期的上升沿之后,确保master的正确采集。
b). slave插入等待状态的single transfer
上面的情况是slave可以及时处理master请求的情况。但也可能存在这种情况:slave太慢不能立即处理。这时需要让master稍微等一等。这时需要slave来插入一些等待的状态。
如上图,HREADY信号在第二第三个周期拉低,意在告诉master说slave不能立即处理,需要master等待2个周期。在这里需要注意2点:
1. 如果是写操作,master需要在等待期间保持写数据不变,直到本次传输完成。
2. 如果是读操作,slave不需要一开始就给出数据(如果一开始可以给出的话,就不需要等待了),仅当HREADY拉高之后才给出有效数据。
c). 多个single transfer的piplline操作
前面2个都是只发单独的一个transfer,那么多个transfer连续发送会怎么样呢:
1. 第一个周期的上升沿之后,master发起一个操作A,并将地址和控制信号打入总线。
2. 在第二个周期的上升沿处,slave收到了来自总线的请求,master获取HREADY信号为高。
3. 在第二个周期的上升沿过后,slave由于空闲将HREADY信号拉高,表示可以处理数据。
4. 在第二个周期的上升沿过后,发现有操作B需要执行,并且检查到上一周期的HREADY为高,则发起第二个操作B。
5. 在第三个周期的上升沿处,master获取HREADY信号为高,表示操作A已经完成。
6. 在第三个周期的上升沿之后,master发现有操作C需要执行,并且检查到上一周期的HREADY为高,则发起第三个操作C。
7. 在第三个周期的上升沿之后,slave由于繁忙而插入了一个等待状态,将HREADY拉低。
8. 在第四个周期的上升沿处,master获取HREADY的信号为低,知道了slave希望他这一拍等待一下,此时,master在第四个周期内需要保持和上一拍一样的信号。
9. 在第三个周期期间,slave处理完了事务,所以在第四个周期的上升沿之后,slave将HREADY信号拉高,表示已经可以继续处理数据。
10. 在第五个周期的上升沿处,master获取HREADY信号为高,知道了slave已经可以处理B操作。
11.在第五个周期的上升沿之后,B操作完成。
12.在第六个周期的上升沿之后,C操作完成。
对于上面的过程需要注意几点:
1. HREADY在一定程度上表示了slave的pipeline能力,在AHB中,是2个pipe。也就是总线上最多存在2个未处理完的transfer。
2. 只有当总线上未完成的transfer少于2个时,master才能发起操作。
下面开始学习AHB的特色传输 - burst transfer
在介绍burst transfer之前,还是把AHB的控制信号补全。
HWRITE - 这个信号是读写控制信号,也即transfer的方向控制信号。 高电平表示写操作,低电平表示读操作。
HSIZE - 这个信号是指明单次transfer的数据宽度。具体如下图所示
HPROT[3:0] - 为transfer提供额外的访问保护和控制权限信号。一般不用,在此不做介绍
HTRANS[1:0] - 进行一次传输时的传输类型,这个信号由master根据自己要进行的传输类型生成的控制信号。一共4种类型
00 – IDLE:
告知slave当前总线处于空闲状态,没有有效的transaction在进行,那么此时就算slave被使能,也不会从总线上获取任何的数据信号。如果此时salve被选中,那么每一个IDLE周期slave都要通过HRESP[1:0]返回一个OKAY响应(见HRESP)
01 – BUSY:
如果slave收到了这个信号,表面当前的master正在进行一个burst传输但是在当前周期不能立刻给出下一次要传输的数据,这时slave不会从总线上收取数据而是等待,并且通过HRESP[1:0]返回一个OKAY响应。需要注意的是,这个transfer需要给出下一拍的地址和控制信号,尽管slave不会去采样。
10 – NONSEQ:
Salve收到这个信号时,表示当前是一个single transfer(就是只传输一次)或者是burst 传输的第一个transfer。此时总线上的地址信号和控制信号与之前的毫不相干。可以理解为一个新的transaction的开始。
11 – SEQ:
这个信号只有在burst传输中出现。当slave收到这个信号时,表明当前的transfer是一个burst transaction中的某一拍。这时,总线上的控制信号应当与之前的保持一致,地址视情况递增或者回环。(这些信号其实是由master决定的,slave不用考虑,只需要单方面接收即可)
那么下面就继续学习burst transfer的流程。
d) 递增burst
1. T1时刻之后,master将第一拍地址和控制信号打入总线,因为是一个新的burst的开始,所以transfer的类型是NONSEQ的。
2. 由于master不能在第二个周期里处理第二拍,所以master使用BUSY transfer来为自己延长一个周期的时间。注意,虽然是延长了一个周期,但是master需要给出第二个transfer的地址和控制信号。
3. slave在T3时刻采集到了master发来的BUSY transfer,知道master需要等待一拍,所以,slave会忽略这个BUSY transfer。
4. 在等待了一个周期之后,master在第三个周期发起了第二个transfer,因为是同一个burst的第二个transfer,所以transfer的类型是SEQ。
5. 在第五个周期里,slave将HREADY信号拉低,告诉master需要等待一个周期。
6. 最后在T8时刻完成最后个transfer。
需要注意的 虽然slave会忽略掉BUSY transfer,但是master也需要给出下一拍的地址可控制信号。
e). wrapping 4-beat burst
上图为一个4拍的回环burst传输。
跟之前唯一的区别在于地址的不同,在0x3C地址之后,根据回环的地址边界,第三拍的地址变为0x30。
一共四拍,一共4个地址,每个地址各不相同,这四个地址是一个回环范围。起始地址决定了回环操作的回环范围。至于如何确定回环地址和范围,在之前的帖子里说的非常清楚,在此不再赘述。
f). 4拍的递增burst
这个是地址递增的4拍burst。
和上面的基本一直,只不过地址在0x30并不回环,而是递增。
g). 其他还有4种burst
wrapping 8
increasing 8
wrapping 16
increasing 16
基本和上面类似,这里就不再一一说了。
本文转自:http://blog.163.com/qixin_william/blog/static/240217035201491425318830/
http://blog.163.com/qixin_william/blog/static/240217035201491133626819/