axi协议中的信号可以分为5组,写地址,写数据,写响应,读地址和读数据。
信号概述
sig_name | source | destination | description |
写地址通道 | |||
awid | M | S | 用于标识写地址是哪个主机发出。 |
awaddr | M | S | 写地址。 |
awlen | M | S | 突发长度,给出突发传输的次数(拍数) [3:0]:axi3,所有突发长度为1-16。 [7:4]:axi4,incr为1-256,其余长度为1-16。 |
awsize | M | S | 突发大小,给出每次突发传输的大小(bits) 总传输量=len*size。 |
awburst[1:0] | M | S | 突发类型,fixed,incr,wrap,reserverd。 |
awlock | M | S | 总线锁信号,提供操作的原子性,普通或互斥访问。 |
awcache | M | S | 内存类型,表明一次传输是怎样通过系统的。 |
awprot | M | S | 保护类型,表明一次传输的[0]特权级[1]安全等级[2]交易是数据访问还是指令访问。 |
awqos | M | S | 质量服务qos |
awregion | M | S | 区域标识,能实现单一物理接口对应多个逻辑接口。 |
awuser | M | S | 用户自定义信号 |
awvalid | M | S | 有效信号,表明此通道的地址控制信号有效,一直保持有效直到awready为高。 |
awready | S | M | 表明从机准备好接收写地址和对应的控制信号。 |
写数据通道 | |||
wid | M | S | 用于表明写数据是哪个主机发出的,与awid相对应。 |
wda | M | S | 写数据,总线位宽可以是8,16,32,64,...,1024bit。 |
wstrb | M | S | 写选通,写数据有效的字节线,用来表明哪8bit有效。 |
wlast | M | S | 用于表明这次传输是最后一次突发传输。 |
wuser | M | S | 用户自定义信号。 |
wvalid | M | S | 用于表明写数据信号有效。 |
wready | S | M | 用于表明从机准备好接收数据。 |
写响应通道 | |||
bid[3:0] | S | M | 写响应id和awid匹配 |
bresp[1:0] | S | M | 表明写传输的状态,ok,exok,slverr,decerr。 |
buser | S | M | 用户自定义。 |
bvalid | S | M | 写响应有效信号。 |
bready | M | S | 表明主机能够接收写响应。 |
读地址通道 | |||
arid[3:0] | M | S | 读地址id |
araddr[31:0] | M | S | 读地址,给出一次写突发传输的读地址,只给首地址。 |
arlen | M | S | 突发长度,给出突发传输的次数(拍数) arlen[3:0]:axi3 arlen[7:4]:axi4 |
arsize[2:0] | M | S | 突发大小,给出每次突发的字节数。 |
arburst | M | S | 突发类型,fixed,incr,wrap,reserverd。 |
arlock | M | S | 总线锁信号,提供操作的原子性,普通或互斥访问。 |
arcache | M | S | 内存类型,表明一次传输是怎样通过系统的。 |
arprot | M | S | 保护类型,表明一次传输的[0]特权级[1]安全等级[2]交易是数据访问还是指令访问。 |
arqos[3:0] | M | S | 质量服务qos |
arregion | M | S | 区域标识,能实现单一物理接口对应多个逻辑接口。 |
arvalid | M | S | 读地址有效信号。 |
arready | S | M | 表明从机可以接收地址和对应的控制信号。 |
读数据通道: | |||
rid | S | M | 读id,与读地址id相对应 |
rdata | S | M | 读数据,总线位宽可以是8,16,32,64,...,1024bit。 |
rresp | S | M | 表明写传输的状态,ok,exok,slverr,decerr。 |
rlast | S | M | 表明读突发的最后一次传输。 |
ruser | S | M | 用户自定义。 |
rvalid | S | M | 表示读数据信号有效。 |
rready | M | S | 表明主机能够接收数据和响应信息。 |
在axi结构上允许多个Master和Slave相连接,因此各个通道都需要用id信号表明是哪个主体发送过来。
len、size和burst信号属于axi通过burst方式传输应用的。axi传输方式有:burst、outstanding、out_of_order、interleaving、narrow、unaligned传输方式。
burst 突发传输:
意思为在一段时间中连续的传送多个(地址相连的)数据。在整个传输事务过程中,master首先将接下来 burst 传输的控制信息以及数据首个字节的地址传输给slave,这个地址被称为起始地址。在本次 burst 后续传输期间,从机将根据控制信息计算所有需要用到的后续数据的地址。AXLEN 信号从零开始表示,实际的长度值为 AXLEN + 1。所以突发长度至少为 1。如果len=0,则需要每发一个数据就发一个地址对应。如果len=5,则可以发一个首地址,发6beat数据。
一个burst就如同一节火车车厢,一列火车有多少个车厢,可以用len表示,车厢的大小装载的人数可以用size表示。axi中size是以字节为单位,为了用较小的数表示较多的位宽,axi字节数信息以2的次方来表示,size =6,表示一个burst中装载了2^6=64B的数。如果声明数据位宽为512bit=64B,那么此size就为6。
在burst写操作中,主机只需要发送首地址,slave会根据首地址和传输的长度将数据传输到对应的地址中缓存,读操作也是如此,主机只需要发送首地址,slave会根据首地址自动进行地址计算,将对应的数据和响应返回给主机。只需要进行一次握手就可以实现地址通道的请求传输,避免系统总线的占用。
burst传输又下分为不同的几种类型:
awburst[1:0] arbursrt[1:0] | 突发类型 | 描述 | 访问 |
00 | 固定长度突发 | 地址固定的突发。 | fifo |
01 | 增量突发(incr) | 地址递增的突发。 | 正常序列memory |
10 | 回环突发(wrap) | 地址递增突发,到地址临界点回环到较小的地址。 | 高速缓存线 (cache line) |
11 | rsv |
FIXED传输为地址固定传输,所有传输都会写在同一个地址中。主要应用在FIFO的传输中,因为FIFO为先入先出,只需要往同一个地址写数据即可。
INCR传输为地址递增传输,可根据具体的配置有固定长度递增和非定长递增。大部分的数据传输都是使用这种方式,尤其是在内存访问中,可以大大提高效率。
WRAP传输为地址回环传输,在一定长度后会回环到起始地址。主要应用在Cache操作中,因为cache是按照cache line进行操作,采用wrap传输可以方便的实现从内存中取回整个cache line。
窄带传输(narrow transfer):
指本次传输数据位宽小于通道本身数据位宽时,称为窄带传输。比如声明一个512位宽的ddr,axi通道数据位宽也是512bit,但有笔实际写入256bit,则master通过mask(strobe)指出哪些bit有效。strobe信号位宽等于数据通道位宽的字节数量。如数据通道位宽为512bit,64B,那么strobe信号位宽为64bit,每bit对应数据的每BYTE是否有效。
非对齐传输:
指起始地址与突发传输位宽不对齐的的传输。如数据总线位宽为32bit,与 32bit 位宽总线对齐的地址需要能被 4 整除。如果起始地址为 0x1002,则产生了非对齐现象。对齐与否应该取决于突发传输的宽度,而不是总线位宽。
对于非对齐传输,主机会进行两项操作:
- 即使起始地址非对齐,也保证所有传输是对齐的
- 在首个 transfer 中增加填充数据,将首次传输填充至对齐,填充数据使用 WSTRB 信号标记为无效。
outstanding:
axi协议允许地址信息应用在实际数据传输之前,支持多个未解决的事务,支持乱序事务。地址和数据的分离,outstanding及乱序的存在都是为了提升效率。
在主机向从机读数据过程中,会先握手,从机向主机发送准备好被读信号(arready),主机检测到从机准备好被读了,向从机发送arid、arvalid,araddr信号,从机接收到读请求后返回rvalid和rdata、rid等信号。若是主机没有接收到从机的读响应,此时能不能发下一笔读操作呢?
若一手交钱一手交货概无两佘,那一笔交易的发生,既受限于买方什么时候有需求,还受限于卖方什么时候有货,这样交易频率会大大受限,效率降低。
若主机在没有接收到读请求响应的情况下,可以继续发送多次读请求。这就类似于买方在没有收到货的情况下,继续向卖方下订单,在良好的信誉保证下,买方只要有需求,就敢向卖方下订单,卖方也会因此源源收到订单,工厂开足马力生产,再将生产的产品发回给卖方。相较于一手交钱一首交货方式明显提高了效率。买方提交了的订单而卖方还没来得及返回给买方相应的产品,这些订单就是未解决的,outstanding。买方在提交订单的时候同时要付款,资金池耗尽的时候,就不能再向卖方提订单买货。买方能够承担多少卖方未返回产品的订单,就是在途的,最大流水深度。
因此,outstanding适用于有反馈的接口协议,在axi协议中,主机向从机写,从机需要向主机发写响应,主机向从机读,从机需要向主机发读响应。
如何测买方资金池(最大流水深度)?不给买方提供产品。对应在axi上,主机发出读请求时,不返回rlast,主机检测不到rlast信号,也就认为没有收到一次返回。
Burst可以减少地址通道的交互,提升单笔传输的效率,Outstanding可以较少多笔传输之间的等待,提升多笔传输的效率。
out of order:
Out-of-order传输可针对于多个从机,返回的response可以不按照master访问的顺序,慢的可以快,快的可以慢。如果master要求返回的数据必须按照他们访问的顺序来返回,则必须使用相同的ID。如果master不要求按顺序返回数据,则可以通过使用不同的ID来实现乱序传输。 也就是说乱序不乱序的实现是通过master的访问ID来进行控制的,同一个ID必须按照顺序,不同ID可以乱序。
由上图的例子可见(略去握手信号),当slave连续收到ARID分别为ID0和ID1的读请求,由于未知原因,对ID1的响应速度比对ID0更快,slave可以先返回RID为ID1的读数据,再返回RID为ID0的读数据。读乱序机制可以提高总线的性能。如果严格保序,RID为ID1的读数据需等到ID0的读数据都返回之后才可返回,明显造成了性能的浪费。
其中读乱序的深度由read data reordering depth决定,代表slave中允许pending的adress个数。当read data reordering depth = 1时代表不允许读乱序。
Interleaving:
交织(交叉)传输,是在乱序的基础上支持不同ID间数据之间的乱序。但是相同ID的数据还是顺序返回的,不同ID之间才会有交织传输。 在axi3中支持写交织,axi4/5去掉了wid,不支持写交织。
如图所示,slave在返回了一个RID为ID2的读数据后,中间间插返回了ID0与ID1的读数据,最后才返回一个的ID2的读数据。但同一RID的读数据之间需要保序。由此可见,在读交织机制下,同一个transaction中间插了来自其他transaction的transfer,所以乱序的粒度是transfer级的。
out of order与interleaving的区别在于前者是transaction粒度的乱序,而后者是transfer粒度的乱序,可以说后者是前者的一种实现方式。
4KB 边界:
协议中规定单次 burst 传输中的数据,其地址不能跨越 4KB 边界。4K边界是指低12bit为0的地址。以32位地址为例,[31:12]相等的地址都是同一个page,没有跨4K边界。 即[11:0] 可以为0~0xFFF. 例如0x1000和0x2000就是在不同的page,跨了4K边界。0x1000和0x1FFF则是在同一个page,没有跨4K边界,0x1FFF和0x2000则跨了4K边界,虽然他们是相邻的byte。 一个burst即使没有4K大小,但是如果起始地址是0x1FFC等靠近边界地址, INCR模式,就会跨边界。协议之所以规定一个burst不能跨越4K边界,是为了避免一笔burst交易访问两个slave(每个slave的地址空间是4K/1K对齐的)假如一个burst交易访问了两个slave A 和B(A在前B在后),那么只有A收到了地址和控制信息,而B不会收到地址和控制信息,因此只有A响应B并无响应,这就会导致此笔burst交易无法完成。
原子操作:用来说明不可分割的操作。AXI的原子操作包括exclusive和lock两种,不管是exclusive还是lock操作,在执行期间不可被其它操作打断,否则操作失败。
用于保证某一过程段内只有一个master对slv的某个地址享有控制权。
exclusive的应用场景主要是处理器需要对某个内存地址进行写操作时,假如写一个字节,而内存的数据位宽大于一个字节,比如32bit,这时处理器需要将内存地址对应的32bit数据先读出来,然后将要写入的一个字节数据进行更新后,再将更新后的32bit数据重新写入内存中去,该过程通常被业内称为读改写操作(RMW)。
但是实际芯片中,在CPU将数据读回,并将更新数据写回内存期间,可能会有其它的master也会访问内存,假如DSP将地址0的数据改成了0xff,那么内存中地址0应该保存的正确数据就应该是0xff,但是CPU由于操作延时,又将地址0的数据改成了0x0,这个时候DSP以为地址0里的数据是0xff,但实际上却是0x0,就无法保证数据的一致性。
于是就引入了exclusive操作。CPU要改写内存中数据,会先发一笔exclusive的读操作,此时内存作为slave,slave中会有一个monitor记录这笔exclusive读操作的地址和ID,然后返回EXOK,表示其支持exclusive操作,否则返回OK,代表不支持exclusive操作,在此情况下CPU收到OK就知道内存不支持exclusive操作。假如内存支持exclusive操作,则CPU收到EXOK后会继续发一笔exclusive写操作,将更新后的数据写回内存中。在此过程中如果内存的地址0x0~0x3没有被别的master访问过,则slave返回EXOK,代表此次exclusive操作(一次exclusive操作包含exclusive读和exclusive写)被正确执行;
假如在exclusive读和写之间,内存的这个地址被其它master访问过,如DSP将内存地址改写了,则slave返回OK,且此笔写操作不会被执行(如果执行会出现上边提到的数据一致性问题)。CPU收到OK的响应后就知道此次exclusive失败了,即写操作没写进去。此时CPU可以选择再次发起一次exclusive操作,继续对内存进行改写。
相对exclusive来说,lock操作比较简单,master发出lock操作后,interconnect要保证在lock期间只有此master能获得总线使用权,且lock操作的最后一笔transaction要将AXlock拉低,以此解除lock状态,最后一笔unlock操作结束后,其它的master才可以获得总线使用权,说白了就是我发出lock操作后,其他人不能打断我。
相比exclusive操作,lock操作会降低总线的利用率,而且影响QOS的使用,外加应用场景并不多,在AXI4中已经删除了lock操作。
混合大小端:
大端:高字节(MSB)应该存在低地址
小端:低字节(LSB)应该存在低地址
为了能够使大小端模式在存储中共存,AXI 协议设计了一种字节顺序恒定(Byte-invariant)的大小端传输方案。对于存储中包括多个字节的数据结构(单字节自然不存在大小端问题):
无论大小端模式,每个数据结构存储空间的分配方式是相同的
该数据结构按照其大小端模式决定字节存储的地址顺序
在传输过程中不考虑数据结构的大小端,按照字节原先存储的顺序,原样传输并存放至对端
该模式的意义在传输双方均不对数据结构的大小端进行解析转换,而严格按照字节的存储顺序进行传输并转存,防止大小端共存产生数据覆盖。
cache:
AXI协议,无论是握手还是突发传输,其实默认的都是主设备(如CPU Core)和从设备直接相连。但是实际情况中,主设备还需要通过分层存储的形式连接在Cache上,那么通过AXI协议读取的数据是应该在Cache上还是应该在外存上,通过AXI 写回的数据是应该写回在Cache上还是应该在外存上。
Cache是一种存储介质,一般介于CPU和主存之间。cpu速率提升,但访问主存的速度很慢。得益于数据一致性,将host常用的数据存放到cache中,而不用再访问主存,从而提高速率。
cahce一般也分为多层,每个cpu核都有L1和L2,L3是所有cpu核共享的。
Cache的读行为:
若hit:说明可以在Cache中找到对应地址的数据,直接从Cache中读取数据即可。
若miss,处理方式区分如下:
①Read through: 从slave中读取数据,但是不缓存到Cache处。
②Read allocate:从slave中读取数据,同时缓存到Cache处。
两种方式区分的条件是看数据的价值(是否被经常访问)。若被经常访问,则放到cache。
Cache的写行为与读行为相似:
若hit,说明可以在Cache 找到对应地址 以及这个地址所对应的数据,那么出现了两种情况的区分
①Write through: 把数据同时写到Cache和内存中
②Write back:先把数据写到Cache中,再通过flush方式写到内存中
若miss:
Write allocate: 先把要写的地址和其所对应的地址块载入到Cache中,再write through or write back。
No write allocate:直接把要写的数据写入到内存中而不经过Cache。
flush是Cache的一种指令,目的是在保留Cache中数据的前提下,将Cache的数据写回到主存中,这里的先Cache后flush相当于把一步操作拆成了两步操作(flush这种操作可能会造成在某些特定情况下,同一个地址Cache中的数据和外存中的数据不一致)。
文章部分参考以下链接
原文链接:https://blog.csdn.net/qq_41554005/article/details/125985849