4. AXI突发传输:FIXED/INCR/WRAP突发类型、地址计算、突发长度与大小

大家好,我是你们的芯片验证工程师老友。今天咱们聊聊AXI总线里一个核心话题——突发传输。

说实话,我刚接触AXI协议那会儿,最头疼的就是这几种突发模式。FIXED、INCR、WRAP,光看名字就够绕的。但后来在实际项目中踩过几次坑,才真正搞明白它们各自的门道。

嗯,咱们今天就把这事儿彻底说透。

4.1 什么是突发传输?

突发传输,说白了就是一次握手,传一串数据。

你想想看,如果每次传一个数据都要走一遍地址握手,那效率得多低?AXI的突发机制就是让你只发一次起始地址,然后连续传多个数据。这在DMA搬运大块数据时特别有用。

我个人习惯把突发传输比作「快递小哥送货」:

  • 起始地址 = 小区门口
  • 突发长度 = 要送几栋楼
  • 突发大小 = 每栋楼送几个包裹
  • 突发类型 = 是按门牌号顺序送,还是绕圈送

这个比喻虽然糙,但道理不糙。

4.2 三种突发类型详解

4.2.1 FIXED 突发(固定地址)

FIXED模式,每次传输都访问同一个地址。

「什么情况下会用?」你可能会问。

我在项目中遇到过,比如往一个FIFO里连续写数据,或者操作一个状态寄存器。地址不动,数据一直往里塞。

地址计算规则:

每次传输的地址 = 起始地址(不变)

说白了就是:地址锁死,数据轮换。

举个实际例子:

起始地址:0x1000
突发长度:4
突发大小:4字节(32位)

传输顺序:
Beat 0 → 地址 0x1000,数据 D0
Beat 1 → 地址 0x1000,数据 D1
Beat 2 → 地址 0x1000,数据 D2
Beat 3 → 地址 0x1000,数据 D3

注意:我曾经在调试一个DMA搬运FIFO数据时,误把FIFO的读地址设成了INCR模式。结果每次读地址都递增,读到的全是垃圾数据。后来改成FIXED才搞定。这种坑,踩一次就记住了。

4.2.2 INCR 突发(递增地址)

INCR是最常用的模式。地址依次递增,适合搬运连续内存块。

比如从DDR里搬一段数据到另一个地址,或者从外设读数据到内存。我敢说,你写的AXI master里,90%的传输都是INCR。

地址计算规则:

第N次传输的地址 = 起始地址 + N × 突发大小

看个例子:

起始地址:0x1000
突发长度:4
突发大小:4字节

传输顺序:
Beat 0 → 地址 0x1000,数据 D0
Beat 1 → 地址 0x1004,数据 D1
Beat 2 → 地址 0x1008,数据 D2
Beat 3 → 地址 0x100C,数据 D3

这里有个细节要注意:地址递增的步长 = 突发大小,不是1。很多新手会搞混,以为地址每次加1。其实加的是字节数。

4.2.3 WRAP 突发(回卷地址)

WRAP模式,嗯,这个稍微有点绕。

它本质上也是递增,但到了边界就「卷」回起始地址。常用于Cache line的填充——你想想看,Cache line的大小通常是固定的,比如64字节。你从内存里读一个Cache line,地址到了边界就自动回卷,多方便。

地址计算规则:

WRAP的地址范围 = [起始地址, 起始地址 + 突发长度 × 突发大小)

地址递增到上边界后,回卷到下边界。

举个例子:

起始地址:0x100C
突发长度:4
突发大小:4字节
地址范围:0x100C ~ 0x101C(不包含0x101C)

传输顺序:
Beat 0 → 地址 0x100C,数据 D0
Beat 1 → 地址 0x1010,数据 D1
Beat 2 → 地址 0x1014,数据 D2
Beat 3 → 地址 0x100C(回卷!),数据 D3

我的经验:WRAP模式有两个限制:

  • 突发长度只能是2、4、8、16
  • 起始地址必须对齐到「突发长度 × 突发大小」的边界

我曾经在验证一个Cache控制器时,发现WRAP地址算错了。查了半天,原来是起始地址没对齐。从那以后,我写验证用例时都会特意检查地址对齐条件。

4.3 突发长度与突发大小

这两个参数是突发传输的「骨架」。

