转载自漫谈AMBA总线-AHB

AHB引言

在上篇文章文章我们已经分析了AMBA总线系列中的APB总线的优点和缺点。总结得出:

缺点1: APB支持且仅支持一个主机

缺点2: APB两个周期才能完成一个数据的传输,数据传输效率不高。

所以针对以上的缺点,ARM 开发了更高级的总线AHB,下文将详述AHB基于APB的改进点,改进策略,以及AHB的协议运行机制。

背景

总线碰撞(Bus Collision ):
在AHB总线里面,ARM在设计的时候就支持连接多个主机进行操作。当两个或者两个以上的主机同时发起数据操作的时候,那么总线就会产生混乱,导致数据传输失败。
本质原因:一条总线服务两个主机,难免会产生冲突,比如两个人同时打第三个人的电话,第三个人只能接其中某一个人的电话,主要是资源冲突。

解决方法:
1.给每个主机配套一个总线,同时对应从机也复制,称为资源复制,这种方案设计最简单,但是耗费大量的资源。
2.总线侦听:主机自身在对总线发起请求时,先确认总线上没有主机占用,如果有,等待当前主机释放总线。
3.优先级仲裁策略:对主机等级进行分类,优先级最高的主机先获得总线使用权,等最重要的主机完成处理之后,仲裁设施再服务相对比较不重要的主机,总线仲裁中称为优先级仲裁策略。

结论:ARM在升级APB的时候,为了支持多主机,同时为了解决总线冲突的问题,引入了第三种解决方法(优先级仲裁),给每个主机分配不同的优先级,优先级高的主机先发送数据,优先级低的等待完成之后再进行数据发送。

PS:CAN总线,IIC总线使用的是第二种解决方法(总线侦听)来解决总线碰撞的问题。一般来说,分布式总线比较倾向于使用第二种策略,集中式总线比较倾向于第三种(例如SOC片内总线)。

Q1:可能有同学会问,那两个水果店同时发起请求的几率很小,有没有必要引入优先级仲裁策略:

答:如果为了安全的完成数据的策略,即使这种情况出现的概率很小,但是也要考虑这种最坏的情况。同时同样的问题,在SOC设计中遇到这种情况的概率相对较大。

突发传输(Burst)

在AHB总线中,数据传输时基于Burst类型进行传输的,每次传输都是多个(总线位宽的)数据,通过数据形成多拍(流水的)效果,相比APB总线提升数据的传输效率。

这两个点是AHB针对APB总线提升最大的两个点,当然AHB为了兼容一些其他的问题,有自己独立的一些信号,这个下面继续讨论。

在这里我们总结一下多主机总线的正式概念:

总线是被总线上所有的部件所共享的一组通路(连线),对于支持多主机的总线,如果某一个主机想要与其他的部件进行通信(获得数据),首先需要向总线内部的仲裁器发起使用总线的请求,获得内部仲裁器授予所有权。其次需要将地址(厂商名字)、数据(水果)、命令(进货还是退货)放到总线上,其他的部件对总线上的数据进行侦听,检查地址数据和命令的是否与自己相关,最后相关从机部件做出命令响应。

AHB总线详解

AHB在SOC内使用的部分

如上图:

CPU : CPU是操作的发起者,CPU发起读写外设数据的操作。

DMA: DMA也是操作的发起者,DMA从一个部件搬移数据到另一个部件。

比如Mem 2 Mem 、 Mem 2 Peri 、 Peri 2 Mem 、Peri 2 Peri

AHB_interconnect(AHB_Bridge):

根据上文所说的总线协议和传输信号的要求,构建出来的设计实体,该实体首先接收主机端发送过来的独占AHB总线和通路的请求,其次根据内部的仲裁算法拒绝或者授予该主机访问总线的权利。当主机端被授予访问总线的权利时,该AHB_interconnect(AHB_Bridge)接收主机端的命令、数据、地址总线并传播和生成相应的信号到外设。同时接收外设返回的数据并交付给主机端。

SLAVE:对AHB_interconnect输出数据和指令进行响应。
Q2 : 是否可以不需要AHB_interconnect,AHB_Interconect的作用是什么?

同上篇APB文章类似,当CPU只有一个外设,那么直接可以和外设相连,不需要AHB_Interconect。同时也不需要总线的仲裁逻辑,所以关于总线仲裁逻辑的接口直接根据信号状态tie相应的值或者悬空。

当CPU需要连接多个外设的时候,且不止有一个主机(还有DMA)时,需要AHB_interconnect进行仲裁、路由、相应外设信号的生成。

AHB总线接口(AMBA AHB 2.0)

AHB信号较多,相应功能也比较强大

系统信号:
HCLK AHB总线的时钟,所有的设备的操作都在时钟下进行,上升沿有效。
HRESETn AHB总线复位信号,给AHB 总线电路结构初始值
地址总线:
HADDR AHB传输主机想要操作的地址
数据总线:
HWDATA 主机需要给外设写入的数据通道
HRDATA 外设给主机返回的数据通道
命令总线:(支持突发)
HWRITE 传输AHB主机的读写操作,1写0读
HSIZE 传输数据的位宽(Byte、HalfWord、Word)
HBURST 传输数据的个数
HPROT 提供给外设一定级别的保护
HSELx 仲裁器根据配置输出的选中外设的标志
HTRANS 本次传输的类型
HREADY 此次传输数据是否完成,只关注完成,不关注对错
HRESP 此次传输数据外设给出的响应,表示外设处理的对错等
仲裁总线:(支持多主机)
HBUSREQx 主机请求仲裁器,想要获得总线所有权
HLOCKx 主机请求锁定总线一段时间(在这段时间内这个主机独占,不能被再授予)
HGRANTx 获得总线所有权标志(还要结合其他信号)
HMASTER 哪个主机正在使用总线和支持SPLIT从机寻找对应的主机(后面这个附加其他功能,后文详解)
HMASTERLOCK 表示使用总线的主机正在尝试一次锁定次序的传输(附加其他功能,后文详解)
HSPLITx 从机指示仲裁器,对应的主机应该重新发起一次SPLIT传输。(附加其他功能,后文详解)

