1.AXI传输层级概念
在手册的术语表中,与 AXI 传输相关的有三个概念,分别是 transfer(beat)、burst、transaction。用一句话串联就是:
在 AXI 传输事务(Transaction)中,数据以突发传输(Burst)的形式组织。一次突发传输中可以包含一至多个数据(Transfer)。每个 transfer 因为使用一个周期,又被称为一拍数据(Beat)。
再展开一层,两个 AXI 组件为了传输一组数据而进行的所有交互称为 AXI Transaction,AXI 传输事务(所以会有写事务和读事务),包括所有 5 个通道上的交互。
- AXI传输事务Transaction
- AXI突发 Burst
- AXI传输 Transfer / Beat(使用一个周期)
- AXI突发 Burst
AXI 是一个 burst-based 协议,AXI 传输事务中的数据传输以 burst 形式组织,称为 AXI Burst。每个传输事务包括一至多个 Burst。每个 Burst 中传输一至多个数据,每个数据传输称为 AXI Transfer。双方握手信号就绪后,每个周期完成一次数据传输,因此 AXI Transfer 又被称为 AXI beat,一拍数据。不严谨地说
AXI Transaction =M*AXI Burst ,M >= 1
AXI Burst = N * AXI Transfer(AXI beat) ,N >= 1
和上述概念相关的信号是AXLEN、AXSIZE、AXBURST。这三个信号均由主设备发出。
突发传输长度
AXLEN[7:0]定义突发传输长度
表示一次突发传输(Burst)中包含的数据传输(transfer)数量。
协议中的 AxLen 信号从零开始表示,实际的长度值为 AxLen + 1。
突发传输长度在不同的模式(burst type ,将在后文中讨论)下有一些限制,包括:
对于 WRAP 模式,突发传输长度仅能为2,4,8,16
在一次突发传输中,地址不能跨越一个 4KB 分区
一次突发传输在完成所有数据传输前不能提前结束(early termination)
协议中多次强调,通信双方都不能在传输事务的所有 Transfer 完成前提前结束。哪怕发生错误,也得含泪走完整个传输事务的流程。
但是主机也有办法减少传输的数据。在写传输事务中,发送方可以通过置低所有的写有效位,使写数据无效。在读传输事务中,主机可以直接丢弃读取到的数据。
突发传输位宽
AXSIZE[2:0]定义突发传输transfer的位宽
表示每个beat周期传输数据的字节数/每拍传的数据位宽
每拍传的数据位宽 = 2AXSIZE
突发传输类型
AXBURST[1:0]定义突发传输类型
FIXED 类型中, burst 中所有数据都使用起始地址。该模式适合对某个固定地址进行多次数据更新,比如读写一个 fifo 时,读写地址就是固定的。
INCR 类型最为常用,后续数据的地址在初始地址的基础上进行递增,递增幅度与传输宽度相同。适合对于 RAM 等通过地址映射(mapped memory)的存储介质进行读写操作。
WRAP 类型比较特殊,首先根据起始地址得到绕回边界地址(wrap boundary)与最高地址。当前地址小于最高地址时,WRAP 与 INCR 类型完全相同,地址递增。但到递增后的地址到达最高地址后,地址直接回到绕回边界地址,再进行递增,就这样循环往复(通常用在cache的访问中)。最高地址由绕回边界地址计算得到:wrap boundary + (N_bytes x burst_len)
Wrap突发传输不支持AXI非对齐传输。
Wrap的特点:
起始地址必须与总传输数据大小对齐
突发传输长度仅能为2,4,8,16
数据总大小:一次突发中传输的数据总量 = 传输次数(AXLEN) * 单次传输大小(AXSIZE)
对齐:起始地址是数据总大小的整数倍
4K边界
要求一次AXI突发(Burst)传输不能跨越4K字节的地址边界,所谓的4K边界是指低12bit为0的地址,例如32'h00001000, 32'h00002000... 这些特殊的地址我们称之为4k边界;同理1k边界是指低10bit为0的地址,例如32'h00000400,32'h00000800...
例如:在Master_A设计中,假如Master_A只操作一块64M SDRAM(此Master_A不操作任何其他Slave),读写的数据量远远大于4K。因此其中某个Burst的操作可能 会出现在4K边界上,在这样的情况下,Master_A设计的Burst操作就需要考虑遵守4k边界的约定。
协议中之所以规定一个burst不能跨越4K边界是为了避免一笔burst交易访问两个slave(每个slave的地址空间是4K/1K对齐的)。如果一个突发跨越了4K边界,即从一个4K页面的末尾跳转到另一个页面的开始,那么它可能会尝试同时访问两个不同的slave设备,这会导致协议冲突和数据不一致性。(假如一个burst交易访问了两个slave A 和B(A在前B在后),那么只有A收到了地址和控制信息,而B不会收到地址和控制信息,因此只有A响应B并无响应,这就会导致此笔burst交易无法完成(B无法返回最后一笔transfer)。)因此如果你必须确定系统中所有slave中地址空间最小的那一个,假设是1M,这样你的burst边界可以大于4K至1M。但还是不建议这么做,毕竟一个burst跨越4K边界的概率还是较低的,如果真的跨越了就拆分。
4K对齐最大原因是系统中定义一个标准页大小是4K字节。这是因为许多系统中,物理内存被划分为4K字节大小的页。所以,为了更好的设定每个slave的访问attribue,就给一个slave划分4K空间。 4K对齐,以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模式,就会出现跨4k边界的问题, 1K对齐,就是说 [31:10]相等的地址都是在一个1K对齐的空间内。
主机每一次写突发或者读突发传输,地址偏移量(或叫地址增加量),不能超过4K,也不能跨域4K。4K=4096。
举个例子:数据位宽m_axi_wdata=128bit,突发长度为100。可以计算出突发长度的字节数量:128÷8×100=1600。
第一次:突发开始的地址是0,结束地址(最后一个字节的地址)是1599。axi总线规定一个字节对应一个地址。
第二次:突发开始的地址是1600,结束地址(最后一个字节的地址)是3199。axi总线规定一个字节对应一个地址。
第三次:突发开始的地址是3200,结束地址(最后一个字节的地址)是4799。axi总线规定一个字节对应一个地址。这个就有问题了,地址超过了4096(4k)
如下图,4k区间即0-4095,或者4096-8191,读写的时候不能跨越4k区间
如果真的跨越了4k边界地址,就将该次burst进行拆分,分为两次burst传输。例如处理器load多个数据,就是跨页访问,到了接口控制模块,也会把这一个访问拆分成两个访问。在interfere上的都是符合协议的transaction。例如,core要访问0x1FF0-0x200C共32byte的数据(每次beat 4B,4byte对齐的,所以是1FFC。1FF0,1FF4,1FF8,1FFC,4*4byte = 16byte)。系统会自动给拆分成0x1FF0-0x1FFC和0x2000-0x200C两个transaction。
ARM对AHB burst这样设计的目的是在于,SLAVE的地址访问空间基本都是以1KB为单位的,当AHB以burst方式传输时,为了避免错误的访问到其他的Slave空间而造成系统致命错误,因此在burst传输时限制1KB,若需要跨1KB边界时,需要重新initial一个新的传输。
在AHB划分系统时,最小的地址空间为1KB,即slave至少地址空间是1k,或者2K,或者1M等。这样,当AHB访问地址空间时,因为地址空间对其的原因,就不会恶意的访问到其他的地址空间。
cpu发出这样的请求时,AHB会自动的将其转换为1KB,1KB的传输格式,可以根据其地址区间是否跨越对齐的000来判断。
计算最大的突发长度
计算公式:最大的突发长度发=4096÷(axi数据位宽÷8)。
1)m_axi_wdata=128bit:可以计算出最大突发长度:4096/(128÷8)=256。4096是4k边界,128÷8为字节数
2)m_axi_wdata=256bit:可以计算出最大突发长度:4096/(256÷8)=128。
3)m_axi_wdata=512bit:可以计算出最大突发长度:4096/(512÷8)=64。
4)m_axi_wdata=64bit:可以计算出最大突发长度:256。按照上面的计算的话4096/(64÷8)=512,但是axi总线规定突发长度在0到256之间,所以此时最大只能是256
如何避免4k边界
1)如果突发长度固定,每次突发的地址偏移量可被4096整除,比如axi4写数据位宽为128bit,突发长度为128,则地址偏移量:128*(128/8)=2048。4096÷2048=2,地址偏移量可以被整除,这可以避免跨越4k边界。地址偏移量就是结束地址减去起始地址。
2)如果突发长度不固定,可以给每次突发分配4k地址空间。
假设数据位宽m_axi_wdata=128bit。第一次突发长度为100,起始地址是0,结束地址是128/8*100 - 1=1599。第二次突发长度是200的话,起始地址是1600,结束地址是1600+(128/8 * 200)-1=4799,此时跨越了4k边界,会出现错误。为了避免跨越4k边界,可以在第二次时,初始地址给4096,那么结束地址就是4096+(128/8 * 200)-1=7295。同理,第三次突发时,起始地址可以从8192开始。