一. INCR Burst Type
我们先来看一张wdata排布图,灰色单元表示该Byte没有被传输。
我们先来讲几个前提变量:
Start_Address:表示的是一笔transaction的起始地址,它等于AxADDR。
Number_Bytes:表示1个transaction中每笔data transfer的最大byte数,它等于2 ^ AxSIZE。
Data_Bus_Bytes:表示data bus的byte宽度,也就是在实现中定义好的物理最大宽度了,比如我说某个AXI master的data bus宽度是8Byte,这个8Byte就是Data_Bus_Bytes。
Aligned_Address:它是Start_Address根据Number_Bytes做对齐之后的值,也就是Aligned_Address = (INT(Start_Address / Number_Bytes)) × Number_Bytes。
Burst_Length:它表示在transaction中会burst传输多少笔data transfer,它的计算公式Burst_Length = AxLEN + 1。
Address_N:它表示在一次burst传输第几笔transfer的地址,比如N=1,那么表示burst传输中的第1笔transfer。对于第1笔transfer,Address_1等于Start_address。INCR burst之后的Address_N计算公式为:Address_N = Aligned_Address + (N – 1) × Number_Bytes。
Lower_Byte_Lane:表示1笔transfer最低address的Byte通道。
Upper_Byte_Lane:表示1笔transfer最高address的Byte通道。
INT(x):表示x的向下取整数值。
现在我们来分析上面的wdata排布图,由图可以得出:
-
Start_Address=0x07, Number_Bytes=4Byte, Data_Bus_Bytes=8Byte,
Aligned_Address=0x4, Burst_Length=0x4 -
Address_1=0x07,Address_2=0x08,Address_3=0x0C,Address_4=0x10
接下来Lower_Byte_Lane和Upper_Byte_Lane的计算公式为:
如果是第1笔transfer,那么
- Lower_Byte_Lane = Start_Address – (INT(Start_Address /
Data_Bus_Bytes)) × Data_Bus_Bytes - Upper_Byte_Lane = Aligned_Address + (Number_Bytes – 1) –
(INT(Start_Address / Data_Bus_Bytes)) × Data_Bus_Bytes
如果不是第1笔transfer,那么
- Lower_Byte_Lane = Address_N – (INT(Address_N / Data_Bus_Bytes)) ×
Data_Bus_Bytes - Upper_Byte_Lane = Lower_Byte_Lane + Number_Bytes – 1
所以结合以上公式,我们可以算出4笔transfer的Upper_Byte_Lane和Upper_Byte_Lane为:
- 1st transfer:Upper_Byte_Lane = 7,Lower_Byte_Lane = 7;
- 2nd transfer:Upper_Byte_Lane = 3,Lower_Byte_Lane = 0;
- 3rd transfer:Upper_Byte_Lane = 7,Lower_Byte_Lane = 4;
- 4th transfer:Upper_Byte_Lane = 3,Lower_Byte_Lane = 0;
其实Upper_Byte_Lane和Lower_Byte_Lane的数值就代表在data channel占据第几字节,比如Lower_Byte_Lane=0,表示最低的0字节。因为每1笔data transfer的data只能在data channel的DATA((8 × Upper_Byte_Lane) + 7: (8 × Lower_Byte_Lane))之间传输,所以至此也就能解释数据为什么是这样排布了。
二. 扩展到 WRAP Burst Type
这里需要额外介绍一个变量叫做Wrap_Boundary。
Wrap_Boundary:表示WRAP burst传输的最低address,它的计算公式Wrap_Boundary = (INT(Start_Address / (Number_Bytes × Burst_Length)))× (Number_Bytes × Burst_Length)。
扩展到WRAP burst的话,其实也类似的,只是WRAP的Address_N计算起来和INCR有点不一样,它涉及到绕回。我们再以一张Wrap burst传输图为例顺便说下,灰色单元表示该Byte没有被传输。
由图可以得出:
- Start_Address=0x04,Number_Bytes=4Byte,Data_Bus_Bytes=8Byte,Aligned_Address=0x4,Burst_Length=0x4
根据AXI spec,Wrap传输的Address_N计算公式定义为:
如果WRAP传输刚开始,还没有到达边界,Address_N=Aligned_Address + (N – 1) × Number_Bytes。如果WRAP传输的Address_N等于Wrap_Boundary + (Number_Bytes × Burst_Length),那么当前transfer的Address_N会用Wrap_Boundary传输
之后transfer的Address_N为Start_Address + ((N – 1) × Number_Bytes) – (Number_Bytes × Burst_Length)
所以这个WRAP burst的Address_N为:
- Address_1=0x04,Address_2=0x08,Address_3=0x0C,Address_4=0x0
虽然Address_N的计算公式和INCR burst不一样,但是Upper_Byte_Lane和Upper_Byte_Lane的计算公式是一样的。我们可以算出4笔transfer的Upper_Byte_Lane和Upper_Byte_Lane为:
- 1st transfer:Upper_Byte_Lane = 7,Lower_Byte_Lane = 4;
- 2nd transfer:Upper_Byte_Lane = 3,Lower_Byte_Lane = 0;
- 3rd transfer:Upper_Byte_Lane = 7,Lower_Byte_Lane = 4;
- 4th transfer:Upper_Byte_Lane = 3,Lower_Byte_Lane = 0;
三. 结论
不管是WRAP传输,还是INCR传输,其实Upper_Byte_Lane和Lower_Byte_Lane的计算公式是一样的,我们在平时可以不用套用这么多公式去计算,太麻烦了。我们其实根据Data_Bus_Bytes,Number_Bytes和Start_Address就可以大致心算出write data在data bus上是如何排布的了。是这样的:
- 先用Data_Bus_Bytes去把address空间划分为很多子空间,每段子空间大小为Data_Bus_Bytes。
- Number_Bytes把address空间划分为很多更小的子空间,每段子空间大小为Number_Bytes。每段子空间的最大值称为Number_Bytes的最大边界,每段子空间的最小值称为Number_Bytes的最小边界。
- Start_Address%Data_Bus_Bytes的结果(余数)就是第1笔transfer的Lower_Byte_Lane,Upper_Byte_Lane的取值肯定在达到第一个Start_Address落在的Number_Bytes子空间的最大边界处。
- 之后的transfer就以此类推下,其实就是以Number_Bytes大小的窗口在address上平移。