3、AXI传输特性:突发传输、乱序传输、交织传输与原子访问

AXI协议之所以能成为高性能总线的事实标准,核心就在于它对传输行为的精细控制。说白了,它不光告诉你怎么传数据,还允许你“插队”、“乱序处理”,甚至“锁住”某个地址不让别人碰。

我刚开始接触AXI时,总觉得这些特性是锦上添花。直到有一次调试一个多主控的DDR控制器,数据死活对不上,才发现自己对“乱序”的理解太肤浅了。嗯,这一章咱们就把这几个核心特性掰开揉碎了讲清楚。

3.1 突发传输(Burst)

突发传输是AXI最基础的加速手段。它的思路很简单:你告诉总线“我要从地址A开始,连续读/写N个数据”,总线就一气呵成地帮你搞定,不用每个数据都发一遍地址。

核心三要素:

  • 突发长度(Burst Length):一次突发传输的数据个数。1~16(对于INCR类型,可以到256)。
  • 突发大小(Burst Size):每个数据的字节数。1、2、4、8、16、32、64、128字节。
  • 突发类型(Burst Type):FIXED(固定地址)、INCR(递增地址)、WRAP(回环地址)。

我个人习惯把突发类型记成三种场景:

  • FIXED:所有数据都打在同一个地址上。典型场景是写FIFO或状态寄存器。我见过有人拿FIXED去读DDR,结果数据全是同一个地址的内容,排查了半天才发现类型配错了。
  • INCR:地址依次递增。最常用,比如从内存读一段连续的数据。
  • WRAP:地址递增到边界后回环到起始地址。专门为Cache Line设计,比如64字节的Cache Line,地址对齐到64字节边界,读到边界就自动折回来。

这里有个容易踩的坑——地址对齐。突发传输要求起始地址必须对齐到突发大小。比如你设Burst Size=8字节,起始地址必须是8的倍数。我曾经在项目中用了一个非对齐的起始地址,结果仿真波形里地址乱跳,数据也错位了。后来养成习惯:每次配突发参数前,先算一遍地址对齐。

实战小技巧:

计算突发传输的总字节数:Burst Length × Burst Size。这个值不能超过4KB边界。为什么?因为AXI协议规定一次突发不能跨4KB边界。这是为了简化Slave的地址解码逻辑。

3.2 乱序传输(Out-of-Order)

乱序传输是AXI提升总线利用率的关键。它允许Slave不按Master发请求的顺序返回数据。

你想想看:Master先发了读请求A(地址在DDR),又发了读请求B(地址在片上SRAM)。如果必须按顺序返回,那Master得干等DDR的几百个周期,SRAM的数据再快也得排队。有了乱序,SRAM的数据可以先回来,Master先处理它,效率一下子就上去了。

乱序的实现靠的是ID标签。每个传输事务都带一个ID,Slave返回的数据必须带上相同的ID。Master根据ID来匹配请求和响应。

特性 说明
ID宽度 AXI3支持4位ID(最多16个未完成事务),AXI4扩展到8位(最多256个)
乱序深度 Slave可以同时处理多个不同ID的事务,并按任意顺序返回
同ID顺序 相同ID的事务必须按顺序返回——这是协议硬性规定

我曾经踩过的坑:

在设计一个DMA控制器时,我给所有传输都用了同一个ID。结果Slave虽然支持乱序,但看到同ID就老老实实按顺序处理了,性能完全没发挥出来。后来改成每个通道分配独立ID,乱序效果立竿见影。

记住:乱序的前提是ID不同。想充分利用乱序,就得合理分配ID资源。

3.3 交织传输(Interleaving)

交织传输比乱序更进一步。乱序只是允许响应乱序回来,但交织允许数据在传输过程中被拆散穿插。

举个例子:Master发了两笔写传输,事务1有4个数据,事务2有4个数据。在交织模式下,Slave可以先收事务1的WDATA[0],再收事务2的WDATA[0],再收事务1的WDATA[1]……数据在总线上是交错传输的。

