电子产业一站式赋能平台

PCB联盟网

搜索
查看: 262|回复: 0
收起左侧

【芯片设计】深入理解AMBA总线(五)AHB-lite Transfer进阶

[复制链接]

407

主题

407

帖子

5198

积分

四级会员

Rank: 4

积分
5198
发表于 2023-12-29 12:00:00 | 显示全部楼层 |阅读模式
上一篇文章介绍了AHB的发展历史、AHB-lite BUS的架构、AHB-lite的信号介绍以及最简单的AHB-lite传输流程,这节课给大家介绍AHB-lite的一些控制信号,帮助大家进一步理解AHB-lite协议,除了掌握协议本身,更重要的是去思考为什么要这么设计,有什么好处,这样学别的协议就简单了。
1、AHB-lite控制信号

3xfqk0lwecm64044031946.jpg

3xfqk0lwecm64044031946.jpg

图1
总线协议,本质上就是完成主机和从机之间的通信传输,因此我们基于上面的硬件架构图去讲解,大家阅读下文的时候要有意识的去思考这个硬件架构图。
1.1、Transfer TypeHTRANS[1:0]信号用于指示当前的传输类型,一共有四种类型:
IDLE
没有数据传输,其它的控制信号和地址信号因此也就不起作用。
BUSY
没有数据需要传输。
这个信号可以在突发传输中(什么是突发传输后面讲,因为官方文档也是这个顺序,如果这一部分看不懂的,先硬着头皮看完,然后等看完后面的突发传输再回过头来再看一遍),用来插入空闲的CYCLE,表示主机在忙,也就是说传输还在继续,但是处于暂停状态。
在不指定突发长度的情况下,在最后一拍用BUSY去传输,来表明这是Burst的最后一笔,这一鸡肋的机制被AXI的LAST信号完美替代。
实际上BUSY这个状态很少见,在CORTEX-M系列基本上不会有这个BUSY状态,在大部分情况下都是使用NONSEQ和SEQ传输类型,因此可以暂时不去掌握该类型
NONSEQ
需要传输数据。
可能是发一笔数据(Single传输),也可能是Burst传输的第一笔transfer(在这里transfer指的是突发传输的一次读或者一次写,或者就是Single传输)。
地址和其它控制信息和之前的传输没有关系!只取决于这次transfer本身。
SEQ
需要传输数据。
用在突发传输中,代表连续的传输。
地址需要增加(除非上一笔transfer是BUSY transfer)。
其它的控制信号保持不变。
话不多说,我们直接看时序图,更加便于我们的理解:

zxskp5hhlpc64044032046.jpg

zxskp5hhlpc64044032046.jpg

图2:4-beat突发读
可以看到这次的时序图和之前最简单的传输相比,增加了一个HTRANS信号,实际上是之前没有画出来,大家可以思考一下最简单的传输中HTRANS信号应该是怎么变化的?
由上图可以知道,这是一次突发读操作,实际上是4拍有效读:
T0->T1:突发传输的第一笔Transfer,因此HTRANS应该为NONSEQ,HADDR为0x20代表起始地址.
T1->T2:突发传输的第二笔Transfer(伪),因为HTRANS为BUSY,可能是因为主机忙碌没有空去读,所以插入了这样一拍,HADDR增加0x4,HRDATA返回了0x20地址的数据,这一拍没有发生数据传输。
T2->T3:突发传输的第二笔Transfer(真),由于上一拍是BUSY,所以HADDR的地址不需要增加。HTRANS应该是SEQ。
T3->T4:和上一拍差不多,第三笔Transfer。
T4->T5:最后一拍读,由于Slave不能完成数据传输,因此将HREADY拉低,这一拍相当于wait state。
T5->T6:最后一拍读,HREADY拉高,说明这拍主机可以将控制信号等信息发给从机。
T6->T7:从机返回最后一拍读的数据。
1.2、Locked Transfers如果主机想发起一次带锁的访问,那么就需要HMASTERLOCK信号。至于什么是“锁”,请自行学习操作系统相关的知识(想做SoC的朋友一定要认真学操作系统和体系结构这两门课啊!)。
简单理解就是在多主机可以访问一个从机的情况下,需要确保这个时间段只有该主机对其进行访问,避免数据出现错误,如图3所示。(想象一下,主机2去写个数据,还没有写完主机1就去读同样的地址的数据,就拿到了旧的值,这样就不符合预期了,很多汇编指令有原子操作指令,从底层来看就需要硬件的机制来帮忙)。

zxi5uj0fciv64044032146.jpg

zxi5uj0fciv64044032146.jpg

图3
同样的,我们看传输协议,如图3所示。可以看到是一个读操作一个写操作,HMASTERLOCK为高说明这是带锁的操作,也就是希望这两个操作之间不希望被BUS的Interconnect打断!
以图5为例,slave3可以被多个Master访问,假设Master0发起了读又发起了写,没有原子操作的支持的话,假设Master1也发起了读,我们本质上是希望Master1读到Master0写到slave3的数据,但是Master1的读很可能位于Master0的写之前,这样就不符合我们的预期了。流程如下:
Master0读Slave0
Master1读Slave0(读到的还是之前的值,不是Master0新写的值!)
Master0写Slave0
因此就需要HMASTERLOCK的支持。他保证了这两笔是原子的,中间不会有任何的操作。这样就非常的赛高啊,完美实现了我们的需求。流程如下:
Master0读Slave0紧接着Master0写Slave0(这是一个整体,不能被打断)
Master1读Slave0
此外在原子操作的下一拍,通常插入一个IDLE,代表原子操作结束了。如图2的第三拍所示。

