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 四种传输类型的对比
好了,四种传输类型都讲完了。我画了一张图,帮你理清它们的关系:
我的经验总结:
- 90%的场景用突发传输就够了
- 固定地址传输只用在FIFO或特殊寄存器
- 非对齐传输能避免就避免,实在不行就拆成两次
- 原子操作是双刃剑,用之前想清楚
好了,这四种传输类型就讲到这里。每种都有它的用武之地,关键是要理解它们的原理和适用场景。我在实际项目中,一般会先看需求,再选类型。比如DMA传输,我肯定用突发;配置寄存器,用单次传输就够了。
记住一点:没有最好的传输类型,只有最合适的。你根据实际场景选对了,性能自然就上去了。