参数 含义 取值范围 说明
突发长度 一次突发中传输的数据个数 1 ~ 256(INCR)
2/4/8/16(WRAP)
1 ~ 16(FIXED)
用ARLEN/AWLEN信号表示
实际长度 = ARLEN + 1
突发大小 每个数据包含的字节数 1/2/4/8/16/32/64/128 用ARSIZE/AWSIZE信号表示
2^ARSIZE 字节

这里有个公式,我建议你记下来:

一次突发传输的总字节数 = 突发长度 × 突发大小

举个例子:

突发长度 = 16(ARLEN = 15)
突发大小 = 4字节(ARSIZE = 2)
总字节数 = 16 × 4 = 64字节

这正好是一个典型的Cache line大小。

注意:突发长度和突发大小不是随便组合的。AXI协议有对齐要求:

  • 起始地址必须对齐到突发大小
  • 对于WRAP模式,起始地址还要对齐到总字节数

我见过一个设计,因为没检查地址对齐,导致WRAP传输时地址算错了,数据全写到了错误的位置。这种bug在仿真里很难发现,但流片回来就完蛋了。

4.4 地址计算实战

好了,理论说完了,咱们来点实战。

假设你要设计一个AXI master,需要从地址0x1000开始,连续读取32个32位数据。你会怎么配?

方案一:用INCR模式
起始地址:0x1000
突发长度:8(ARLEN = 7)
突发大小:4字节(ARSIZE = 2)
需要4次突发才能读完32个数据

方案二:用INCR模式,一次搞定
起始地址:0x1000
突发长度:32(ARLEN = 31)
突发大小:4字节(ARSIZE = 2)
一次突发搞定,但注意:AXI协议允许INCR最大256长度

我个人习惯用方案二,因为一次突发效率更高。但要注意,有些slave不支持那么长的突发,你得先确认。

再来看一个WRAP的例子:

场景:读取一个64字节的Cache line
起始地址:0x1000
突发长度:16(ARLEN = 15)
突发大小:4字节(ARSIZE = 2)
总字节数:64字节

地址计算:
Beat 0:  0x1000
Beat 1:  0x1004
...
Beat 15: 0x103C
没有回卷,因为起始地址正好对齐到64字节边界

但如果起始地址是0x100C呢?

起始地址:0x100C
突发长度:16
突发大小:4字节
地址范围:0x100C ~ 0x104C

Beat 0:  0x100C
Beat 1:  0x1010
...
Beat 15: 0x100C(回卷!)

注意:0x100C + 15×4 = 0x1048,超过了上边界0x104C?
不对,让我重新算:
0x100C + 15×4 = 0x100C + 0x3C = 0x1048
上边界是 0x100C + 16×4 = 0x104C
所以 Beat 15 的地址是 0x1048,没有回卷。

等等,我搞错了。WRAP的地址范围是 [0x100C, 0x104C),
地址从0x100C开始,每次加4,到0x1048结束。
没有回卷,因为起始地址没有对齐到64字节边界?

关键点:WRAP模式只有在地址到达「突发长度 × 突发大小」的整数倍边界时才会回卷。如果起始地址不对齐,就不会触发回卷。

这也是为什么AXI协议要求WRAP的起始地址必须对齐到总字节数边界。

4.5 知识体系总览

最后,我用一张图来总结今天的内容。这张图是我自己画的,把三种突发类型的核心逻辑串在了一起。

AXI突发传输知识体系 突发传输核心 FIXED 固定地址 INCR 递增地址 WRAP 回卷地址 特点 • 地址始终不变 • 适合FIFO/寄存器操作 • 突发长度 ≤ 16 特点 • 地址依次递增 • 适合连续内存访问 • 突发长度 1~256 特点 • 地址到边界回卷 • 适合Cache line填充 • 长度仅2/4/8/16 关键参数 突发长度 (ARLEN/AWLEN) = 实际传输次数 - 1 突发大小 (ARSIZE/AWSIZE) = 2^信号值 字节 总字节数 = 突发长度 × 突发大小

这张图把三种突发类型的特点和关键参数都串起来了。你保存下来,以后写代码或者做验证时,随时可以翻出来看看。

好了,关于AXI突发传输的核心内容,今天就聊到这儿。记住:FIXED锁地址、INCR顺序走、WRAP绕圈圈。搞清楚了这三兄弟,AXI的地址计算你就拿下了。

最后一个小建议:做验证的时候,一定要把地址计算的测试用例写全。边界条件、对齐条件、回卷条件,一个都不能少。我当年就是因为少测了一个WRAP回卷的边界情况,差点让项目延期。嗯,吃一堑长一智吧。