从这张大表可以看出,为了克服APB的缺点从而支持多主机模式、提升效率操作,所在总线接口上付出的代价。至少AHB总线位宽和信号个数远远超过了APB总线

总线的概念

主机总线的概念:

总线是被总线上所有的部件所共享的一组通路(连线),对于支持多主机的总线,如果某一个主机想要与其他的部件进行通信:

(1)首先需要向总线内部的仲裁器发起使用总线的请求,获得总线授权。

(2)其次需要将地址、数据、命令放到总线上,其他的部件对总线上的信号进行侦听,检查地址数据和命令。

(3)最后相关从机部件对命令做出响应。

接下来会先引入AMBA协议中的术语:

(1)在AMBA AHB总线中,数据的传输分为三个层次:


如下图:

对应的例子就是:

冬天到了,家里需要拉两吨的煤用来生火,但是家里面只有一辆拖拉机。每次只能运送半吨煤。同时拖拉机的载货箱内部是由一个个单元大小的箱子组成。一个箱子能装50KG煤,因为运输工人卸货的时候一次只能搬一个箱子。所以就需要把这个两吨煤先分解成为拖拉机能装的部分,在此基础上装满拖拉机载货箱内部的单元箱。

类比:

在AHB总线中,每次运输的最小单位就是一次Transfer,表示一个数据的搬移。为了提升搬移的效率,把多个transfer组合成一个Burst进行搬移操作。最后为了完成用户所规定的数据量,需要多个Burst合起来达到用户规定的数据量。

Q1:为什么需要把用户的数据包分割成不同的Burst?为什么Burst的地址范围是1KB?

答:(1)在AHB的协议中,每个Burst的地址范围是不能跨越1KB边界线。举例来说:AHB总线传输的时候就像一列火车,火车的每一节都有一定的载货量,如果一节超出这个载货量火车可能就不会运行,对于AHB总线来说是一致的,用户需要传输的数据量比较大,超过了一次规定的大小(Burst),那么多的数据就需要放到下一个Burst中去。

(2)在AHB的协议中,1KB的范围是分配一个外设的地址空间最小的范围。Burst不跨越1KB地址范围就是不想让一次访问覆盖多个外设的地址。如下图:

当CPU开始发起一次Burst读操作,因为URT0在第一个1K地址范围内,如果在一个Burst内超过了这个1K边界,就访问到SPI0了,可能就不是我们想要访问的目的了。为了完成这个边界跨越,我们在1KB的边界再重新主动发送一个新的Burst。[其实这一块我认为是AHB想要提醒我们,不要Burst跨越这1KB,除非主动操作]。如果你非要违反他,其实也能正常工作,但是模块就不能和其他的标准IP互联,会产生边界问题。这也提醒我们,在配置标准AHB IP的时候,外设的地址范围是1KB的整数倍并对齐到1KB。

AHB的SLAVE回复机制:

在通信中,对于主从双方,因为不是同一个体,所以双方都会在通信中出现一些双方内部状态不一致的问题(非通信问题),需要通过进行交换消息让两者同步。

下面通过例子先阐述一下从机部分的问题和这些问题的解决方案,从而引出AHB的SLAVE回复机制

场景1: 我现在和小明正在对话,我说了一句命令,小明去执行。
我:小明(确定对象),去做1(数据)个俯卧撑(命令)
小明:已经成功做完!(既表示可以处理,同时任务处理完成了)

在场景1下,我(主机)发起一个操作请求,小明(从机)执行这个操作。
可以确定的是我发起的请求和数量,小明根据自己的状态反馈可以接收该命令!(HREADY == 1)同时因为任务简单在表明响应的时候小明也已经完成处理该请求(RESP == OKAY)
类比
在AHB中,主机发起一个元操作(Transfer),从机回复一个 OKAY && HREADY ,表示从机根据当前状态可以接收该命令,同时在这短暂的时间内已经正确处理完毕这个请求。

场景2: 我现在和小明正在对话,我说了一句命令,小明去执行。
我:小明(确定对象),去做1(数据)个俯卧撑(命令)
小明:哎?俯卧撑多少个?你说啥?俯卧撑多少个?
我:1个~~~~~~~~~~~(持续几秒)
小明:收到,俯卧撑1个成功完毕。

在场景2下,我(主机)发起一个操作请求,小明(从机)执行这个操作。

可以确定的是我发起的请求和数量,因为自身的原因,小明根据自己的状态反馈暂时不可以接收该命令!(HREADY == 0)此时也没有执行命令(默认RESP 回复OKAY),而这时候,我需要保持我当前发出命令的状态,等待小明接收命令。
类比
在AHB中,主机发起一个元操作(Transfer),从机回复一个 OKAY &&!HREADY ,表示主机你等会,因为个人的原因,内部有点忙。你先保持一下这个传输的状态(占住总线)。让我缓缓再仔细听听这个数据,再回复。

因为HREADY = = 0 ,此时没有接受命令和数据,这个元操作没有完成(不可分割),所以总线也没有释放,还在占用总线资源。

场景3: 我现在和小明正在对话,我说了一句命令,小明去执行。

我:小明(确定对象),去修1(数据)下大飞机(命令)

小明:???!!! 我不会!

在场景3下,我(主机)发起一个操作请求,小明(从机)执行这个操作。

可以确定的是我发起的请求和数量,小明根据自己的状态反馈可以接收该命令!(HREADY == 1)但是因为我发起的这个要求不合理,小明根本完不成,所以反馈错误命令。

类比

在AHB中,主机发起一个元操作(Transfer),从机回复一个 ERROR && HREADY ,表示从机根据当前状态可以接收该命令,但是因为主机发起的请求,从机根本无法处理(或者超出了从机的能力),所以回复ERROR。

