APB-AHB协议理解&面试常问点

声明:本文引用IC解惑君的AMBA总线系列文章,加上个人浅薄理解和面试总结

一、APB协议

1、引言

图片

        有一个水果店,只卖三种水果,分别是草莓、蓝莓和苹果。水果店按照客人购买量进行水果的进货厂商根据水果店的要求,提供对应数量的水果并运送到水果店

        每次交易如下:

        水果店根据需求使用大喇叭广播自己的订单需求,说出想要订货的数量,对应厂商提供水果上门,水果店签收。

    使用这条水果运输总线类比AMBA总线的APB总线:

概念1:  主机(Master)

        订单的发起只能由水果店发起,所以水果店在这条水果运输总线里面运输水果占有主动地位。

类比:

        在APB总线里面,数据的传输只能由主机发起,其他部分响应主机操作。

概念2:从机(Slave)

        当水果店发起订单之后,和订单匹配的厂家需要提供对应的水果送到水果店。这里面的厂家只能根据要求送水果,自己不能随便向水果店送水果(没有主动的权限)。

类比:

        在APB总线里面,数据的回复由从机完成,从机只能完成主机发起的操作,自己不能发起操作然后完成操作。

概念3:单主机(Single Master)

        在这条水果运输总线里面,当前只有一个水果店,也只有这个水果店可以发起订单需求,所以在这条水果运输总线里面,只有一个主机(按上图来说)

类比:

        在APB总线里面,有且只有一个主机可以连接到APB总线接口,其他的只能连接从机(外设),所以APB总线只支持单主机模式。即:APB不支持多master。

概念4:总线协议(Bus Protocol)

        在这条水果运输总线里面,水果店按照自己的需求,发起订单,厂商提供水果,水果店确认收到这一个完整的流程以及顺序被称为水果总线在传输水果的协议。

类比:

        在APB总线里面,主机先发起要访问的外设地址,外设根据要求返回数据,主机收到数据,这一个完整的流程被称为APB总线协议。

所以我们可以根据上面得出单主机总线的正式概念

        总线是被总线上所有的部件所共享的一组通路(连线),对于单主机来说,如果该主机想要与其中的外设部件进行通信(获得数据),需要将地址(厂商名字)、数据(水果)、命令(进货还是退货)放到总线上,其他的从机部件对总线上的数据进行侦听,检查地址数据和命令的是否与自己相关,然后相关部件做出响应

概念5:命令总线、数据总线、地址总线

        在这条水果运输总线里面,水果店按照自己的需求,使用大喇叭发出进货还是退货(命令)、哪个厂家(地址)、退货的水果或者进货的水果(数据)。

类比:

        在APB总线中,有地址线(PADDR),命令线(PWRITE、PENABLE、PESEL)和数据线(PRDATA、PWDATA)。

PS:举的例子和APB不是一一完全对应,但是表达的意思相同。

2、APB总线协议详解

2.1、APB在SoC内使用的部分

