4、常见总线协议(三):AMBA AXI4.0总线协议详解、乱序传输与通道机制

AXI4.0,说实话,这是AMBA家族里我最喜欢的一个协议。为什么?因为它够灵活,够快。我在做第一颗AI加速芯片的时候,就是靠AXI4.0把DDR和计算单元之间的带宽吃满的。今天咱们就把它掰开揉碎了讲清楚。

4.1 AXI4.0的整体架构

AXI4.0最大的特点,就是它把读写分开了。不是简单的分开,而是用了五个独立的通道。你想想看,这就像一条双向八车道的高速公路,读和写各走各的道,互不干扰。

这五个通道分别是:

  • 读地址通道(AR):发送读请求的地址和控制信息
  • 读数据通道(R):返回读到的数据,以及读响应信号
  • 写地址通道(AW):发送写请求的地址和控制信息
  • 写数据通道(W):发送要写入的数据
  • 写响应通道(B):返回写操作的完成状态

每个通道都是独立的,都有自己的握手信号。这意味着什么?意味着你可以同时发读请求、写请求,还能同时收数据。我在项目中遇到过,有些新手把AXI当成APB来用,一个事务做完再做下一个,那带宽利用率简直惨不忍睹。

核心要点:AXI4.0的五个通道是并行工作的。读操作和写操作可以同时进行,互不阻塞。

4.2 通道握手机制

每个通道都用一套简单的握手协议:VALID和READY。发送方拉高VALID表示数据有效,接收方拉高READY表示可以接收。当两者同时为高时,传输发生。

这里有个坑,我踩过。VALID信号不能依赖READY信号。什么意思?就是发送方一旦拉高VALID,就必须保持住,直到握手成功。你不能因为看到READY没拉高,就把VALID拉低。我曾经在一个DMA控制器里犯了这错,结果仿真没问题,上板子就死机。查了两天才发现是VALID被错误地拉低了。

重要规则:VALID一旦拉高,必须保持到握手完成。READY可以等待VALID,但VALID不能等待READY。

4.3 乱序传输——AXI的灵魂

乱序传输,说白了就是允许后发的请求先完成。为什么会这样?你想想看,如果总线连着DDR控制器,读地址0x1000和0x2000。0x1000那行刚好在DDR的Bank冲突,要多等几个周期;而0x2000那行刚好命中,直接就能返回数据。如果非要按顺序来,那就得傻等,多浪费啊。

AXI4.0用ID标签来解决这个问题。每个事务都带一个ID,从设备返回数据时带上相同的ID。主设备根据ID就知道哪个数据对应哪个请求。这样,数据返回的顺序就可以和请求的顺序不一样了。

我个人习惯,在复杂SoC设计中,给每个主设备分配不同的ID高位,低位留给事务编号。这样调试的时候,一看ID就知道是哪个模块发出来的请求。

实战技巧:ID的分配要合理规划。建议高位表示主设备编号,低位表示事务编号。比如主设备0用ID[3:0]=4'b0000~4'b1111,主设备1用ID[3:0]=4'b0001~4'b1111,以此类推。

4.4 乱序深度与顺序保证

乱序不是无限度的。AXI4.0要求:相同ID的事务必须按顺序完成。也就是说,如果你用同一个ID发了两个读请求,那么第一个请求的数据必须在第二个之前返回。

这个约束其实很合理。你想想看,如果同一个ID的事务都乱序了,那软件怎么写?根本没法保证数据的一致性。所以,想要乱序,就得用不同的ID。

我在做视频编解码IP的时候,就用到了这个特性。把帧内预测和帧间预测的请求用不同的ID发出去,帧内预测的数据先回来就先处理,不用等帧间预测。这样流水线就不会因为等待数据而停顿。

4.5 突发传输与地址计算

AXI4.0支持突发传输,一次地址请求可以传输多笔数据。突发类型有三种:

突发类型 地址变化 适用场景
FIXED 地址不变 FIFO操作、外设寄存器
INCR 地址递增 内存连续读写
WRAP 地址递增,到边界回绕 Cache Line填充

突发长度从1到256,但要注意:INCR类型最大支持256笔,WRAP类型最大支持16笔。这个限制是因为WRAP需要预知边界,太长的话硬件实现太复杂。

地址对齐也是个容易出错的地方。突发传输的起始地址必须对齐到突发大小的边界。比如你发一个4笔的突发,每笔4字节,那起始地址必须是16字节对齐的。我曾经见过一个同事,地址没对齐,结果仿真跑得好好的,上板子就随机出错。查了三天,最后发现是地址计算逻辑写错了。

4.6 原子操作与锁

AXI4.0支持两种原子操作:独占访问和锁定访问。独占访问用于实现信号量,锁定访问用于实现总线仲裁。

独占访问的流程是这样的:

  1. 主设备发一个独占读请求
  2. 从设备返回数据,并记录这个地址被独占监视
  3. 主设备发一个独占写请求
  4. 从设备检查这个地址是否被其他主设备修改过
  5. 如果没有修改,写成功;否则写失败

这个机制在多核系统中特别有用。我记得在做双核CPU系统的时候,就用独占访问来实现自旋锁。两个核同时抢锁,只有一个能成功,另一个就循环重试。简单高效。

注意:独占访问要求从设备支持独占监视。不是所有的从设备都支持,设计时要注意检查。

4.7 低功耗接口

AXI4.0还定义了低功耗接口,通过CACTIVE和CSYSREQ等信号来控制时钟和电源。这个在实际项目中用得不多,但如果你做的是低功耗设计,就绕不开。

低功耗接口的核心思想是:当总线空闲时,可以关闭时钟甚至电源来省电。但要注意,关闭前必须确保所有未完成的事务都处理完了。否则数据就丢了。

我在做IoT芯片的时候用过这个特性。芯片大部分时间都在休眠,只有需要传输数据时才唤醒总线。这样功耗能降低90%以上。但代价是唤醒延迟,大概需要几十个微秒。所以,如果你的系统对延迟敏感,就要权衡一下了。

4.8 实战经验总结

说了这么多,最后分享几个我在项目中总结的经验:

  • ID管理要规范:给每个主设备分配独立的ID范围,方便调试
  • 地址对齐不能忘:突发传输的地址必须对齐,否则硬件实现会非常复杂
  • VALID不能依赖READY:这是AXI协议的基本规则,违反就会出问题
  • 乱序要适度:不是乱序深度越大越好,太深了会增加硬件开销和延迟
  • 仿真要覆盖边界:地址边界、突发长度边界、ID回绕边界,这些最容易出bug

AXI4.0是个强大的协议,但越强大的东西,用起来越要小心。我建议你在做第一个AXI设计的时候,先画一个时序图,把每个通道的握手过程画清楚。等跑通了,再慢慢优化性能。别一上来就想把带宽吃满,那样很容易翻车。

好了,关于AXI4.0的核心内容就这些。记住,协议是死的,人是活的。理解了背后的设计思想,你就能灵活运用它来解决实际问题。

AXI4.0 总线协议核心架构 主设备 从设备 读地址通道 (AR) 读数据通道 (R) 写地址通道 (AW) 写数据通道 (W) 写响应通道 (B) 核心特性 乱序传输 ID标签实现 相同ID保序 突发传输 FIXED/INCR/WRAP 长度1~256 原子操作 独占访问 锁定访问 低功耗 CACTIVE CSYSREQ 五个独立通道并行工作,支持乱序传输,提高总线利用率 每个通道使用 VALID + READY 握手协议

可可精品资料库