场景4: 我现在和小明正在对话,我说了一句命令,小明去执行。

我:小明(确定对象),去做100(数据)个俯卧撑(命令)

小明:您先忙,我弄完叫你(完成当前的元操作,反馈临时结果)。

我:释放资源给其他人,等小明

小明:我执行完了(反馈最终结果)

在场景4下,我(主机)发起一个操作请求,小明(从机)执行这个操作。

可以确定的是我发起的请求和数量,小明根据自己的状态反馈可以接收该命令!(HREADY == 1)同时因为任务很复杂短时间内执行不完,所以给我回复不了这个任务执行的信息(因为任务很复杂,短时间内是不能有执行信息回复)。所以小明只能先让我不要等了(回复临时的状态信息)完成这个操作请求,释放资源,之后小明做完之后再叫我,回复真正的任务执行状态信息。

[ 我(主机)发起一个操作请求,小明(从机)执行这个操作的时候先让我去做其他(小明已经临时回复,为了释放此次原操作占用的资源),之后再正式回复我任务状况。这个时候小明已经先回复我了他的状态,我就不需要再等待(释放资源),我就可以让出通信资源给其他人然后等待小明回复我。]

类比
在AHB中,主机发起一个元操作(Transfer),从机回复一个 SPLIT && HREADY ,表示从机根据当前状态可以接收该命令,但是从机分析之后发现这个命令自己需要超长的执行时间,所以临时先回复一下主机,说这个任务复杂需要你等我一会(完成这个元操作的过程),主机收到之后就知道任务复杂,所以自己也就不占用总线的资源,释放总线资源给其他的主机使用。这样就**提升了总线的利用率,**等从机处理完成之后,主机再检查处理回复的结果。

(从机完成当前主机分配的任务之后,提醒该主机)

PS:这个操作是很重要的,直接整体提升了AHB总线的使用效率。关注这一点同时是为了将来引出AXI总线的相关机制。

场景5: 我现在和小明正在对话,我说了一句命令,小明去执行。
我:小明(确定对象),去做1(数据)个俯卧撑(命令)
小明:哎,我听到你说做1个俯卧撑(先响应这个)。但是我现在有点忙,等会你再说一遍(给当前这个请求一个暂时的回复)
等几秒~~~~
我:小明(确定对象),去做1(数据)个俯卧撑(命令)(重发)
小明:收到,俯卧撑1个成功完毕。

在场景5下,我(主机)发起一个操作请求,小明(从机)执行这个操作。

可以确定的是我发起的请求和数量,小明根据自己的状态反馈可以接收该命令!(HREADY == 1)但是因为自己内部还有点问题暂时来不及处理这个命令。所以小明临时回复(RESP == RETRY),释放此次原操作占用的资源。告诉我等会重新试试这条命令,小明可能就从当前来不及的状态就变成可以处理的状态了。过一会后,我估摸着小明缓过来了,这时候我再重新说一次这个命令,小明缓过劲来就可以直接执行。

类比
在AHB中,主机发起一个元操作(Transfer),从机回复一个 RETRY && HREADY ,表示从机根据当前状态可以接收该命令,但是从机内部还有其他的活没有解决(可以接受,但是没有办法立即执行),所以临时先回复一下主机,说我身上还有点活正在忙,你等会再找我,(完成这个元操作的过程),主机收到之后就知道从机当前还在执行其他任务,所以自己也就不占用总线的资源,释放总线资源给其他的主机使用。过一会差不多了,主机再次重新发起请求,这时候从机缓过来了之后就可以执行主机当前的命令了。

(从机不会再提醒主机,主机一会自己主动尝试联系从机)
总结:在AHB 总线传输的时候,一次Transfer(元操作)是不能分割和打断的,所以占用着总线的资源。所有的改进措施,都是先完成Transfer(元操作)的基础上再进行提升。完成元操作不代表这个操作必须完全执行完成才可以,而是可以先把这个Transfer(元操作)的流程走完结束掉它,之后用其他的途径再进行操作(比如在从机的回复下,主机回滚到之前的地址操作处再进行相同操作)。


所以我们在设计AHB从机的时候是可以根据这两个信号,让主机等待从机。(根据设计,灵活选择让主机等待从机的方式)

主机Master端控制传输的方式

对于主机来说,因为当前传输主动发起表达的是自己的意志和请求,而从机不过是被动的响应(通过在响应中反向表达自己内部状态的机会)。所以可以看到在AHB总线的信号列表中,绝大多数信号接口是为主机表达自己的意思而准备。所以主机的权限是比较大的,同时因为主机的权限比较大,发出的命令要有响应(等不到响应の主机,就卡住总线来占用总线资源)。

注意:所以在AMBA AHB中就规定了,主机只有真的需要发起请求和命令时候才可以发起,一旦发起,就必须至少完成最小单位传输(元传输),不能自己中途撤销

