目录
一、burst type 基本概念
基于AXI4 协议规范,axi burst type支持的类型有如下三种, 其中当burst type取值为2'b11,为reserved情况
1.1. fixed模式
这时对于一笔burst中的每个transfer对应的地址均为固定值, 这种burst type 多用于对相同位置的重复访问,例如加载或清空FIFO。
1.2. INCR模式
对于burst type 值为2'b01时, 为INCR模式, 这时对于一笔burst中的每个transfer对应的地址位依次递增,递增的值与每个transfer的size有关,这种burst type 多用于访问正常的顺序存储器。
1.3. wrap模式
对于burst type 值为2'b10时, 为wrap模式, 这时对于一笔burst中的每个transfer对应的地址有上限和下限的限制,在这个限制范围之内,每个transfer对应的地址也是递增的关系,这种burst type多用于cache line 访问(如MCU), 但是需要注意的是
-
起始地址必须与每次传输的大小对齐
- burst length 的取值必须是2,4,8,16
二、地址计算公式
2.1. 地址相关概念
那么如何计算burst type为INCR和wrap两种情况下每笔burst中每个transfer对应的地址?
首先需要明确如下几个概念
-
start_address: master发出的每笔burst的首地址
-
number_bytes: 每个transfer传输的最大数据量,以byte计
-
burst_length: 在一笔burst中,包含的transfer的数量
-
address_n: 一笔burst中的第n个transfer对应的地址,对于第一个transfer,对应的地址为address_1,对于第n个transfer,对应的地址为address_n
-
aligned_address: 起始地址的对齐版本
-
wrap_boundary: 当burst type为wrap时,一笔burst的地址下界,(为便于理解,后续计算将其定义为wrap_floor)
-
wrap_celling: 当burst type为wrap时,一笔burst的地址上界
-
int(x): 对x向下取整
下面给出上述提及概念的具体计算公式
-
start_address = AxADDR
-
number_bytes = 2 ^ AxSIZE
-
burst_length = AxLEN + 1
-
aligned_address = (int(start_address / number_bytes)) * number_bytes
基于burst type 为INCR和wrap两种情况,对于第n个transfer地址的计算规则如下
2.2. INCR burst 地址计算:
address_1 = start_address = AxADDR(起始地址可以不对齐)
address_n = aligned_address + (n-1)*number_bytes
2.3. WRAP burst 地址上下界及地址计算
wrap_floor = (int(start_address / (number_bytes * burst_length))) * (number_bytes * burst_length) (起始地址需要对齐)
wrap_celling = wrap_floor + (number_bytes * burst_length)
因此对于wrap burst, 一笔burst中的每个transfer的地址取值范围为 wrap_floor<=address_n<wrap_celling
-
对于第1个transfer,即address_1 = start_address;
-
对于第n个transfer,address_n = address_n-1 + number_bytes == wrap_celling ? wrap_floor : address_n-1 + number_bytes; 即第n个transfer的地址按照INCR burst计算出来后,如果值和wrap_celling 相等,那么第n个transfer的地址则需要绕回到wrap_floor, 如果不等,则地址继续递增
三、详细示例
3.1. 起始地址对齐
一笔burst(无论读写)的起始地址为AxADDR = 0x30,AxLEN = 3, AxSIZE = 4
3.1.1 INCR burst
number_bytes = 2^4 = 16
burst_length = 3 + 1 = 4
aligned_address = 0x30(起始地址对齐)
address_1 = start_address = 0x30
address_2 = aligned_address + (2 - 1) * 16 = 0x30 + 16 = 0x40
address_3 = aligned_address + (3 - 1) * 16 = 0x30 + 32 = 0x50
address_4 = aligned_address + (4 - 1) * 16 = 0x30 + 48 = 0x60
3.1.2 wrap burst
number_bytes = 2^4 = 16
burst_length = 3 + 1 = 4
aligned_address = 0x30(起始地址对齐)
wrap_floor = (int(0x30 / (16 * 4))) * (16 * 4) = int(0x30 / 0x40) * 0x40 = 0x00
wrap_celling = 0x00 + (16 * 4) = 0x40
address_1 = start_address = 0x30
address_2 = address_1 + 16 == 0x40 ? 0x00 : address_1 + 16 = 0x00(address_1 + 16 = 0x40)
address_3 = address_2 + 16 = 0x10
address_4 = address_3 + 16 = 0x20
3.2. 起始地址非对齐
一笔burst(无论读写)的起始地址为AxADDR = 0x32,AxLEN = 3, AxSIZE = 4
3.2.1 INCR burst
number_bytes = 2^4 = 16
burst_length = 3 + 1 = 4
aligned_address = (int(0x32 / 16)) * 16 = 3 * 16 = 0x30
address_1 = start_address = 0x32
address_2 = aligned_address + (2 - 1) * 16 = 0x30 + 16 = 0x40
address_3 = aligned_address + (3 - 1) * 16 = 0x30 + 32 = 0x50
address_4 = aligned_address + (4 - 1) * 16 = 0x30 + 48 = 0x60
参考文献
[1] AMBA® AXI and ACE Protocol Specification