以下文章来源于微信公众号“IC解惑君”,作者木飞
原文链接:漫谈AMBA总线-AHB(3)
前言:
上文提到,AHB 协议传输的最小单位是Transfer,但是为了传输的效率,一般都会把多个相邻地址和相同类型的Transfer组合成一个Burst。所以我们使用AHB的时候,可以认为AHB协议是基于Burst的协议。而之前我们所说的Slave回复,针对的也就是Burst内部的Transfer的回应。而Slave出现问题的响应,就可以认为对于主机发出的某一个Burst中的Transfer,从机无法及时响应。这样也就造成了一个主机发出Burst中间的Transfer遇到问题,那么对于主机发出的完整Burst并没有执行完成。按照上篇文章的逻辑,从机在无法响应的时候选择占用总线或者让主机释放总线两种方式。那么,对于主机来说,主机发出的完整的Burst没有完成,卡在发出的Burst中间的某一个Transfer中。主机需要怎么应对这样的情况呢?
如下表所示(漫谈AMBA总线-AHB(2)):
从机回复: | 主机动作: |
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 | 主机接受从机反馈不要释放总线的请求,主机一直占用总线等待着从机的回复。主机不会发出新的Burst(一直都在等待当前Burst内部的Transfer完成),单纯的占用总线等待从机的响应,在这种情况下,主机不需要计算剩余的Burst和Transfer(因为主机没有释放总线开启新一个Burst),只在等待从机的响应即可,等从机响应当前Transfer之后,继续发当前Burst剩下Transfer的数据。 |
上面所有的内容,都是主机根据从机的反馈,调整自己的内部状态,匹配从机的反馈,完成一次数据的传输。那是否可以想到,主机会不会有一系列的反馈状态告诉从机,控制当前传输。
那主机是否也有能力,在传输的时候表达自己内部当前的状态?
(1)比如主机遇到问题,不能连续发出从机需要执行的命令。
(2)比如主机并不需要和从机进行通信(总线上没有通信的有效命令)。
(3)比如主机正常和从机通信,需要从机执行命令这个流程(正常流程)。
下面的话,一起学习一下主机Master端有什么控制传输的能力。
引言:
对于主机来说,因为当前传输主动发起表达的是自己的意志和请求,而从机不过是被动的响应(通过在响应中反向表达自己内部状态的机会)。所以可以看到在AHB总线的信号列表中,绝大多数信号接口是为主机表达自己的意思而准备。(参照漫谈AMBA总线-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边界的操作。
下文:
AHB仲裁器的仲裁
AHB传输的时序图分析
AHB总线问题汇总
有问题大家可以后台留言,谢谢大家。
如果有喜欢的文章,大家请点赞分享加转发
未完待续,下文更精彩。。。。。。。。