CPU :CPU是操作的发起者,CPU发起读写外设数据的操作。(相当于Master

APB_Interconnect:根据上文所说的总线协议和传输信号的要求,构建出来的设计实体,该实体接收CPU发出的数据和指令,然后广播到每一个外设部件。(DUT

SLAVE:对APB_interconnect输出数据和指令进行响应。(Slave

图片

Q1 : 是否可以不需要APB_interconnect,APB_Interconect的作用是什么?

        如上图,当CPU只有一个外设,那么直接可以和外设相连,不需要APB_Interconect。此时CPU的发出的指令和操作只会发给URT0,不需要地址来仲裁。如下图:

图片

        但是当CPU需要连接多个外设的时候(CPU只管发出地址和命令),根据CPU地址范围分配表

        APB_Interconect对每一个外设设置地址,然后APB_Interconect根据CPU发出的地址,选中对应地址的外设,把CPU的地址和指令传输到该外设 [地址路由仲裁]。

结论:是否需要APB_interconnect根据应用而定,如果只是单个的外设连接CPU(很少出现),可以直接连接CPU和外设通过APB总线。不需要APB_Interconect但是当外设数目变多,自然而然的就引入了不同外设的区分,所以当多个外设的时候,需要引入APB_Interconect来做这些相关的处理。

        用水果店类比:水果店用大喇叭发出订单,所有的水果厂家进行侦听,然后响应订单,或者假如水果厂家没有侦听装置,可以在水果店和水果厂家之间加一个Interconect这个Interconect的作用是当收到某一个厂家的名字时,根据厂家名字和地址的关系,把需求单独发送给对应的厂家,专门通知供应厂家(也就是选中外设)。

图片

2.2、APB总线接口(AMBA APB 2.0)

系统信号
PCLKAPB总线的时钟,APB所有的操作在时钟下进行,上升沿有效。
PRESETNAPB总线复位信号,给APB 总线电路结构初始值
地址总线
PADDR传输APB 想要操作的地址
命令总线
PSELx根据地址生成选中的信号
PENABLE根据地址生成使能的信号(APB协议要求)
PWRITE传输APB主机的读写操作,1写0读
数据总线
PRDATA外设给主机返回的数据通道
PWDATA主机需要给外设写入的数据通道

根据上图,结合之前的类比和概念我们基本就可以知道APB该怎么运行。

2.3、APB Bridge示意接口(APB_Interconnect

根据AMBA APB手册,截取APB Bridge接口:

图片

图左边的接口System Bus Slave Interface,连接APB主机(即上面的CPU),这个接口也是APB完整的接口,包含上面举例的信号。图右边和左下面的接口连接多个SLAVE其中PSELn有多个,每个对应不同的SLAVE。其他信号对于SLAVE是一致的,因为PSELn已经可以选中不同的SLAVE来接收传输的共享信号了。

2.4、APB BUS时序(AMBA APB 2.0)

写传输:

图片

如上时序图,主机在T2时刻把所要访问的地址,命令和数据全部放到APB总线上,沿着组成APB的接口的金属线传播到从机接口处。在T3时刻,从机发现自己的PSEL信号为高,就知道主机选择它来处理数据的写操作,此时从机内部准备好处理数据的准备动作,在T4时刻,从机完成总线上数据采样并进行内部数据处理

读传输:

图片

如上时序图,主机在T2时刻把所要访问的地址,命令和数据全部放到APB总线上,沿着组成APB的接口的金属线传播到从机接口处。在T3时刻,从机发现自己的PSEL信号为高,就知道主机需要它内部的数据(PWRITE ==0),此时从机内部准备好返回数据并把返回的数据放在数据总线上,在T4时刻,主机完成总线上数据采样得到需要的数据

2.5、APB总线优缺点

优点:设计简单,时序简单,可以用在不需要高性能总线的外设。

缺点:APB总线只支持一个主机工作;每个数据的传输都需要两个时钟周期,这样APB总线满载的带宽也只有50%,带宽利用率不高。

二、AHB协议

1、引言

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

1.1、背景

还是以水果店举例,在APB中,只有一个水果店,只卖三种水果。但是随着地区人数的上涨,一个水果店(单主机)已经无法满足当前地区居民的需求,并且在APB中,水果店和供应商的配合时间太长(传输效率低),所以在股东的商议下决定再开一家水果店(大于等于2),这样两家水果店独立运营,这种情况下之前的水果运输总线(APB BUS)就无法满足需求,需要重新指定水果传输总线V2

图片图片

在改进了总线版本后,就会出现水果传输策略的问题,其中最主要的两个问题如下:

问题1:当水果店1和水果店2同时缺货时,两家店同时使用大喇叭广播自己的订单需求,那么供应商此时因为两个喇叭同时通知,听不清订单需求,会产生互相干扰。

概念1:总线碰撞(Bus Collision)

        由于水果店1和水果店2同时使用大喇叭广播自己的需求,导致供货商听不清订单需求,那么此次水果传输任务将失败。

类比:

        AHB总线中,ARM在设计时支持连接多个主机的操作,当两个或两个以上的主机同时发起数据操作时,总线会产生混乱,导致传输失败。

本质原因:一条总线服务两个主机,难免产生冲突,比如两个人同时打第三个人的电话,第三个人只能接其中某一个人的电话,资源冲突

解决方法:

(1)每个水果店配套一个水果运输总线,同时供应商也再配套三个,专门为对应的水果店服务,在设计中叫资源复制。这种方法最简单,但是消耗大量资源。

(2)当出现两个水果店同时进行订单需求时,水果店先确认另一个水果店有没有广播,如果有就等另一个水果店使用大喇叭广播完毕,自己再使用大喇叭广播,在总线协议中,这个动作叫总线侦听

(3)两个水果店不想派人力进行侦听广播(或不具备条件),所以购买一个仲裁设施,仲裁设施对水果店等级进行分类,如果两个水果店同时发起请求,那么更重要的水果店先获得这个仲裁设施的允许再使用大喇叭广播(获取仲裁允许的动作叫作获取总线授权),等更重要的水果店完成订单之后,仲裁设施再服务相对而言不重要的水果店,在总线中称为优先级仲裁策略

结论:

        ARM在升级APB时,为了支持多主机操作,同时为了解决总线碰撞的问题,引入了方法三即优先级仲裁策略,给每个主机分配了不同的优先级,优先级高的主机先发送数据,优先级低的主机等待完成之后再进行数据发送。

注:

        CAN总线、I2C总线使用的是方法二总线侦听。一般来说,分布式总线倾向于总线侦听策略,而集中式总线倾向于优先级仲裁策略(如SOC片内总线)。

问题2:在APB总线中,水果店需要一箱水果,厂家就提供一次水果传输,水果店再需要一箱,再次提供一次传输,这导致水果店订单小但却经常发起订单,浪费了厂家的运输时间,因为等待订单和运输是串行工作的,只有先订单发出了,再运输,再发出订单,再运输。

概念2:突发传输(Burst)

        在水果店发起请求的时候,不再以一箱水果作为订单单位,而是以N箱作为订单请求(burst_type),虽然厂家运输单位仍然是一箱(一辆车只能运送一箱),但厂家可以派出多辆车同时传输,形成运输车队(即流水线!),这样N拍运输时间就基本满足了水果店的需求,而在APB总线下需要2N拍时间才能满足需求(每个数据的传输都需要两拍)。所以该方案需要水果店和厂家同时改进方案。

类比:

        AHB总线中,数据传输基于burst type传输,每次传输都是多个(总线位宽)数据,通过数据形成多拍(流水线)效果,相比APB可以提高数据传输效率。

概念3:多主机总线

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

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

        其次需要将地址(厂商名字)、数据(水果)、命令(进货还是退货)放到总线上,其他的部件对总线上的数据进行侦听,检查地址数据和命令的是否与自己相关。

        最后相关从机部件做出命令响应

2、AHB总线协议详解

2.1、AHB在SoC内使用的部分

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

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

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

SLAVE:对DUT输出数据和指令进行响应。

图片

Q2 : 是否可以不需要AHB_interconnect,AHB_Interconect的作用是什么?

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

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

2.2、AHB总线接口(AMBA AHB 2.0)

AHB信号较多,相应功能也比较强大。具体可看我的另一篇文章:AMBA 2.0 AHB Spec 阅读笔记

名称            来源描述
系统信号:
HCLK时钟源AHB总线的时钟,所有的设备的操作都在时钟下进行,上升沿有效。
HRESETn复位控制器AHB总线复位信号,给AHB总线电路结构初始值
地址总线:
HADDRMasterAHB传输主机想要操作的地址
数据总线:
HWDATAMaster主机需要给外设写入的数据通道
HRDATASlave外设给主机返回的数据通道
命令总线:(支持突发)
HWRITEMaster传输AHB主机的读写操作,1写0读
HSIZEMaster传输数据的位宽(Byte、HalfWord、Word)
HBURSTMaster传输数据的个数
HPROTMaster提供给外设一定级别的保护
HSELxDecoder仲裁器根据配置输出的选中外设的标志
HTRANSMaster本次传输的类型(IDLE、BUSY、NONSEQ、SEQ)
HREADYSlave此次传输数据是否完成只关注完成,不关注对错
HRESPSlave此次传输数据外设给出的响应,表示外设处理的对错等
仲裁总线:(支持多主机)
HBUSREQxMaster主机请求仲裁器,想要获得总线所有权
HLOCKxMaster主机请求锁定总线一段时间(在这段时间内这个主机独占,不能被再授予
HGRANTxArbiter获得总线所有权标志(还要结合其他信号)
HMASTERArbiter哪个主机正在使用总线支持SPLIT从机寻找对应的主机(后面这个附加其他功能,后文详解)

HMASTER
LOCK

Arbiter表示使用总线的主机正在尝试一次锁定次序的传输(附加其他功能,后文详解
HSPLITxSlave从机指示仲裁器,对应的主机应该重新发起一次SPLIT传输。(附加其他功能,后文详解

3、AHB的从机响应

3.1、数据传输

在AHB总线中,数据传输分为三个层次:

Transfer:

AHB bus 数据传输的最小操作单位。在这里,称之为元传输操作。这里的元代表该操作不可分割,不可打断。

这个操作表示:

主机把一次访问的地址和命令放到总线上,总线上对应的从机响应主机的操作。

举个例子:CPU读取0地址处的一个数据,数据的位宽是Word,这个完整的操作就称为一次Transfer。

基本的Transfer就理解成一辆车运一单。

Burst:

多个相同类型的Transfer组成一个Burst

这里的类型相同指的是:

访问数据的位宽相同,访问命令相同(读/写),但是地址不同

举个例子:CPU读取0、4、8、C地址处的数据数据的位宽是Word。在这里面,除了访问的地址不同,数据的其他属性(位宽、读写)都相同。

CPU在访问这些数据的时候,也是完成一次Transfer之后才发起另一次Transfer操作。

运输车队流水线,一辆车运一单但是有很多辆车组成车队。

用户数据传输包:(由自己定义)

用户想要通过AHB总线传输的总的数据量

比如用户通过AHB总线上的DMA,把数据从UART传送到Mem中,需要传输的总数据量为1MB。这1MB数据就称为用户数据传输包

想要通过AHB Bus传输这些数据,就需要按照AHB 总线的格式,把总的数据先分成不同的Burst,然后不同的Burst完成不同的Transfer,从而完成整个数据的传输。

大卡车车队,每辆卡车里面有一个个单元大小的集装箱,每次只搬一个箱子。

图片

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

类比:

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

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

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

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

图片

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

3.2、从机回复机制

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

场景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)但是因为我发起的这个要求不合理,小明根本完不成,所以反馈错误命令(RESP == ERROR)。

类比:

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

场景4:主机发起请求,从机响应,处理要时间,提醒主机

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

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

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

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

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

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

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

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

类比:

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

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

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

场景5:主机发起请求,从机响应但内部忙暂时无法处理

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

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

小明:哎,我听到你说做1个俯卧撑(先响应这个)。但是我现在有点忙,等会你再说一遍(给当前这个请求一个暂时的回复)

等几秒~~~~

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

小明:收到,俯卧撑1个成功完毕

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

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

类比:

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

从机不会再提醒主机,主机一会自己主动尝试联系从机

总结

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

从机请求主机等待自己的响应分类:

占用总线

注意!

HREADY == 0 

&& 

RESP == OKAY 

从机无法接受命令且不准备释放总线因元操作未完成

释放总线

HREADY == 1 

&& 

RESP == SPLIT

任务复杂,暂时不能完成和回复任务响应。先释放总线,稍后从机通知主机查收(从机会提醒主机

HREADY == 1 

&& 

RESP == RETRY

从机自己还在执行其他主机任务,暂时响应不了当前主机的任务,先释放总线,让主机等会再试试(从机不会提醒主机,主机自己尝试

HREADY == 1 

&& 

RESP == ERROR

从机认为任务有问题,无法/没有能力执行,直接释放总线

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

4、AHB的主机控制

对于主机来说,主机发送的完整Burst没有完成,卡在发出Burst中间的某一个transfer中,主机需要如何应对这样的情况?

从机回复:主机动作:

HREADY == 1 

&& 

(  

RESP == SPLIT      | |

RESP == RETRY

主机发出的一个完整的Burst内的Transfer,从机反映出现了问题(暂未处理),那么对于主机来说,就需要把当前出现问题的Transfer位置记录下来,然后把总线交还给仲裁器(从机已经表示主机可以释放总线资源)。然后等下一次主机申请到总线之后,再把出现问题的Transfer发出来。

但是因为主机每次的数据发送是基于Burst,那么上次出现问题的Transfer(中途因为问题中断)就需要在新的Burst里面重新生成并且是该Burst内的第一个Transfer

比如:主机第一次发了读0地址,Burst 长度4 ;表示 0 ,1,2 ,3地址被慢慢送上总线,这时候从机反映1地址 Transfer 出现问题,主机只能停止发送(等待从机解决,释放总线),等下一次主机发送的时候(完成剩下的任务),主机就必须从被终止的地方重新开始读1地址Burst长度3(假如协议存在这种长度的Burst),把上一个Burst剩余的Transfer发送完毕

HREADY == 1 

&& 

RESP == ERROR

主机接收到从机反馈的请求,知道自己的要求不合理

所以可能会有两种解决方案(任意一种均可):

(1) 跳过这个地址,重新生成发送基于下一个地址的新的Burst,覆盖上一个Burst剩余的所有Transfer(主机考虑到当前不合理,剩下的所有的Transfer是正确的)。

(2) 停止发送这个Burst内剩余的所有Transfer(主机考虑到全部不合理)。

HREADY == 0

&& 

RESP == OKAY

(RESP默认OKAY)

主机接受从机反馈不要释放总线的请求,主机一直占用总线等待着从机的回复主机不会发出新的Burst(一直都在等待当前Burst内部的Transfer完成),单纯的占用总线等待从机的响应,在这种情况下,主机不需要计算剩余的Burst和Transfer(因为主机没有释放总线开启新一个Burst),只在等待从机的响应即可,等从机响应当前Transfer之后,继续发当前Burst剩下Transfer的数据。

上面所有的内容,都是主机根据从机的反馈,调整自己的内部状态,匹配从机的反馈,完成一次数据的传输。那是否可以想到,主机会不会有一系列的反馈状态告诉从机,控制当前传输。

主机是否也有能力,在传输的时候表达自己内部当前的状态

(1)比如主机遇到问题,不能连续发出从机需要执行的命令

(2)比如主机并不需要和从机进行通信(总线上没有通信的有效命令

(3)比如主机正常和从机通信,需要从机执行命令这个流程(正常流程

4.1、引言

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

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

4.2、主机数据传输机制

场景1:BUSY

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

我:    小明(确定对象),去做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:IDLE

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

我:    小明,没啥事

小明: 好的(必须回复OKAY,因为小明当前没有任何任务)。

我:    小明,没啥事

小明: 好的(必须回复OKAY,因为小明当前没有任何任务)。

类比:

        AHB主机并没有什么数据和从机进行通信,但是AHB协议上并不允许什么数据状态都没有(就算没有数据和命令都必须打空拍。所以主机和从机为了满足AHB规定的协议状态,只能像正常工作一样,主机发起空传输HTRANS == IDLE),从机应答(RESP = = OKAY && HREADY == 1,满足协议的规定。

PS:从上面这点可以看出,即使总线上没有东西传输,也要维持传输的动作状态(空拍)主机发空操作,从机回复OKAY。

场景3:NONSEQ & SEQ

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

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

小明: 已经成功做完!(既表示可以处理,同时任务处理完成了)

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

小明: 已经成功做完!(既表示可以处理,同时任务处理完成了)

我:    小明(确定对象),开始去跳1(数据)下绳(命令)

小明: 已经成功做完!(既表示可以处理,同时任务处理完成了)

我:    小明(确定对象),继续去跳1(数据)下绳(命令)

小明: 已经成功做完!(既表示可以处理,同时任务处理完成了)

我:    小明(确定对象),继续去跳1(数据)下绳(命令)

小明: 已经成功做完!(既表示可以处理,同时任务处理完成了)

我:    小明(确定对象),继续去跳1(数据)下绳(命令)

小明: 已经成功做完!(既表示可以处理,同时任务处理完成了)

类比:

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

从机可以按照自己的状态,反馈给主机。完成主机发出的Burst中的一次Transfer传输

主机:

HTRANS == 

SEQ

从机:

RESP == XXXX

主机接着Burst的开始Transfer之后的Burst中的其他Transfer

(比如场景3的开始跳绳命令之后的三个继续跳绳命令

从机可以按照自己的状态,反馈给主机。完成主机发出的Burst中的一次Transfer传输

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

ADDR :1022102310241025 
HTRANS NONSEQ SEQSEQSEQ

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

ADDR :102210231024
HTRANS NONSEQ SEQSEQ

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

ADDR :1025 
HTRANS NONSEQ

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

5、AHB的主机仲裁

仲裁部分深入探讨一下,如果多个主机同时需要获取总线访问权是如何夺权和斗争的,同时也可窥见ARM官方是如何定义多个主机争权夺势的规则。

5.1、主机仲裁机制

场景1:FIFS先来先仲裁

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

类比:

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

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

场景2:优先级仲裁

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

类比:

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

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

场景3:先来先 ++ 优先级仲裁

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

类比:

        两个AHB的主机现在连接在AHB_Interconnect上。首先主机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:先来先 -- 优先级仲裁

在场景3中,即使我先发起购买的动作,但是最终煎饼果子店还是先服务了小明,之后再服务我。同时在上面我们也分析了原因,因为我购买煎饼果子到煎饼果子交付中间的环节相对较多,每个环节可能都会被小明趁机而入。同时每个环节没有明显的禁止插队的规则,所以基于此,看看AHB总线如何解决这个优先级插队的问题

我和小明在大街上游玩,突然我有点饿,于是就去煎饼果子店买煎饼,小明没过了一会也觉得饿,也去煎饼果子店买煎饼,因为煎饼果子店只有一家,虽然煎饼果子的店老板是小明的爸比。但是店内的发票机器是根据先后顺序打票并进行交付煎饼果子,这样虽然小明的爸爸是店长,但是按照机器的打票规则必须先给我打完发票交付之后才能再给小明交付。在这期间,机器打票规则这个就成了我捍卫我自己的权利的一种规则或者手段。

类比:

        在AHB总线协议中,在前文我们分析了AHB的接口,在表格中我们列出了一个信号:HLOCKx在AHB中,这个HLOCKx信号就是主机捍卫自己权利的一种规则或者手段,如上例子,当主机1在进行数据请求传输的时候,不希望别的主机打扰他,于是他在请求总线的所有权的时候,拉高HLOCKx信号既在请求中表达了自己想要获取总线又表示我希望我这次获取的总线是不能被别人打扰的相当于请求的进一步递增。这时候,AHB_Interconnect 把总线授予给主机1,同时也在内部做好不会在主机1使用总线的时候,让其他的主机使用总线(即使优先级高也不行)。等到主机1请求完了之后,高优先级的主机2才能进行总线所有权的获取和数据的传输

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

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

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

Q:那么这个(HLOCKx  = 1)会在什么情境下使用呢?或者换个说法的话,什么情况下一个主机发送数据才不想要其他的主机打扰呢?

A:不想被打扰状态代表主机的一次操作具有原子性。原子操作一般会用在操作系统中。

信号量:一般情况下,解决进程/线程之间的同步和互斥问题的一种通信机制。假如CPU 0 运行一个程序1,CPU 1运行一个程序2。但是程序1和程序2都需要配置UART 0发送当前运行的程序标号。即“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体现。其他的应用就不一一说明了。

6、AHB主机仲裁时序分析

6.1、多Master多Slave

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

图片

如上图所示:

1)CPU和DMA同时向AHB_Interconnect申请获得总线所有权。

2)AHB_Interconnect(内部权衡)之后决定把总线授予给CPU,所以AHB_Interconnect应答了CPU申请总线的信号。

3)此时CPU已经知道自己获得了总线的授权,所以把自己需要访问的地址和命令放到总线上

4)通过CPU发出的地址范围AHB_Interconnect把命令和地址路由(转发)到对应的UART从机。

5)UART从机接收到主机发过来的命令,知道要进行读取自己内部寄存器的操作,所以自己把自己内部的数据放在数据总线上。

6)再由AHB_Interconnect路由到对应的主机的数据总线接口,交付给主机。

该模拟的操作完全把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协议通过流水线操作增加了APB总线的带宽。

6.2、时序图分析

6.2.1、单主机仲裁

图片

a. 单主机单周期仲裁时序图:

图片

(1)CPU先在(T1后)拉高HBUSREQx信号向AHB_Fabric申请使用总线

(2)AHB_Fabric同意主机使用,所以在(T3后)拉高HGRANTx表示允许主机使用总线。

(3)CPU收到AHB_Fabric返回的授权命令,于是就在T4周期后把自己想要控制的地址通过金属线发送到AHB_Fabric,在此周期内 AHB_Fabric把对应的地址和控制信号路由到Slave对应的接口上去。

(4)T5周期后,CPU既发出(A+4)的地址,又发出A地址所对应的数据[A]在这个周期,也就是AHB比之APB体现性能的地方所在,分离地址和数据进行流水操作。

PS : HMASTER表示当前哪个主机正在使用总线

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

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

b. 单主机周期仲裁时序图:

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

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

T4时刻:CPU收到AHB_Interconnect的授权信号(认为自己得到授权,准备占有地址和控制总线),准备发出地址和控制信号的时候,发现HREADY信号为低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的一个缺点呢?

6.2.2、多主机轮转

图片

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的下一拍的地址和命令信息。

6.2.3、多主机仲裁

图片

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总线面试题

1、描述一下AHB协议

AHB是一种高性能的高速总线,两级流水线操作(地址周期和数据周期),可支持多个总线主设备(Master),最多16个,支持burst传输(一次传一批)

2、AHB的基本信号

Master发出的信号:
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。
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过段时间再来。

3、AHB是流水的嘛,是几级流水,如果这一拍是地址,且有数据,那么下一拍的地址可以改吗

AHB是两级流水线,先地址再数据,注意数据和地址分两个总线传输(Pipeline形式),A地址的数据需要在下一拍到达,也就是A的下一个地址和A的数据同时到达。下一次如果HREADY信号为高,地址就可以改。

4、请描述一下AHB协议你是怎么写的,AHB的第一拍是做什么,第二拍做什么?Hready为高是什么操作?

自写的vip中,不管是执行写操作还是读操作,都要等待总线的授权,主机先向总线请求授权,总线给予授权,从机给予响应之后再进行处理。

AHB是个流水线结构,主机在第一个时钟周期hclk的上升沿给出地址和控制信号,随后从机会在第二个时钟周期给出响应,主机则会在第三个时钟周期采样到从机的响应;如果第一拍给出地址A,那么第二拍在给出地址B的同时可以给出地址A的数据,第三拍给出地址C和地址B的数据,以此类推。

HREADY为高表示当前传输已经完成,但是该信号并不关心传输的对错,所以还需要HRESP信号,HREADY拉高表示一次传输完成,拉低表示需要等待传输;当一次传输成功完成时,HREADY拉高同时RESP返回OKAY。

5、AHB是怎么验的,验证环境是怎么搭的

6、AHB的driver和monitor是怎么写的,你这个数据是从哪里来到哪里去

首先明白数据是怎么传的,不同的tc对应不同的seq,产生的激励通过挂载到sequencer上传到driver中,同时driver里通过seq_item_port.get_next_item()向sequencer申请transaction,完成一次握手。

driver拿到这个tr后按照时序进行驱动,驱动时首先判断burst_type即突发类型,transfer元传输和burst突发传输对应着不同的task,使用case语句。

在自写vip中,仅考虑元操作即do_atomic_trans,在元操作中,判断读写即xcat_type,如果是写操作则执行写过程,读操作则执行读过程。

先进行SINGLE的写操作,首先等待总线授权,即先拉高HBUSREQx总线请求,然后等待HGRANTx授权信号和HREADY信号表明从机已经响应,接着将htrans设为NONSEQ,地址、突发类型、传输大小分别进行非阻塞赋值为transaction中的对应值,而hwrite信号置1,表明当前为写操作,SINGLE操作时空一拍,然后将tr的data给到cb的hwdata,先驱动数据!同时整个操作阶段一直检查下降沿时hready信号是否拉高,如果拉高则跳出进行读操作,如果hready一直为低电平代表从机未响应,那么主机占线就一直等待。

然后执行SINGLE的读操作,一样的htrans设为NONSEQ,地址、突发类型、传输大小一样赋值,hwrite信号置0,表明当前为读操作,SINGLE操作空一拍,先驱动数据!然后检查hready,如果OKAY那么执行,读回接口上的rdata。

7、AHB的协议和APB的协议特点,以及两者对比

APB总线设计简单,时序简单,可以用在不需要高性能总线的外设;AHB总线相比于APB总线具有高性能、流水线、突发、多主机、分段传输的特点,是一种高性能总线。

8、AHB总线的速率为什么比APB速率高

因为APB总线只支持一个主机工作;每个数据的传输都需要两个时钟周期,这样APB总线满载的带宽也只有50%,带宽利用率不高。

而AHB总线可以使用流水线形式传输,支持burst和多主机,可以提高传输效率。

9、AHB的传输类型,说一下4回环突发的传输应该是怎么样的,这个回环边界怎么确定

传输类型(trans_type)是由信号HTRANS[1:0]来表征的,分为IDLEBUSYNONSEQSEQ,具体见下。

WRAP回环突发表示:在一定长度后如果跨越地址边界,就会回环到起始地址。主要应用于cache中,因为cache是按照cache line操作的,使用wrap突发传输可以实现从内存中取回整个cache line。

WRAP4:代表四拍回环突发。

回环计算方法为:地址边界 = HBURST拍数 * HSIZE大小 = beats * size。

所以当字传输时,WRAP4的地址边界 = 4 * 4 = 16。

比如突发地址0x34、0x38、0x3C、______

换算为十进制,即52、56、60都不能被16整除,而下一位64可以被16整除,所以发生回环,回到起始地址即 64 - 16 = 48,故填 0x30

10、Hburst和Htrans是怎么用的

HBURST和HTRANS都由Master来控制,Master必须保证两者的一致,即如果突发类型为SINGLE的话,那么HTRANS在传输时无法进行连续传输,因此只能为NONSEQ,如果是burst传输,那么HTRANS在第一次传输时为NONSEQ,后面连续传输为SEQ。

如果突发类型为SINGLE,每次传输完因为不能进行连续传输,总线又规定在没有数据命令的情况下必须打空拍,因此就必须要使用IDLE传输类型。

当MASTER内部有点忙,不能按照协议及时提供下一个Transfer命令时,Master要发出HTRANS == BUSY信号表示当前很忙。

在传输类型为IDLEBUSY时,slave面临这种情况必须回复RESP == OKAY,因为slave并没有任务进行

11、AHB的写过程和读过程,简述一下是怎么读的

先进行SINGLE的写操作,首先等待总线授权,即先拉高HBUSREQx总线请求,然后等待HGRANTx授权信号和HREADY信号表明从机已经响应,接着将htrans设为NONSEQ,地址、突发类型、传输大小分别进行非阻塞赋值为transaction中的对应值,而hwrite信号置1,表明当前为写操作,SINGLE操作时空一拍,然后将tr的data给到cb的hwdata,先驱动数据!同时整个操作阶段一直检查下降沿时hready信号是否拉高,如果拉高则跳出进行读操作,如果hready一直为低电平代表从机未响应,那么主机占线就一直等待。

然后执行SINGLE的读操作,一样的htrans设为NONSEQ,地址、突发类型、传输大小一样赋值,hwrite信号置0,表明当前为读操作,SINGLE操作空一拍,先驱动数据!然后检查hready,如果OKAY那么执行,读回接口上的rdata。

12、AHB中Hready是怎么回事儿,APB中psel和penable的作用

HREADY:Master发送了一个信号,要知道Slave能不能接受,这个信号很重要,Master要知道数据是不是写进去了。
比如发送一个ADDR,检查HREADY是否为高,高了之后再发下一拍的动作:下一个地址以及上一拍的数据。如果HREADY没有被拉高,那么信号维持一拍再检查READY。

如果READY信号不一直为高电平,出现了低电平的话:

当Master检测到Slave的Ready信号为低电平,视为当前的数据和地址都没有被接受,延长一拍再检查Ready信号,如果还是没有,那继续等下一拍。
需要注意的是这个HREADY信号如果一直为低电平的话,等待的时间太长了,是会影响到总线的效率的,所以说不要大于16个时钟周期。如果Slave设备要做的事情很多,那就在RESP信号中,发出Split或者Retry,仲裁信号会根据slave的指示把Master的总线授权给关了,有时还会降低它的优先级。

PSEL和PENABLE:不进入SETUP状态,直接ACCESS其实也可以完成传输,但是APB可能出于通用性,灵活性,时序,历史遗留等考虑,多加一个状态,一根信号。直接由PSEL和PREADY握手就像AXI的单Master多Slave的结构一样是可以的。

  • 5
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值