交织传输在AXI3中是可选特性,但到了AXI4被完全移除了。为什么?因为实际设计中,交织带来的硬件复杂度远大于收益。Slave需要为每个交织的事务维护独立的写数据缓冲和状态机,面积和时序压力都很大。

AXI3 vs AXI4 交织对比:

  • AXI3:支持写交织(Write Interleaving),通过WID信号区分数据属于哪个事务。
  • AXI4:不再支持写交织,WID信号被移除。所有写数据必须按顺序发送。
  • 读交织:两个版本都不支持读交织。读数据通道本来就只有一个,不存在交织问题。

我个人建议:如果你在做AXI3的老项目,尽量别用交织。除非你有非常充分的理由(比如某个老IP强制要求),否则老老实实按顺序发数据,省下来的逻辑资源干点别的不好吗?

3.4 原子访问(Atomic Access)

原子访问解决的是多主控环境下的竞争问题。两个Master同时读写同一个地址,如果没有保护机制,数据就乱套了。

AXI提供了两种原子访问机制:

  • 独占访问(Exclusive Access):Master先读一个地址(打上独占标记),然后写同一个地址。如果这期间没有其他Master写这个地址,写操作成功;否则写操作失败,Master需要重试。
  • 锁定访问(Locked Access):Master锁定总线,不允许其他Master发起传输,直到锁定事务完成。这种方式比较粗暴,会降低总线利用率。
特性 独占访问 锁定访问
总线占用 不锁定总线,其他Master可以继续传输 锁定总线,其他Master必须等待
实现复杂度 需要Slave支持独占监视器 相对简单,但影响性能
适用场景 信号量、互斥锁 需要严格连续操作的场景
AXI4支持 支持 不再推荐使用(AXI4中ARLOCK/SLOCK信号被简化)

我在项目中用过独占访问来实现多核之间的信号量。具体做法是:每个核在访问共享资源前,先执行一次独占读;如果读到的值是0(表示资源空闲),就执行独占写把值改成1;如果写成功,说明拿到了锁。整个过程是原子的,不会出现两个核同时拿到锁的情况。

独占访问的硬件要求:

Slave必须实现一个独占监视器(Exclusive Monitor),记录每个地址的独占状态。监视器通常是一个硬件状态机,维护一个地址-状态表。当Master发起独占读时,监视器标记该地址为“已独占”;当其他Master写这个地址时,监视器清除独占标记。独占写时,监视器检查标记是否存在,存在则写成功,不存在则写失败。

3.5 四种特性对比总结

这四种特性从不同维度提升了总线的灵活性和效率。我画了一张图,帮你理清它们的关系:

AXI传输特性关系图 AXI传输特性 突发传输 乱序传输 交织传输 原子访问 各特性核心关注点 • 突发传输:减少地址发送次数,提升连续数据传输效率 • 乱序传输:允许不同ID的事务乱序完成,提高总线利用率 • 交织传输:允许写数据交错传输(AXI3支持,AXI4已移除) • 原子访问:通过独占/锁定机制保证多主控下的数据一致性 • 共同目标:在带宽、延迟、一致性之间找到最佳平衡点

从图中可以看出,这四种特性各有侧重:突发传输解决的是“怎么传得快”,乱序和交织解决的是“怎么传得灵活”,原子访问解决的是“怎么传得安全”。

在实际项目中,我通常这样选择:

  • 数据流场景(DMA、显示控制器):优先用突发传输,配合合理的ID分配实现乱序。
  • 控制面场景(寄存器读写):用单次传输,必要时加独占访问保护。
  • 多核共享数据:原子访问是必须的,否则数据一致性会出大问题。

重要提醒:

不要为了用特性而用特性。每个特性都有代价:突发传输需要地址对齐检查,乱序需要ID管理和重排序缓冲,原子访问需要独占监视器。在设计中,够用就好。我见过一个项目,工程师为了追求极致性能,把所有特性全开了,结果综合出来的面积比预期大了30%,时序也收不拢。后来砍掉不必要的交织和深度乱序,问题才解决。