4. AXI传输类型:突发传输、固定地址传输、非对齐传输、原子操作

大家好,我是老李。做AXI验证这些年,我见过太多工程师在传输类型上栽跟头。说白了,AXI协议的核心就是这四种传输方式。你搞懂了它们,总线调优就成功了一半。

今天咱们就一个一个掰开揉碎了讲。我会结合我踩过的坑,给你说清楚每种传输该怎么用、什么时候用、有什么坑。

4.1 突发传输(Burst Transfer)

突发传输是AXI最常用的传输方式。我习惯叫它「打包发货」——把多个数据一次性发出去,效率最高。

核心要点:突发传输允许主设备发起一次传输请求,连续传输多个数据。地址只需要在第一个节拍给出,后续数据自动递增。

突发传输有三个关键参数:

  • ARLEN/AWLEN:突发长度,表示传输多少个数据。注意,实际传输数量 = ARLEN + 1
  • ARSIZE/AWSIZE:每个数据的字节数。比如SIZE=2表示4字节
  • ARBURST/AWBURST:突发类型,有FIXED、INCR、WRAP三种

举个例子,你想想看:

// 一次读8个32位数据,地址递增
ARADDR  = 0x1000
ARLEN   = 7      // 实际传输8个数据
ARSIZE  = 2      // 4字节(32位)
ARBURST = 1      // INCR模式,地址递增

我在项目中遇到过一个问题:有人把ARLEN设成0,以为只传1个数据。结果是对的,但效率极低。你想想,一次突发只传1个数据,那还不如用单次传输呢。

我的建议:尽量把突发长度设大一些。比如DDR控制器,我一般设成8或16。这样总线利用率最高。

4.2 固定地址传输(Fixed Address Transfer)

固定地址传输,说白了就是所有数据都往同一个地址写。嗯,这个场景不多见,但用对了很关键。

什么时候用?我举个例子:你有一个FIFO,每次写数据都写到同一个入口地址。这时候用FIXED模式最合适。

// 固定地址写,所有数据写到0x2000
AWADDR  = 0x2000
AWLEN   = 3      // 传4个数据
AWSIZE  = 2      // 每个4字节
AWBURST = 0      // FIXED模式

注意:固定地址传输容易造成数据覆盖。我曾经调试一个模块,发现数据总是对不上。查了两天才发现,从设备没处理好FIXED模式,后一个数据把前一个覆盖了。

我个人习惯,只有在明确知道从设备支持FIFO操作时,才用FIXED模式。否则,老老实实用INCR。

4.3 非对齐传输(Unaligned Transfer)

非对齐传输,这是很多工程师的噩梦。我记得刚入行时,被这个问题折磨了好几天。

什么叫非对齐?简单说,就是传输的起始地址不是数据宽度的整数倍。比如你想从地址0x1001读一个32位数据,这就是非对齐。

AXI协议怎么处理?它通过两个信号来指示:

  • WSTRB:写数据选通信号,告诉从设备哪些字节是有效的
  • 地址的低位:指示数据在总线上的偏移位置

举个例子:

// 从地址0x1001开始写4字节数据
// 数据总线是32位(4字节)
// 地址0x1001对应数据总线的字节1、2、3,以及下一个地址的字节0

AWADDR = 0x1001
AWSIZE = 2       // 4字节传输
WSTRB  = 4'b1110 // 字节1、2、3有效(从0开始计数)
// 实际传输:字节0无效,字节1、2、3有效

避坑指南:我曾经在一个项目中,从设备没正确处理非对齐传输。结果数据总是错位。后来我加了一个检查逻辑:如果地址不是对齐的,就拆成两次传输。虽然效率低一点,但至少不会出错。

你想想看,为什么AXI要支持非对齐?说白了,是为了兼容不同的数据类型。比如一个结构体里,有char、short、int混在一起,地址自然就对不齐了。

4.4 原子操作(Atomic Operation)

原子操作,这是多核系统中最重要的传输类型。我习惯叫它「不可分割的操作」。

原子操作有两种:

  • 原子加载-链接(Load-Linked, LL):读取一个地址,并标记该地址
  • 原子条件存储(Store-Conditional, SC):只有在地址未被修改时,才执行写入

说白了,就是「读-改-写」三步合一步,中间不能被其他主设备打断。

AXI协议通过以下信号实现原子操作:

信号 描述
AxLOCK 锁定传输,表示这是一个原子操作序列
ARDOMAIN/AWDOMAIN 定义操作的共享域
ARSNOOP/AWSNOOP 定义操作的 snoop 类型

重要提醒:原子操作对总线性能影响很大。因为它会锁定总线,其他主设备必须等待。我建议只在必要时使用,比如实现信号量、互斥锁等场景。

我记得有一次,一个同事在中断处理里用了原子操作。结果中断响应时间变得不可预测。后来我们改成用普通读写加软件锁,性能反而更稳定。

4.5 四种传输类型的对比

好了,四种传输类型都讲完了。我画了一张图,帮你理清它们的关系:

AXI四种传输类型对比 突发传输 连续地址,批量传输 效率最高,最常用 INCR/WRAP/FIXED 固定地址传输 所有数据写同一地址 适合FIFO操作 注意数据覆盖 非对齐传输 地址非对齐 通过WSTRB控制 兼容不同数据类型 原子操作 读-改-写不可分割 LL/SC指令 多核同步必备 选择建议 • 普通数据传输:用突发传输(INCR模式),效率最高 • FIFO/寄存器操作:用固定地址传输(FIXED模式),注意数据覆盖 • 混合数据类型:用非对齐传输,配合WSTRB信号 • 多核同步:用原子操作,但注意性能开销 根据场景选择合适的传输类型

我的经验总结:

  • 90%的场景用突发传输就够了
  • 固定地址传输只用在FIFO或特殊寄存器
  • 非对齐传输能避免就避免,实在不行就拆成两次
  • 原子操作是双刃剑,用之前想清楚

好了,这四种传输类型就讲到这里。每种都有它的用武之地,关键是要理解它们的原理和适用场景。我在实际项目中,一般会先看需求,再选类型。比如DMA传输,我肯定用突发;配置寄存器,用单次传输就够了。

记住一点:没有最好的传输类型,只有最合适的。你根据实际场景选对了,性能自然就上去了。

可可精品资料库