doejt1z5bh464044032246.jpg

doejt1z5bh464044032246.jpg

图4

uiest4a3oaw64044032346.jpg

uiest4a3oaw64044032346.jpg

图5
还有一点需要注意,大部分Slave实际上不需要实现HMASTERLOCK信号,因为大部分Slave不会被多个Master所访问。只有能够被多个Master访问的Slave,才需要HMASTERLOCK信号,如多端口Memory Controller,就必须要实现HMASTERLOCK信号的机制。
最后再补充一下Locked Transfer和ARM处理器的知识:
ARM9和ARM11处理器在使用SWP指令的时候发起的传输会是Locked Transfers(这两种处理器已经没人用了)
Cortex-M3使用Locked Transfers,用在Bit-Band write上。(专门划分了一个位操作的区域,对这一区域的访问会自动转换成Locked Transfers,所以比较慢)
Locked Transfer实际上用的很少了,SWP指令也被抛弃了(思考一下为什么),因此这一部分大家还是侧重于学习思想即可。
1.3、Transfer sizeHSIZE[2:0]用于标志数据传输的位宽,共有下图这几种组合。

bvzvaekmuwr64044032446.jpg

bvzvaekmuwr64044032446.jpg

图6
这个信号其实非常简单,对于信号自身而言没有任何难以理解的地方。
有一点需要注意的是它其实表明了在突发写或者突发读中HADDR每一次需要增加多少。我们最常见的是32bit,此时HSIZE=3'b010。因此HADDR应该每一次增加0x4(不要问我为什么地址加0x4对应32bit...)。
1.4、Burst operation突发传输!重中之重!
在之前的例子中,我们其实已经见过了什么是突发传输。突发(burst)将多个传输(Transfer)作为一个单元(有时候可以叫Transaction)进行执行,而不是独立地处理每次Transfer,核心思想是将多次Transfer看做一个整体。对于主机而言,一次下发,即可实现连续的写或者连续的读。
我们重新看一下图2,这就是一次突发读。共有4个beat(4次Transfer)。对于主机而言,只要下发一次命令,给个起始地址,给个突发传输的类型,给个Size。就不用管后续的东西了,剩下的Interconnect会帮助主机完成。
接下来我们分析不同的突发传输类型,进而讨论突发传输的优点和应用场景。
突发传输本质上有四种类型:
SINGLE
突发长度为1,也可以理解成不是突发传输。
HTRANS可以是IDLE或者NONSEQ。
INCR
非定长。
不可以跨越1KByte的边界(因为AHB规定不同的Slave最小粒度为1KB,因此跨越1KB可能访问到别的Slave去)。
INCRx
定长,可以是4、8、16笔transfer。
不可以跨越1KByte的边界。
WRAPx
回环(主要用于cacheline,具体的后面说),可以是4、8、16笔transfer。
Cacheline访问,critical word first(关键词优先)。
首先看一下INCR4的例子,如下图所示:
总共是4笔Transfer(因为HBURST为INCR4)
HADDR每次增加0x4(因为HSZIE为Word,即代表32Bit)
HTRANS,第一笔为NONSEQ,后面的为SEQ
可以看到有了突发传输,主机只需要给个地址,给个HBURST类型,给个HSIZE,就可以坐等4组数据的返回了!并且突发读是流水线的,理论上最快只需要N+1个Cycle(N为transfer次数)。
再思考一下:突发读或者突发写,和流水线形式的SINGLE TRANSFER是一样快的嘛?为什么?

r1arvho5mwx64044032546.jpg

r1arvho5mwx64044032546.jpg

图7
再看一下WRAP8的例子,如下图所示:
总共是8次Transfer(因为HBURST是WRAP8)
地址每次增加4(因为HSIZE为Word,即代表32Bit)
地址不总是增加,从0x90开始,也就是critcal-word,增加到0x9c以后跳回了0x80
为什么这么算呢?这是由WRAP8和HSIZE共同决定的,HSIZE决定了每次地址增加0x4,而8个0x4就是0x20,也就是0x20为一组。0x90则属于第五组(0x80~0x9C之间),因此地址是这样变化的(看一下图9,从中间开始增加,然后返回起点继续写)。

z0i1bxrsiyt64044032646.jpg

z0i1bxrsiyt64044032646.jpg

图8

spmoq1zbdnl64044032746.jpg

spmoq1zbdnl64044032746.jpg

图9
最后我们回顾一下开始的思考题:突发读或者突发写,和流水线形式的SINGLE TRANSFER是一样快的嘛?为什么?
表面上来看,没什么区别。理论上都是N+1个Cycle。但是这是针对一拍可以回数的紧耦合SRAM而言的,如果访问的是DDR呢?
如果是突发传输,你只需要下发一次命令,DDR Controller可以帮你计算好,你总共需要读多少数据,比如每一拍是32Bit,突发长度是4,DDR控制器只要对DDR发一次命令即可,一次性读回128Bit的数据
如果是Single transfer,DDR Controller可不知道你下一笔传输的地址和这笔传输的地址只差了0x4,DDR Controller完全可能把你的第一次single transfer下发出去,然后又下发第二次,然后又下发第三次,然后...由于DDR的读取时序没有那么简单,不是完全的流水式的,因此这中间就可以阻塞很多个周期。
所以!突发传输和流水线的Single transfer是不一样的!能用突发传输就用突发传输,不要用多次Single Transfer。

uourwz5g5k164044032846.jpg

uourwz5g5k164044032846.jpg

图10
这篇文章篇幅有点长了,因此AHB-lite文档剩余的一些内容,和一些代码说明放在下一篇文章。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表