AMBA总线概述
系统总线简介:
系统芯片中,各个模块之间需要有接口来连接,总线作为子系统之间共享的通信链路
其优点是低成本、方便易用,缺点是会造成性能瓶颈。
AMBA 2.0
AMBA全称Advanced Microcontroller Bus Architecture高级微控制器总线架构
定义了三种总线:
AHB(Advanced High-performance Bus):高性能总线
ASB(Advanced System Bus):高级系统总线(这个用的相当少)
APB(Advanced Peripheral Bus):外围设备总线
一个典型的AMBA系统:
AHB
AHB是一种高性能的高速总线
两级流水线操作(地址周期和数据周期)
可支持多个总线主设备(Master),最多16个
支持burst传输(一次传一批)
总线带宽:8、16、32、64、128
上升沿触发操作
AHB的四大组成部分:
AHB主设备(Master)
AHB从设备(Slave)
AHB仲裁器(Arbiter)
AHB译码器(Decoder)
Master:
发起读写
一时间只允许一个设备使用
CPU、DMA、DSP、LCD Controller等等可以做master
因为一时间只允许一个设备使用总线,那么就需要一个仲裁器来决定谁来使用这个总线。
Arbiter:
master会发一个request信号给arbiter。arbiter允许了就返回一个grant信号。
到底怎么仲裁,可以自己设计。
Decoder:
根据地址解释AHB找到的是哪一个slave
AHB总线互连(这是简单的一部分示意图):
由仲裁器通过MUX来决定数据总线和地址总线由谁发出。
基本AHB信号:
简单说明:
Master发出的信号:
H打头表示AHB。相应的,APB的信号都是用P打头的。
HCLK:Clock
HRESETn:低电平复位信号
HADDR:Address
HTRANS[1:0]:Master用来指示当前传输的数据状态,包括四种:IDLE,BUSY,NONSEQ,SEQ
HWRITE:是否为写数据 1:写 0:读
HSIZE[2:0]:选择Bus的宽度 0:8bit 1:16bit 2:32bit大部分时间是不变的,等于2。这个玩意儿还能再往上设置(有64bit,128bit甚至最高有1024bit……哪会有这么多线噢!),但是不会用到
HBURST[2:0]:burst传输,表示一串信号的传输,当slave设备知道这是一连串的数据的时候就比较好准备,减少没ready的情况。
HPROT:protect,这个不怎么用,就不讲了
HWDATA[31:0]:写入的数据总线
Decoder发出的信号:
HSELx:Decoder在接收到地址以后,判断这个地址属于哪一个slave,然后把这个slave的选中信号HSELx拉高。
Slave发出的信号:
HRDATA[31:0]:读出来的数据总线。
HREADY:Master发送了一个信号,要知道Slave能不能接受,这个信号很重要,Master要知道数据是不是写进去了。
比如发送一个ADDR,检查HREADY是否为高,高了之后再发下一拍的动作:下一个地址以及上一拍的数据。
如果HREADY没有被拉高,那么信号维持一拍再检查READY。
HRESP[1:0]:Response信号。Slave设备指示Master动作的唯一方式。有四种情况:OK、ERROR、SPLIT和RETRY。
正常收到了就返回一个OK,出错了就报一个Error,或者没法响应了,就发Retry或者Split。让Master过段时间再来。Retry和Split的区别,后面会详述。
一个单周期读写的简单例子(无需等待状态):
注意数据和地址分两个总线传输(Pipeline形式),A地址的数据需要在下一拍到达。也就是A的下一个地址和A的数据同时到达。
问:读和写为什么不使用三态总线?
答:三态总线在原则上是可以的,但是一般来说,做数字设计的内部信号不会有inout类型,不会使用三态器件。
流水线示意图:
如果READY信号不一直为高电平,出现了低电平的话:
Master检测到Slave的Ready信号为低电平,视为当前的数据和地址都没有被接受,延长一拍再检查Ready信号,如果还是没有,那继续等下一拍。
需要注意的是这个HREADY信号如果一直为低电平的话,等待的时间太长了,是会影响到总线的效率的,所以说不要大于16个时钟周期。如果Slave设备要做的事情很多,那就在Response信号中,发出Split或者Retry,仲裁信号会根据slave的指示把Master的请求给关了,有时还会降低它的优先级。
BURST传输
如果要节省使用时间,可以使用Burst传输:
Burst Transfer模式由HBURST信号控制。
这个信号是三位的,有八种模式:
0、Single Transfer:(HBURST = 0)只传一次。
1、INCR:没有一个固定的长度,一直传下去。
2、INCR 4-beat:连续传四拍,地址是累加的,这个累加的字长根据Master设备的HSIZE信号指示(一般取2,32bit,也就是四个字节,所以每次的地址需要加4。如果是0或者1的话,就是一个字节、两个字节)。
3、INCR 8-beat
4、INCR 16-beat
Wrapping Burst:
wrapping burst指的是回头传地址。要明白的是碰到哪根边界退回。
比如传8个beat的wrapping burst,每次传32位也就是4byte,那么一次burst需要的地址共为8*4=0x20。当碰到0x20的整数倍的时候,地址会回头跳到上一个0x20的整数倍地址。
如地址序列0x34 0x38 0x3c 0x20(因为这时候如果不回头就碰到0x40了,它是0x20的倍数) 0x24 0x28 …
跟INCR一样也有三种长度
WRAP 4-beat
WRAP 8-beat
WRAP 16-beat
地址计算举例:
大部分时间都是普通的single和INCR这种不定长的连续传输。
上图可以看出来Wrapping 和 Incremental 的区别。
burst波形举例:
INCR8 Burst:
WRAP8 Burst:
在要碰到0x80的时候回头了
详细一点的INCR4 Burst 且有Ready为低的情况:
与之对应的WRAP4 Burst的情况
注意这里的控制信号,HWRITE,HSIZE和HPROT
特别注意——
Burst传输不能跨越1K边界!即0x400。碰到它的时候需要用HTRANS需要变成nonseq状态,因为这里的地址不是连续的。(也没别的要求了,设计Master的时候注意下就行了。)
关于用8bit、16bit的数据存放位置,AMBA协议没有硬性规定。主设备和从设备应该采用相同的印第安序。不支持动态印第安序。
那么什么是印第安序。。。
小印第安序表示先进去的(低地址)是低字节数,
大印第安序表示先进去的是高字节数(这样更符合人的习惯,因为人是从高位往低位读的)。
这个印第安序和印第安人或者印度人没有任何关系…
(emmm因吹丝亭。)
小印第安序:
大印第安序:
插入低电平的HREADY信号表示Slave没有准备好,那如果是Master没有准备好怎么办?
——通过插入一些IDLE和BUSY。
两位信号HTRANS[1:0] 用来指示当前传输的状态,有四种状态:
IDLE BUSY NONSEQ SEQ
IDLE:
表示主设备占用了总线,但是没有进行传输,两次Burst传输中间主设备发IDLE。也就是说,下一个信号IDLE之后的下一个信号一定是新一轮的Burst。
BUSY:
主设备占用了总线,但是在Burst传输过程中还没有准备好进行下一次传输(数据源可能有些问题),则在一次传输的中间主设备发BUSY。即下一个信号还是此次的Burst传输的信号。
NONSEQ:表明一次单个数据的传输,此次地址与之前的不一定连续。在碰到了0x400的时候也要用NONSEQ。
SEQ:表明burst传输接下来的数据的地址和上一次传输的地址是相关的。
这里busy之后还是SEQ,因为是同一个burst。
地址译码:
HSELx:选择从设备,指出由主设备所选择的从设备。
由地址译码器来提供选择信号(Decoder的地址信号由Arbiter通过MUX筛选出来)。
一个slave设备因该至少占用1KB的地址空间。
需要一个额外的缺省slave设备来映射其他的存储地址,否则会综合出锁存器。
站在slave的角度来说,当decoder发出的HSELx信号选中了这个slave的时候,必须响应,不管ready有没有好,能不能接受。
Slave的响应信号有三个,HRDATA,HREADY和HRESP。
当OK且Ready的时候,说明数据可以被收发
从设备响应可能返回的响应:
1、 完成这次传输(OK)
2、 插入等待状态(HREADY)
3、 发出错误信号表示这次传输失败
4、 延迟此次传输,使得总线可用于其它传输(split,retry)
详细一点:
HREADY:transfer done
HRESP[1:0]:transfer response
00:OKAY (单周期响应)成功了
01:ERROR (两周期响应)失败,出了问题
10:RETRY (两周期响应)传输未完成,请求主设备重新开始一个传输
11:SPLIT (两周期响应)传输未完成,请求主设备分离一次传输。
注意:Retry表示的是过段时间再来retry,而不是马上retry。中间可能要等几十上百个周期。
Split也同样,但是它会降低当前master的优先级,意思就是Arbiter觉得你老浪费总线的资源,所以就只在总线空闲的时候再给你用。
双周期,比如说ERROR,这属于异常情况,需要给master一个周期的时间去“思考”下个周期该输出什么。(总线的流水特性需要从设备两个周期的响应,可以使得主设备有足够的时间处理下一次传输。)
例:Retry响应:
A那个地址正在忙,slave返回一个RETRY信号,master接收到retry和低电平的ready,知道从设备暂时无法响应,然后空出一拍的时间,这一拍slave的HRESP必须还是retry,给master一个调整状态的时间。然后接下来的可以再说了。
AHB仲裁:(Arbiter)
HBUSREQx:总线请求信号,每一个主设备都有这么一根总线请求连到仲裁器上。
HLOCKx:锁定传输:
仲裁器必须确保在锁定传输结束之前,不会授权其它主设备。
在一个连续锁定传输之后,仲裁器将总是为一个附加传输保持总线主设备被授权总线,以确保锁定序列的最后一个传输成功完成。并且,没有接收到 SPLIT 或者 RETRY 响应。因此,建议但不规定,主设备在任何锁定连续传输之后插入一个空闲传输,以提供给仲裁器在准备另外一个猝发发传输之前改变总线授权的机会。
因此,建议但不规定,主设备在任何锁定连续传输之后插入一个空闲传输,以提供给仲裁器在准备另外一个猝发发传输之前改变总线授权的机会。
中间三个是arbiter的控制信息的输出或者状态信息的输出。
HGRANTx:仲裁器根据优先级允许请求。
HMASTER:因为最多支持16个master,所以只需要四位的HMASTER就够了,这是一个状态信号用来指出哪一个主设备正在使用总线。注意HGRANTx信号拉高之后并不一定HMASTER就会变为相应的主设备的代号,还跟Ready信号有关系。
HMASTLOCK:同意使用锁定。该信号指示每个从设备当前传输是锁定的,因此必须在更换主设备授权之前被撤销掉。
HSPLITx[15:0]:这里的x表示哪一个slave,这16bit表示哪个Master(独热码)。这个信号由各个Slave提供,指示到底哪个Slave要把哪个Master的优先级做调整。
波形举例:
没有等待状态的1:
仲裁信号举例2:
注意,当GRANT被拉高的时候HMASTER没有立即变动,而是等HREADY做完了,上一次的数据交换完全结束了,HMASTER才可以变动,这时候才把总线交给发送请求的Master设备。
仲裁信号举例3:
(用完了之后怎么办,怎么移交出去)
当M2发出请求信号之后,过了一段时间,从设备发出RESPONSE SPLIT或者RETRY信号,此时仲裁器取消M1的GRANT信号,同时拉高M2的GRANT信号,这时候,由于HREADY信号仍然为低电平,总线暂时还不能交到M2的手上,直到HREADY为高电平了,状态信号HMASTER才会变成2,表示master2在控制总线。
一个需要注意的细节是:在M2取得总线的使用权的那一拍,M1仍然可以使用数据总线,这是因为使用的是流水线结构,M2拿到总线使用权之后这一拍不会用到数据总线。
总线主设备Grant信号示意图:
可以看到,在仲裁器修改了HMASTER之后,相应的地址选择信号才被切换。
几点说明:
1、 对于固定长度的burst传输,不必持续请求总线
2、 对于未定义长度的burst传输,主设备应该持续送出HBUSREQ信号,直到最后一次传输
3、 如果没有主设备请求总线,则给缺省设备设grant信号,且HTRANS = IDLE
4、 建议主设备在锁定总线传输结束后插入IDLE传输,以重新仲裁优先级
SPLIT的产生与解除:
由主设备开始传输
如果从设备需要多个周期才能获取数据,则从设备给出一个SPLIT传输响应。从设备记录主设备号HMASTER。接着仲裁器改变主设备的优先级。
仲裁器grant其它的主设备,总线主设备移交。
当从设备准备结束本次传输,将设置给仲裁器的HSPLITx信号(16位的bus)的相应位。
仲裁器恢复优先级。
仲裁器grant主设备,这样主设备可以重新开始传输。
结束
DEADLOCK:
在使用SPLIT和RETRY时,注意预防总线deadlock
单个传输不会锁定AHB,因为每个从设备都被设计成能在预先确定的周期数内完成传输;
如果多个不同主设备尝试访问同一个从设备,从设备发出分割或者重试响应以表示从设备不能处理,那么就有可能发生死锁。
从设备可以发出分割传输响应,通过确保从设备能够承受系统中每个主设备(最多 16 个) 的单个请求来预防死锁。
从设备并不需要存储每个主设备的地址和控制信息,它只需要简单的记录传输请求已经被处理和分割响应已经发出的事实即可。最后,所有主设备将处在低优先级。
然后,从设备可以有次序的来处理这些请求,指示仲裁器正在服务于哪个请求,因而确保最终服务所有请求。
当从设备有许多未完成的请求时,它可能以任何顺序随机的来选择处理这些请求。
尽管,从设备需要注意,必须在任何其他传输继续之前完成锁定传输。
从设备使用分割响应而不用锁存地址和控制信息显得非常合适。从设备仅需要记录特定主设备做出的传输尝试,并且在稍后的时间段后,从设备通过指示自己已经准备好完成传输,就能获取地址和控制信息。
将授权主设备使用总线并将重新广播传输,以允许从设备锁存地址和控制信息。并且,立刻应答数据或者发出另外一个分割响应(如果还需要额外的一些周期)。
理想情况下从设备不应该有多于它能支持的未完成的传输,但是要求支持这种机制以防止总线死锁。
(这些是SPEC上的,我看不懂…后面再说吧。)
具体接口设计如下
主机的输入:
HGRANTx:Arbiter的允许信号
HREADY:Slave的准备信号
HRESP[1:0]:Slave的状态响应信号
复位、时钟
HRDATA[31:0]:读进来的数据
主机输出:
HBUSREQx:对仲裁器请求
HLOCKx:申请锁定传输
HTRANS[1:0]:输出当前传输状态
HADDR[31:0]:输出地址
HWRITE:是否为写操作
HSIZE[2:0]:指示此次传输的数据是多少位的
HBURST[2:0]:BURST传输的模式
HPROT[3:0]:保护模式
HWDATA[31:0]:写数据总线
注意,这里把主设备的一些信号也包括进来了,比如HTRANS,HBURST。
之前讲过在HBURST为指定的比如4beat incr的时候,即使主设备取消了request,也还是占用着总线的。还有HTRANS的信号是sequence的还是nonsequence的。
从机输入:
HSELx:来自Decoder将地址译码之后的选择信号
HADDR[31:0]:来自经过Arbiter的HMASTER信号选择MUX之后的主机发出的地址
HWRITE:来自主机的读写控制信号
HTRANS[1:0]:来自主机的输出状态
HSIZE[2:0]:来自主机,表示此次传输数据的位数
HBURST和 HWDATA:不讲了
HMASTER[3:0]:用于SPLIT信号的产生,从机需要知道是哪一个主机对它在操作,这个SPLIT是针对哪一个主机的
HMASTLOCK:Arbiter知道这是一个锁定信号,在改变状态的时候,也告诉从机。
HREADY:准备信号
HRESP HRDATA:不讲了
HSPLITx[15:0]:记录是对哪一个主机信号发出SPLIT,同时用于SPLIT的撤销
仲裁器输入:
HBUSREQx(有很多根):来自各个master的请求信号
HLOCKx:来自各个master的锁定传输请求信号
HADDR[31:0]:暂时不清楚这里为什么需要给仲裁器地址信号
HSPLITx[16:0]:接收各个从机的SPLIT指示,以降低和恢复优先级
HTRANS:接收主机的状态
HBURST:接收传输的BURST模式
HRESP:从机的状态
HREADY:需要所有HREADY的与为高电平且HGRANTx为高电平才能使HMASTER改变,即总线完成授权
仲裁器输出:
HGRANTx:GRANT信号
HMASTER:总线占用信息
HMASTLOCK:告诉从机这是一个锁定信号
译码器:
输入为经过Arbiter控制的MUX选择之后的地址总线,输出为各个从机的选中信号。
————————————————
版权声明:本文为CSDN博主「王见王见」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43365647/article/details/103108500