深入AXI4总线-[三]传输事务结构
知乎用户
ljgibbs
授权转发
本系列我想深入探寻 AXI4 总线。不过事情总是这样,不能我说想深入就深入。当前我对 AXI总线的理解尚谈不上深入。但我希望通过一系列文章,让读者能和我一起深入探寻 AXI4。
声明1:部分时序图以及部分语句来自 ARM AMBA 官方手册
(有的时候感觉手册写得太好了,忍不住就直接翻译了。。)
声明2:AXI 总线是 ARM 公司的知识产权
备注:
-
下载手册可以到ARM官网搜AMBA ,需要注册 ARM 账号。官方手册developer.arm.com
-
百度文库应该有中文翻译版本。
Burst-based 的 AXI 协议
Burst,单词本身有爆炸、释放之意,可引申为突发之意。
那么在数据传输的范畴中,就使用 burst 来表示一种传输模式:在一段时间中,连续地传输多个(地址相邻的)数据。此时可译为突发传输或者猝发传输。
在手册的术语表中,与 AXI 传输相关的有三个概念,分别是 transfer(beat)、burst、transaction。用一句话串联就是:
在 AXI 传输事务(Transaction)中,数据以突发传输(Burst)的形式组织。一次突发传输中可以包含一至多个数据(Transfer)。每个 transfer 因为使用一个周期,又被称为一拍数据(Beat)。
再展开一层,两个 AXI 组件为了传输一组数据而进行的所有交互称为 AXI Transaction,AXI 传输事务,包括所有 5 个通道上的交互。
AXI 是一个 burst-based 协议,AXI 传输事务中的数据传输以 burst 形式组织,称为 AXI Burst。每个传输事务包括一至多个 Burst。每个 Burst 中传输一至多个数据,每个数据传输称为 AXI Transfer。我们 通过深入AXI4总线(一)了解到,双方握手信号就绪后,每个周期完成一次数据传输,因此 AXI Transfer 又被称为 AXI beat,一拍数据。不严谨地说
AXI Transaction =M*AXI Burst ,M >= 1
AXI Burst = N * AXI Transfer(AXI beat) ,N >= 1
所以本章我们就将跟着协议手册,从地址、数据以及回复总线上的传输事务结构,来了解 AXI 的整体传输事务结构
传输事务结构(Transaction structure)
读写地址结构
在整个传输事务过程中,主机首先将接下来 burst 传输的控制信息以及数据首个字节的地址传输给从机,这个地址被称为起始地址。在本次 burst 后续传输期间,从机将根据控制信息计算后续数据的地址。
控制信息以及起始地址在读/写地址通道(AWC/ARC)传输。
注意:单次 burst 传输中的数据,其地址不能跨越 4KB 边界。
关于这点在笔者参考的一个来源这样表示,目前笔者觉得看上去很有道理:
协议中之所以规定一个burst不能跨越4K边界是为了避免一笔burst交易访问两个slave(每个slave的地址空间是4K/1K对齐的)
4K对齐最大原因是系统中定义一个page大小是4K,而所谓的4K边界是指低12bit为0的地址。
详情转至参考来源:
关于axi协议里面burst的4k问题_KeepFighting!-CSDN博客blog.csdn.net
地址通道中传输的控制信息中包括三项突发传输相关的信号(AR/AW 均一致,下图为以 AR 为例):
(1)突发传输长度 (burst length),指一次突发传输中包含的数据传输(transfer)数量,在协议中使用 AxLen 信号控制。
在 AXI4 中,INCR 类型最大支持长度为 256,其他类型最大长度为 16。而 AXI3 中这一数字无论何种模式均为 16。因此 AXI4 中 AxLen 信号位宽为 8bit,AXI3 中的 AxLen 则仅需要 4bit。
当然突发长度至少为 1,不然也就没有传输发生了。
协议中的 AxLen 信号从零开始表示,实际的长度值为 AxLen + 1。
突发传输长度在不同的模式(burst type ,将在后文中讨论)下有一些限制,包括:
- 对于 WRAP 模式,突发传输长度仅能为2,4,8,16
- 在一次突发传输中,地址不能跨越一个 4KB 分区
- 一次突发传输不能在完成所有数据传输前提前结束(early termination)
协议中多次强调,通信双方都不能在传输事务的所有 Transfer 完成前提前结束。哪怕发生错误,也得含泪走完整个传输事务的流程。
但是主机也有办法减少传输的数据。在写传输事务中,发送方可以通过置低所有的写有效位,使写数据无效。在读传输事务中,主机可以直接丢弃读取到的数据。
(2)突发传输宽度(burst size),指传输中的数据位宽,具体地,是每周期传输数据的字节数量,在协议中使用 AXSIZE 信号控制。
自然地,突发传输数据宽度不能超过数据总线本身的位宽。而当数据总线位宽大于突发传输宽度时,将根据协议的相关规定,将数据在部分数据线上传输。
突发传输宽度信号 AXSIZE 位宽为 3bit,表示为:
传输宽度 = 2 ^ AXSIZE
(3)突发传输类型(AxBURST),类型共有 3 种,分别为 FIXED,INCR 以及 WRAP。使用 2 位二进制表示。
FIXED 类型中, burst 中所有数据都使用起始地址。该模式适合对某个固定地址进行多次数据更新,比如读写一个 fifo 时,读写地址就是固定的。
INCR 类型最为常用,后续数据的地址在初始地址的基础上进行递增,递增幅度与传输宽度相同。适合对于 RAM 等通过地址映射(mapped memory)的存储介质进行读写操作。
WRAP 类型比较特殊,首先根据起始地址得到绕回边界地址(wrap boundary)与最高地址。当前地址小于最高地址时,WRAP 与 INCR 类型完全相同,地址递增。但到递增后的地址到达最高地址后,地址直接回到绕回边界地址,再进行递增,就这样循环往复。最高地址由绕回边界地址计算得到:wrap boundary + (N_bytes x burst_len)
根据协议手册上表示,WRAP 适合对 cache 的访问,不过目前笔者在这方面的经验还不多,后续有机会再讨论。
地址计算参考
手册在章节 A3 详细给出了不同的突发传输模式下的地址计算公式与伪代码,有相关需求的读者可以参看这一部分。
读写数据结构
在 AXI 数据传输过程中,主要涉及到窄位宽数据传输(Narrow Transfer)、非对齐传输(Unaligned Transfer)以及混合大小端传输(mix-endianness)等问题。
(1)Narrow Transfer
当本次传输中数据位宽小于通道本身的数据位宽时,称为窄位宽数据传输,或者直接翻译成 窄传输。
在窄位宽写传输中,主机需要告知从机数据通道中哪些字节是有效的,需要使用到写数据通道中的 WSTRB 信号。WSTRB 信号中的单个 bit 置起,表示对应位置上的字节有效,对应关系为:
WSTRB[n] 对应 WDATA[8n+7:8n],也就是:当 WSTRB[n] 为 1 时,WDATA[8n+7:8n]有效。
WSTRB 信号比特位宽等于数据通道位宽的字节数量,比如 32bit 位宽的数据通道,对应 WSTRB 信号位宽为 4bit。
对应于下图的情况中,灰色的部分代表数据无效,第一次的传输中低地址第一字节有效,其他数据无效的 ,WSTRB 信号为 0x01,WSTRB [0] 为 1,即 WDATA[7:0] 有效。
我们接着上图继续说,上图中的窄位宽传输有以下几个特点:
- burst 传输长度为 5
- burst 传输位宽为 8bit
- 起始地址为 0x0
- 数据总线位宽为 32bit
- 突发类型为 INCR
从图中我们发现,在每次数据传输中使用的数据总线字节位置(byte line)不同,尽管数据以字节为单位,分为多个周期传输,但是数据的位置仍与其地址对应。D[7:0]将写入起始地址 0x0,故位于最低字节。D[15:8] 将写入地址 0x1,故位于次低字节。
个人理解该设计的意义在于,当主机是因为从机或者其他客观条件限制,需要进行窄传输时,可以一次性将数据放置于数据总线上,只需在每次传输期间改变 WSTRB 信号即可。以上图为例,主机将 D[31:0] 防置于总线,在接下来的四个周期中,仅需对 WSTRB 进行移位,即可依次完成 4 个字节的传输。
该结构有利于 memory 类型的从机进行写入处理,这里设想一种实现方式,结合下图讲解,在 64bit 位宽的总线上进行 32bit 位宽传输,起始地址为 0x4 。此时假设存储介质位宽与总线位宽一致,为 64 bit。
在 transfer 1st 中,从机获取整个总线上的 64bit 数据存储至存储介质中,比如 DDR,并利用 wstrb 作为 mask 信号屏蔽无效的低 32 bit(比如 DDR 的 DQM 信号)。这时候存储介质的写入地址为 0x0,但实际只从地址 0x4 开始写入了 32bit 数据。在后续的 transfer 继续按以上模式工作。
窄传输中通过主机来调整有效数据的字节位置,以及给出字节有效信号 WSTRB,能够使从机无需进行数据重组等工作。
注意:协议未规定窄传输中从机的具体实现,这里举了一个设想的例子,后续需要结合窄传输的用途再研究考证
在读传输中,从机的操作逻辑与写传输中的主机相同,但是从机没有类似 WSTRB 的信号。所以需要主机根据突发传输宽度与总线位宽,计算当前总线中有效数据所在字节位置,读取数据。
协议规定在 INCR 和 WRAP 模式中每次使用的 byte line 必须不同,即数据位置与地址对应。而在 FIXED 模式中,整个传输过程使用相同的 byte line(地址反正 FIXED 不会变)。
(2)Unaligned Transfer
AXI 协议支持地址非对齐的传输,允许突发传输的首字节地址,即起始地址与突发传输位宽不对齐。举个例子,总线位宽为 32bit 时,如果起始地址为 0x1002 ,则产生了非对齐现象。与 32bit 位宽总线对齐的地址需要能被 4 整除,即 ADDR[1:0] = 2'b0。
注意:此处对齐与否应该取决于突发传输的宽度,而不是总线位宽。
传输不对齐怎么办,在线等,挺急的。
对于非对齐传输,主机会进行两项操作:
- 即使起始地址非对齐,也保证所有传输是对齐的
- 在首个 transfer 中增加填充数据,将首次传输填充至对齐,填充数据使用 WSTRB 信号标记为无效
我们通过几个例子来说明主机具体的工作:
例子1
起始地址为 0x1,非对齐,但主机通过添加一字节的填充数据将 transfer 1st 的实际地址调整为对齐的 0x0,并用 WSTRB 信号为 4'b1110 标识出最低字节上无效的填充数据。
在读传输中,从机也按照同样的原则,在读数据中填充无效数据实现对齐,由主机自行分离。
再举一个例子,例子2
我们惊讶地发现这个例子是窄传输+非对齐传输,但问题不大,我们根据之前的经验来看下。首先起始地址为不对齐的 0x07 ,所以首先将首个传输填充至与突发传输位宽 32 bit 对齐:
0x07 mod 4(byte) = 3 byte
至此非对齐的问题就已经解决了。接下问题就简化为窄传输。图 7 中 32bit 数据在 64bit 总线上传输,根据我们上一节的分析(见图5),在 transfer 1st 中 再填充 4 个字节。后续的 transfer 中则遵从窄传输的原则即可。
(3)Byte Invarience
我们来讨论数据传输结构三个问题中的最后一个:混合的大小端模式。首先我们知道内存中有 2 种大小端模式,就像甜咸两党一样,争论的是宇宙的终极奥义问题:
数据的高字节是存在低地址中还是存在高地址中。
大端认为:高字节(MSB)应该存在低地址,而小端认为低字节(LSB)才应该存在低地址。
那么为了能够使大小端模式在存储中共存,AXI 协议设计了一种字节顺序恒定(Byte-invariant)的大小端传输方案。对于存储中包括多个字节的数据结构(单字节自然不存在大小端问题):
- 无论大小端模式,每个数据结构存储空间的分配方式是相同的
- 该数据结构按照其大小端模式决定字节存储的地址顺序
- 在传输过程中不考虑数据结构的大小端,按照字节原先存储的顺序,原样传输并存放至对端
该模式的意义在传输双方均不对数据结构的大小端进行解析转换,而严格按照字节的存储顺序进行传输并转存,防止大小端共存产生数据覆盖。
这个知识点将在涉及到具体问题时,再深入讨论。
读写回复结构
读写传输事务(Transaction)都存在 2bit 位宽的回复信号 RRESP/BRESP,分别存在 4 种回复情况,分别为
-
OKAY ,常规访问成功
-
EXOKAY,独占访问成功
-
SLVERR,从机错误,尽管从机接收到了访问请求,但因为种种原因向主机返回了一个错误状态,AXI 传输事务的回复由应用具体决定,可能包括以下错误场景:
-
- FIFO 或者缓冲区溢出
- 主机发起了不支持的传输位宽
- 尝试向读保护的地址写入数据
- 超时
-
DECERR,解码错误,一般由 interconnect 组件产生,表示主机发送的传输事务地址无效,无法将传输事务发送给某个从机。
注意:在写传输事务中,单个写回复针对的是整个 burst,而不是 burst 中单个 transfer。但是在读传输事务中,从机可以为突发传输中每一个读传输数据产生不同的读回复信号。