场景1:我现在和小明正在对话,我说了一句命令,小明去执行。
我: 小明(确定对象),去做1(数据)个俯卧撑(命令)
小明: 已经成功做完!(既表示可以处理,同时任务处理完成了
我: 小明(确定对象),我有点忙(我妈叫我吃饭,因为我内部有事情处理从而顾不上给小明发下一个动作命令,所以发出临时状态命令)。
小明:好的(必须回复OKAY,因为小明当前没有任何任务)。
我: 小明(确定对象),去做1(数据)个俯卧撑(命令)[这时候我吃饭已经完成了]
小明:已经成功做完!(既表示可以处理,同时任务处理完成了

类比:
AHB主机发出一个Burst命令(该Burst内由许多相同的transfer(元操作)组成,比如读0、1、2、3地址数据),从机收到第一个transfer(读0地址),回复一个数据。主机收到数据之后,按照协议是应该立刻马上发出下一个transfer(读1地址命令)的。但是当前主机由于收到前一个transfer(读0地址)的数据,此时主机内部有些东西需要处理,暂时发不出第二个transfer(读1地址命令)。但是又为了符合AHB总线上时序的协议,主机只能发忙传输(HTRANS == BUSY),从机应答(RESP = = OKAY && HREADY == 1 因为从机并没有接到有效工作的命令),满足AHB协议的规定。

场景2:我现在和小明正在对话,我说了一句命令,小明去执行。
我: 小明,没啥事
小明: 好的(必须回复OKAY,因为小明当前没有任何任务)。
我: 小明,没啥事
小明: 好的(必须回复OKAY,因为小明当前没有任何任务)。

类比:
AHB主机并没有什么数据和从机进行通信,但是AHB协议上并不允许什么数据状态都没有(就算没有数据和命令都必须打空拍)。所以主机和从机为了满足AHB规定的协议状态,只能像正常工作一样,主机发起空传输(HTRANS == IDLE),从机应答(RESP = = OKAY && HREADY == 1),满足协议的规定。
PS:从上面这点可以看出,即使总线上没有东西传输,也要维持传输的动作状态(空拍)。主机发空操作,从机回复OKAY。

场景3:我现在和小明正在对话,我说了一句命令,小明去执行。
我: 小明(确定对象),开始去做1(数据)个俯卧撑(命令)
小明: 已经成功做完!(既表示可以处理,同时任务处理完成了
我: 小明(确定对象),继续去做1(数据)个俯卧撑(命令)
小明: 已经成功做完!(既表示可以处理,同时任务处理完成了
我: 小明(确定对象),开始去跳1(数据)下绳(命令)
小明: 已经成功做完!(既表示可以处理,同时任务处理完成了
我: 小明(确定对象),继续去跳1(数据)下绳(命令)
小明: 已经成功做完!(既表示可以处理,同时任务处理完成了
我: 小明(确定对象),继续去跳1(数据)下绳(命令)
小明: 已经成功做完!(既表示可以处理,同时任务处理完成了
我: 小明(确定对象),继续去跳1(数据)下绳(命令)
小明: 已经成功做完!(既表示可以处理,同时任务处理完成了

类比:
AHB主机把类型相同地址不同的命令(transfer)组合成一个相同类型的Burst。(比如两次Transfer俯卧撑就是一次Burst 2俯卧撑,四次Transfer跳绳就是一次Burst 4跳绳,同一个Burst俯卧撑内部,有第一个开始的Transfer命令,一般标注为开始(NONSEQ),其他的Burst内部的Transfer命令(不是Burst内的第一个Transfer),一般标注为继续(SEQ)。从机根据自己的状态每次接受一个Transer,然后回复该Transfer命令的响应和数据。

总结

对于AHB主机,有四种方法来表达自己传输数据的状态:

主机HTRANS == IDLE
从机:RESP == OKAY
主机没有什么东西可发,只是无奈要维持总线协议形式而已。在这里面,从机面临这种情况必须回复OKAY
响应,因为从机并没有任务进行。(协议硬性规定)
主机:HTRANS == BUSY
从机:RESP == OKAY
主机当前内部有点忙,不能按照协议及时提供下一个Transfer命令。所以主机发出内部HTRANS == BUSY信号表示当前很忙,等会再发出下一拍的命令。从机了解到主机的状态,什么都不用做,直接回复RESP == OKAY 完成主机发出的表示状态的Transfer(不是传输命令数据的Transfer)在这里面,从机面临这种情况必须回复OKAY响应,因为从机并没有任务进行。(协议硬性规定
主机:HTRANS == NONSEQ从机:RESP == XXXX 主机当前发出一笔新的Burst,指定地址和Burst类型,同时指定Burst的开始。(比如场景3的开始俯卧撑、跳绳命令)从机可以按照自己的状态(参考漫谈AMBA总线-AHB(2)),反馈给主机。完成主机发出的Burst中的一次Transfer传输。
主机:HTRANS == SEQ从机:RESP == XXXX 主机接着Burst的开始Transfer之后的Burst中的其他Transfer。(比如场景3的开始跳绳命令之后的三个继续跳绳命令)从机可以按照自己的状态(参考漫谈AMBA总线-AHB(2)),反馈给主机。完成主机发出的Burst中的一次Transfer传输。

PS:从机一般是不在意主机发出的Burst是新的还是旧的(但是关注是否是HTRANS == (BUSY | IDLE),因为必须要回复OKAY ),但是我们上一次文章有提到,在主机发出Burst地址要跨越1KB边界的时候,比如主机发出一个长度为4,读1022地址的Burst操作,按照原本的剧本主机应该是 读Burst 4

ADDR : 1022 1023 1024 1025
HTRANS : NONSEQ SEQ SEQ SEQ

但是由于1KB边界的存在,主机就需要变成读Burst 3

ADDR : 1022 1023 1024
HTRANS : NONSEQ SEQ SEQ

然后主机再发出一个新的读Burst 1。

ADDR : 1025
HTRANS : NONSEQ

从上面、我们已经了解了主机和从机是如何参与并通过传递状态控制当前传输的情况和所谓的跨1KB边界的操作。

仲裁算法

多主机总线的概念: 总线是被总线上所有的部件所共享的一组通路(连线),对于支持多主机的总线,如果某一个主机想要与其他的部件进行通信(获得数据)首先需要向总线内部的仲裁器发起使用总线的请求,获得内部仲裁器授予所有权。其次需要将地址、数据、命令放到总线上,其他的从机部件对总线上的数据进行侦听,检查地址数据和命令的是否与自己相关,最后相关从机部件做出命令响应。

场景1:仲裁算法(FIFS 先来先服务)
我和小明在大街上游玩,突然我有点饿,于是就去煎饼果子店买煎饼,小明过了一会也觉得饿了,也去煎饼果子店买煎饼,因为煎饼果子店只有一家,我又是先买的,所以煎饼果子店需要先给我把煎饼果子交付,之后才服务小明的需求。

类比: 两个AHB的主机现在连接在AHB_Interconnect上(漫谈AMBA总线-AHB)。突然主机1有发送信息的需求,所以它先向AHB_Interconnect部件申请使用总线,当前在AHB_Interconnect上的其他主机并没有发送信息的需求,所以AHB_Interconnect就把这个总线的所有权交给了主机1。过了一会主机2也想发送数据了,但是主机1正在使用总线,所以主机2就只能等待主机1把数据发送完成,再发送数据。

总结:两个主机在发送消息的时候是有时间差和先后的顺序,一般来说这时候如果采用了**(FIFS 先来先服务)的算法,那么就按照发送消息的时间先后来服务不同的主机。**

场景2:仲裁算法(优先级服务)
我和小明在大街上游玩,突然我们有点饿,于是就去煎饼果子店买煎饼,因为煎饼果子店只有一家,然后我和小明同时想要付款买煎饼果子,但是煎饼果子老板认识小明(在老板心里小明比我的比重大,优先级高),于是就先收了小明的钱,先服务小明,之后才服务我。

类比: 两个AHB的主机现在连接在AHB_Interconnect上(漫谈AMBA总线-AHB)。突然主机1和主机2都有发送信息的需求,所以它们同时AHB_Interconnect部件申请使用总线,在当前的AHB_Interconnect上,主机2的权重设计要比主机1的大(假设主机1是跑马灯控制器、主机2是心脏跳动器),所以AHB_Interconnect就先把总线的所有权给主机2使用,之后再授权给主机1.

总结:两个主机在发送消息的时候是同时到来的,一般来说这时候如果采用了优先级的算法,那么就先服务优先级高的主机,之后再授权优先级较低的主机

当然,在生活中所有的事情并不一定是十分的完美按照计划运行,所以在两种仲裁算法的情况下,又衍生出来其他的场景

场景3仲裁算法(FIFS 先来先服务)++ 仲裁算法(优先级服务)
我和小明在大街上游玩,突然我有点饿,于是就去煎饼果子店买煎饼,小明没过了一会也觉得饿了,也去煎饼果子店买煎饼,因为煎饼果子店只有一家,我虽然是先买的(我还在排队等结账),但是煎饼果子店的老板是小明的爸爸,于是煎饼果子店就把正在做的煎饼果子先给了小明,之后再给我做。虽然我心里很不情愿也只能接受这个结果,因为煎饼果子店老板真的不是我的爸爸

类比:
两个AHB的主机现在连接在AHB_Interconnect上(漫谈AMBA总线-AHB)。首先主机1有发送信息的需求,所以它先向AHB_Interconnect部件申请使用总线,当前在AHB_Interconnect上的其他主机并没有发送信息的需求,所以AHB_Interconnect就把这个总线的所有权交给了主机1。过了一会(在主机1正在发送数据的时候)主机2也想发送数据了,在这个机制里面主机2权限确实非常高,所以主机2发送了使用总线的请求,这时候AHB_Interconnect就先停止服务主机1(即使主机1数据并没有发完),接下来赶紧服务主机2。等主机2服务完毕,才继续服务主机1

PS:为什么会发生这样的问题!或者说主机1能够被打断的本质是什么?

举例来说,小明为什么能插队我的煎饼果子,我认为是在我买煎饼果子里面步骤太多和时间太长(且在每个步骤里面没有禁止插队的方案),在我排队的时候,在我结账的时候等,这样都给了小明可趁之机。如果一直跟着AHB系列读上来的同学应该会了解前文说过的一个操作:元操作(Transfer),在我们之前的文章中,说过元操作不可分割,不可打断。所以在AHB总线中,数据的传输都是由基本的元操作完成的。但是元操作之间是没有任何的保证(不可分割和不可打断)比如前文中的Burst内部,是可以打断的,所以在这种情况下就有可能导致主机2申请打断主机1传输的情况发生

PS:如果对AXI或者ACE协议了解的同学,应该会在相应的手册里面看到一个词叫Atom的词,这个词就代表了一种元操作这种操作就在硬件层面保证了一笔操作是不能被打断和分割。当然这个Atom操作和此处的应用环境有所区别,但是都是表达了一种同样的意义。之后漫谈AXI/ACE系列里面也会一点点的去推进和深入。

场景4:仲裁算法(FIFS 先来先服务)-- 仲裁算法(优先级服务)
场景3中,即使我先发起购买的动作,但是最终煎饼果子店还是先服务了小明,之后再服务我。同时在上面我们也分析了原因,因为我购买煎饼果子到煎饼果子交付中间的环节相对较多,每个环节可能都会被小明趁机而入。同时每个环节没有明显的禁止插队的规则,所以基于此,看看AHB总线如何解决这个优先级插队的问题。
我和小明在大街上游玩,突然我有点饿,于是就去煎饼果子店买煎饼,小明没过了一会也觉得饿了,也去煎饼果子店买煎饼,因为煎饼果子店只有一家,虽然煎饼果子的店老板是小明的爸比。但是店内的发票机器是根据先后顺序打票并进行交付煎饼果子,这样虽然小明的爸爸是店长,但是按照机器的打票规则必须先给我打完发票交付之后才能再给小明交付。在这期间,机器打票规则这个就成了我捍卫我自己的权利的一种规则或者手段。
类比:
在AHB总线协议中,在第一章(漫谈AMBA总线-AHB)中我们分析了AHB的接口,在表格中我们列出了一个信号:HLOCKx,在AHB中,这个HLOCKx信号就是主机捍卫自己权利的一种规则或者手段,如上例子,当主机1在进行数据请求传输的时候,不希望别的主机打扰他,于是他在请求总线的所有权的时候,拉高HLOCKx信号既在请求中表达了自己想要获取总线,又表示我希望我这次获取的总线是不能被别人打扰的。相当于请求的进一步递增。这时候,AHB_Interconnect 把总线授予给主机1,同时也在内部做好不会在主机1使用总线的时候,让其他的主机使用总线(即使优先级高也不行)。等到主机1请求完了之后,高优先级的主机2才能进行总线所有权的获取和数据的传输。

PS:我们可以极端的想象,如果每一个主机在请求总线的使用权的时候,都拉高了自己所带的HLOCKx信号,在这种情况下,我们可以预测到,最后这个仲裁结构的算法就基本退化优先级仲裁算法。当一次HLOCKx传输之后,等待传输的下一批主机中选出优先级最高的进行总线占有,如此往复,可能导致优先级低的主机永远得不到总线的所有权(假设总线中的主机发消息都很密集)。

额外再说一句:这个情况在操作系统OS中也会出现,当只有仲裁算法为优先级算法的情况下,优先级高的进程始终优先运行,最后可能会剥夺低优先级运行的权利。当然,在操作系统中,有很多处理的方式,比如动态优先级、多级反馈等。暂且按下不表,等以后如果有机会可以和大家一起再深入学习一下。

PS:最后通过上面的例子我们可以推测出在AMBA AHB的协议中一般来说在设计主机的时候,主机发出的数据传输一般都不会锁定总线HLOCKx = 1 )。因为锁住总线的话会可能导致高优先级的主机剥夺低优先级的主机的数据发送时间,这个肯定不是指定规则的人的想法。只有在必要的情况下,才发出锁定这笔总线的操作。(所以在设计中,注意一般不要发出锁定总线的操作)

Q1 : 那么这个(HLOCKx = 1)会在什么情境下使用呢?或者换个说法的话,什么情况下一个主机发送数据才不想要其他的主机打扰呢
答:不想被打扰状态代表主机的一次操作具有原子性原子操作一般会用在操作系统中
信号量:一般情况下,解决进程/线程之间的同步和互斥问题的一种通信机制。假如CPU 0 运行一个程序1,CPU 1运行一个程序2。但是程序1和程序2都需要配置UART0发送 当前运行的程序标号。即“CPU Num x“。假设当CPU 0 发起一笔普通的运行UART 0的命令,此时UART 0 刚 发送”CP“,此时CPU 1 进行夺权操作,发起普通运行UART 0的命令,这时候UART 0就继续发送了CPU 1的 “CPU Num 1”。这时候对于外界的UART接收器接收到的总信息就是 “ CPCPU Num 1 ”。前面绿色是由CPU 0 发出的一半,后面的红色是CPU 1夺取总线后发送的他自己的信息

解决这个问题就是:CPU 0发起操作的时候锁定总线,CPU 1获取不了总线,所以只能等待CPU 0把“ CPU Num 0”信息发完,之后再发送CPU 1的信息 “CPU NUM 1 ”。这样对外界的UART接收器来说,数据接收的就是正常的。
所以,没有硬件方面的原子性支持,现在的多进程操作系统可能会构建的无比复杂或者根本无法构建
在操作系统中还有其他的信号量机制(互斥锁,自旋锁),也是由硬件的原子操作支持的,在这里也就是HLOCKx体现。也有其他的应用就不一一说明了。

AHB时序图分析AHB章节最后再复习一遍多主机的概念:

总线是被总线上所有的部件所共享的一组通路(连线),对于支持多主机的总线,如果某一个主机想要与其他的部件进行通信(获得数据),首先需要向总线内部的仲裁器发起使用总线的请求获得内部仲裁器授予所有权。其次需要将地址、数据、命令放到总线上,其他的从机部件对总线上的数据进行侦听,检查地址数据和命令是否与自己相关,最后相关从机部件做出命令响应

如下图所示(场景模拟):自己对应相关的信号复习一下

如上图所示,CPU和DMA同时向AHB_Interconnect申请获得总线所有权(1)。AHB_Interconnect(内部权衡)之后决定把总线授予给CPU,所以AHB_Interconnect应答了CPU申请总线的信号(2)。此时CPU已经知道自己获得了总线的授权,所以把自己需要访问的地址和命令放到总线上(3),通过CPU发出的地址范围,AHB_Interconnect把命令和地址路由(转发)到对应的UART从机(4),UART从机接收到主机发过来的命令,知道要进行读取自己内部寄存器的操作,所以自己把自己内部的数据放在数据总线上(5),再由AHB_Interconnect路由到对应的主机的数据总线接口,交付给主机(6)。

该模拟的操作完全把CPU的这次访问总线操作串行顺序起来,没有考虑效率。

总结上述AHB_Interconnect操作(重要):
(1)完成总线的授权与拒绝授权
(2)根据CPU发出的访问地址,把地址和命令路由(转发)到对应的从机接口(例如CPU -> UART)。
(3)主机发出的数据路由到刚才地址和命令所对应的从机接口;从机响应的数据路由到之前主机地址和命令对应的主机接口。(相当于地址和控制信息已经提前打好通路的开关,数据只要按着该通路进行流动就行)

PS:为什么所说上述的操作比较重要,因为对于AMBA AXI协议来说,其基本的路由规则也是如上图所示。也许会有同学说AXI的接口和AHB接口不一致,但是基本的思想都是一致,AXI为了更大效率的利用这个流程,设计了很多独有的提升性能的部分,此处按下不表,之后到漫谈AMBA AXI协议会详细说明。

PS:我们是否在上图模拟时发现,对于一个主机来说,操作是有先后顺序的。必须按照流程一步步走完才进行下一步,这样的话就要花费很长时间才能完成一次存取数据的操作。这样就意味着一次访问总线的Latency很长。
那么对于我们来说,想要减小这个总线的Latency:
(1)是否有一种方法是减弱其中的相关性?减少访问总线指令之间和访问总线指令内部的相关性?
(2)或者有一种方法是把这些前后顺序的操作做成流水线的形式?通过增大吞吐量的方式?
这两个问题之后在之后漫谈AXI协议里面还会重新提起。

PS:之前我们也说过,对比APB和AHB总线,AHB协议的效率更高。为什么效率更高?我们可以看到上图AHB_Interconnect在发出地址和命令时(4),主机这时候继续发出下一拍的地址和数据,这两次的地址和数据在时间上就重叠了起来,形成一种流水线机制,增大了总线的传输效率。
至少看来,AHB协议通过流水线操作增加了AHB总线的带宽(此处应该对比漫谈AMBA总线-APB)。

时序图分析

1、单主机仲裁

单主机单周期仲裁时序图

如上图所示:
(1)CPU先在(T1后)拉高HBUSREQx信号向AHB_Fabric申请使用总线(1)
(2)AHB_Fabric同意主机使用,所以在(T3后)拉高HGRANTx表示允许主机使用总线(2)。
(3)CPU收到AHB_Fabric返回的授权命令,于是就在T4周期后把自己想要控制的地址通过金属线发送到AHB_Fabric(3),在此周期内 AHB_Fabric把对应的地址和控制信号路由到Slave对应的接口上去。
(4)T5周期后,CPU既发出(A+4)的地址,又发出A地址所对应的数据[A](4)。在这个周期,也就是AHB比之APB体现性能的地方所在,分离地址和数据进行流水操作。

PS : HMASTER 信号: AHB_Fabric表示当前的哪个主机使用总线

Q1: 可能有同学想问,为什么你没有画AHB_Fabric和从机的接口时序?

答:这里主要的目的就是为了表达一个观点:对于AHB_Fabric来说,它当前扮演的角色就是一个CPU的从机(因为CPU接口直接和AHB_Fabric连接),所以在传输数据的时候,CPU把数据交给AHB_Fabric之后就认为已经交付完成了(如果AHB_Fabric不返回错误或者不转发从机返回的错误)。

单主机多周期仲裁时序图:

T1时刻:CPU拉高了HBUSREQx ,向AHB_Interconnect请求占有总线。

T3时刻:AHB_Internect回复CPU授权CPU使用总线

T4时刻:CPU收到AHB_Interconnect的授权信号(认为自己得到授权,准备占有地址和控制总线),准备发出地址和控制信号的时候,发现HREADY信号为低。参考之前文章(漫谈AMBA总线-AHB(2))的说法,HREADY信号为低,虽然CPU被授权总线了。但是,上一个主机传输卡住了(Transfer),所以当前主机只能等待上一个主机的传输完成。必须要注意:此时上一个主机还没有放弃地址和控制总线的所有权,同时此刻又把下一个地址和命令在总线上表示了(地址和数据的重叠)!(所以虽然CPU虽然得到授权信号,但是它还没有真正掌握到任何一部分总线)。

T5时刻:上一个主机的一个传输完成了,所以CPU可以发出自己的命令和地址了( CPU此时掌握地址和命令总线,但是数据总线还遗留着上一个主机在T4时刻发出的命令所对应的数据)。

T6时刻:CPU发出命令之后(地址A),发现HREADY信号为低HREADY信号为低表示元传输没有完成(上一个主机的数据),所以此时CPU只能保持当前的状态一动不动(保持地址和控制信号)。

T7时刻:CPU收到HREADY信号为高,可以切换自己的状态(上一个主机完成了数据,释放了数据总线),发出下一个地址和控制信号(A+4)。同时发出上一次地址的数据(Data(A)),形成流水。

T8时刻:CPU发出命令之后(地址A+4),发现HREADY信号为低HREADY信号为低表示元传输没有完成(本主机的数据),所以此时CPU只能保持当前的状态一动不动(保持地址和控制信号)。

T9时刻:CPU收到HREADY信号为高可以切换自己的状态,发出下一个地址和控制信号(A+8)。同时发出上一次地址的数据(Data(A+4)),形成流水。

ps:我们会发现上一个主机的传输(元操作)会影响到总线切换后的主机,这个算不算AHB的一个缺点呢?

多主机仲裁

多主机轮转时序图

T3时刻后:因为一些原因(其他主机争权)AHB_Internect取消M1主机的授权,所以拉低了授权信号(HGRANT_M1 = 0),同时授权了M2主机使用总线,拉高了授权信号(HGRANT_M2 = 1)。

T4时刻: 主机M1已经知道自己被取消了授权,所以主机M1之后不会在T4时刻之后发起新的传输了,但是需要把当前的传输传输完毕(因为M1当前的传输命令发出的时候正好接到被取消授权,T3时刻),同时M1主机发现HREADY为低(知道自己当前的数据被卡Data(A+8)),所以保持当前地址控制状态(A+12)。

主机M2知道自己被授权了,但是发现HREADY为低,知道上一个主机的数据还在卡着,所以自己不用发出地址命令(等待主机M1释放地址和控制总线)。

T5时刻: 主机M2知道主机M1的数据已经正确接收(同时释放了地址和控制总线(B + NONSEQ),此时主机M2发出自己的命令和控制信号。

T6时刻: 主机M2已经发出自己地址和命令,此时发现发现HREADY为低,知道上一个主机的数据传输还在卡着(Data(A+12)),于是自己保持当前发出地址和命令当前的状态(B + NONSEQ)。等待上一个主机的最后一个数据交付。

T7时刻: 主机M2发现发现HREADY为高,知道上一个主机的数据已经处理完毕(释放了数据总线)。接下来可以发出主机M2的数据和主机M2的下一拍的地址和命令信息。

多主机仲裁时序图
多主机轮转

多主机轮转时序图:

T3时刻之前:M1主机获得总线,使用总线传输数据

T3时刻:M2主机想要使用总线,所以向AHB_Interconnect发起总线的使用权请求。此时主机M1正在使用总线传输数据。

T5时刻:仲裁器觉得给M1主机使用总线的时间已经足够长,于是要取缔其使用总线的权利。同时准备授予M2主机使用总线。

T6时刻:主机M1接收到AHB_Interconnect取消其使用总线的请求,所以其T6时刻之后不会再发新命令(当然T6时刻之前已经发出命令不能取消了,因为已经被发出到总线)。主机M2已经收到AHB_Interconnect授权总线的请求了,但是当前其虽有授权,但是还是没有真正掌握总线。(上一个主机的数据传输阻塞数据总线 HREADY = =0)

T7时刻:上一个主机的数据成功传输(Data(A+8))释放了主机M1占有的地址和控制总线,所以此时主机M2就开始占有地址和控制总线了。所以主机M2把其想操作的地址和命令发送到地址和控制总线上。

T8时刻:上一个主机的遗留数据传输卡着总线 (HREADY = =0),此时主机M2还不能进一步掌握数据总线。所以只能保持当前的状态等待上一个主机接收数据释放数据总线。

T9时刻:上一个主机数据传输完成,释放了数据总线(Data(A+12)),进而主机M2进一步掌握了数据总线,把自己需要的数据放到数据总线上来进行一次完整的传输。

PS:从上面,我们可以明显看出,总线的移交是两个阶段完成的:

首先第一步移交地址和控制总线,

其次第二步移交数据总线。

总线移交的每一步都需要考虑到上一个主机的感受(即数据的传输!)。

AMBA之AHB总线相关推荐

  1. AMBA总线—AHB总线协议详解

    文章目录 一.AMBA总线介绍 1.1.AMBA发展史 1.2.典型的AMBA系统 二.AHB总线(宏观构造) 2.1.AHB总线组成 2.2.AHB总线组成互连 2.3.AHB操作概述 2.4.AH ...

  2. [接口-AMBA-AHB] AHB总线协议

    一.典型AMBA系统 AHB总线的强大之处在于它可以将微控制器CPU.高带宽的片上RAM.高带宽的外部存储器接口.DMA总线master.各种拥有AHB接口的控制器等连接起来构成一个独立的完成SOC系 ...

  3. AMBA、AHB、APB、AXI总线介绍和对比

    一.引出 研究STM32H7的总线系统,对AXI.AHB.APB.ASB有点兴趣,于是去简单了解了一下,总结如下: 说到AXI.AHB.APB.ASB就得先说AMBA(Advanced Microco ...

  4. AMBA、AHB、APB、AXI总线

    AMBA.AHB.APB总线 * AMBA (Advanced Microcontroller Bus Architecture) 高级微处理器总线架构 * AHB (Advanced High-pe ...

  5. 深度解读AMBA、AHB、APB、AXI总线

    什么是AMBA? 现如今,集成电路芯片的规模越来越大.数字IC从基于时序驱动的设计方法,发展到基于IP复用的设计方法,并在SoC设计中得到了广泛应用.在基于IP复用的SoC设计中,片上总线设计是最关键 ...

  6. AMBA总线协议(三)——一文看懂AHB总线所有协议总结(AHB2 AHB-Lite AHB5 )

    AMBA AHB 总线协议介绍请点击以下链接: AMBA总线协议(一)--一文看懂APB总线协议 AMBA总线协议(二)一文看懂AMBA2 AHB2与AMBA3 AHB-Lite总线协议的区别 AMB ...

  7. SOC设计之AMBA总线-AHB总线详解

    (本文图源AMBA总线2.0) AHB(高级高性能总线):用于高性能高时钟频率的系统模块,AHB 担当高性能系统的中枢总线.AHB 支持处理器,片上存储器,片外存储器以及低功耗外设宏功能单元之间的有效 ...

  8. 数字IC验证:ARM总线协议AMBA中AHB、APB的简介、区别与联系

    写在前面: 最近实习项目里用到这2个协议,因此简单整理一下,内容大多来自ARM官方文档与网络上的,我主要做一个整合,加上自己的理解补充,内容来源都会分别标出.如有侵权请指出,立刻删帖. 官方文档入口: ...

  9. STM32的总线AMBA、AHB、APB

    一.总线的简单介绍: 处理器无疑是计算机中最重要的部件,但并不是唯一的部件.一台计算机也需要随机访问存储器(RAM)来存放机器码指令以便让处理器执行.计算机还必须有一些方法使这些指令进入RAM(输入设 ...

最新文章

  1. 【PAT】A1060 Are They Equal *
  2. 反馈速度小于 200ms!“弹窗”功能让你极速触达用户内心
  3. Spring Clould负载均衡重要组件:Ribbon中重要类的用法
  4. MVP Community Camp 社区大课堂
  5. CentOS7 iso封装语句
  6. delphi7aes加密解密与java互转_跨语言(java vs python vs nodejs)的RSA加解密问题探讨
  7. php中获得客户端,服务器ip
  8. anki 新的卡片类型_用 Anki 建立高效复习错题体系
  9. 【网络安全入门大总结】—Java语言中常用的渗透漏洞大汇总
  10. DP动态规划之01背包问题
  11. KVM通过qemu实现USB重定向
  12. windows下双击可运行的Java软件打包方案
  13. wex5使用java语言_WeX5学习笔记之调用后端服务
  14. 实验吧 ctf题目 天下武功唯快不破
  15. 长隆大马戏机器人_长隆娱乐登陆
  16. linux 排查cpu负载过高原因
  17. 高德地图地位获取地址
  18. win10的内核隔离要不要开?
  19. style-loader和css-loader
  20. 高德的位置服务器,高德位置服务浅析

热门文章

  1. 电容麦克风测试软件,Precision sound
  2. DBA 职业迷茫何去何从
  3. 什么是面向对象?面向对象的特征?面向对象和面向过程的区别?
  4. Unity声音 Sound (圣典篇)
  5. Linux切换中英文环境
  6. antd3.x版本table使用fixed错位问题修复
  7. Windows下Android源码下载
  8. C++ Reference: Standard C++ Library reference: C Library: cmath: cosh
  9. 【你好,windows】Windows 10 18363.476 X86X64企业G纯净版2019.12.5
  10. [SPSS]因子分析和因子得分的SPSS实现——学生成绩因子构成和分科建议实例