4、AXI4总线协议详解:AXI4通道与握手机制、地址/数据/控制信号、突发传输与乱序传输、AXI4-Lite与AXI4-Stream

AXI4,全称Advanced eXtensible Interface,是ARM公司推出的AMBA总线家族中的核心成员。说实话,在FPGA和SoC设计领域,你要是没跟AXI4打过交道,那都不好意思说自己做过高速设计。我个人习惯把AXI4看作是一套“交通规则”——它规定了数据怎么在路上跑、什么时候该停、什么时候该让。

这一章,咱们就把它彻底讲透。我会从最基础的通道结构开始,一步步深入到握手机制、突发传输,最后再聊聊AXI4的两个变种:Lite和Stream。

AXI4 总线协议核心结构 Master Slave 读地址通道 (AR) 读数据通道 (R) 写地址通道 (AW) 写数据通道 (W) 写响应通道 (B) 握手机制:VALID + READY 发送方拉高VALID → 接收方拉高READY → 数据在时钟上升沿传输 双方必须同时有效,传输才发生

4.1 AXI4的五个独立通道

AXI4最核心的设计思想,就是“通道分离”。它把一次总线事务拆成了五个独立的通道。你想想看,这就像一条高速公路,把入口、出口、快车道、慢车道全部分开,车流自然就顺畅了。

这五个通道分别是:

  • 读地址通道(AR):Master告诉Slave“我要读哪个地址”
  • 读数据通道(R):Slave把读到的数据返回给Master
  • 写地址通道(AW):Master告诉Slave“我要往哪个地址写”
  • 写数据通道(W):Master把要写的数据发给Slave
  • 写响应通道(B):Slave告诉Master“写操作完成了,结果如何”

每个通道都是单向的,数据流方向固定。这样做的好处很明显——读和写可以同时进行,互不干扰。我在项目中遇到过一种情况,DMA同时做内存搬运,读和写完全重叠,如果没有这种分离设计,性能直接腰斩。

4.2 握手机制:VALID和READY

每个通道都有一套独立的握手机制,核心就是两个信号:VALIDREADY

说白了,这就是一个“你准备好了吗?我准备好了!”的对话过程。

  • VALID:发送方拉高,表示“我这边数据/地址已经准备好了”
  • READY:接收方拉高,表示“我可以接收了”

传输发生的条件只有一个:VALID和READY同时为高,在时钟上升沿采样,数据就传过去了。

关键点:VALID不能依赖READY。发送方一旦准备好,就必须拉高VALID,不能等READY来了再拉。这是AXI协议的死规定,违反的话时序会出大问题。

我曾经踩过一个坑:在设计一个AXI Slave时,为了省逻辑,我让VALID等READY来了再拉高。结果仿真没问题,上板子就死机。查了两天才发现,Master那边等VALID等了半天,以为Slave死了,直接超时复位。从那以后,我再也不敢在VALID上做手脚。

4.3 地址、数据与控制信号

每个通道除了VALID和READY,还有一组核心信号。咱们挑几个重点说说。

读地址通道(AR)

  • ARADDR:读起始地址
  • ARLEN:突发长度,表示这次读多少个数据
  • ARSIZE:每个数据的字节数
  • ARBURST:突发类型,固定地址/增量地址/回绕地址

读数据通道(R)

  • RDATA:读回来的数据
  • RRESP:读响应状态,OKAY/EXOKAY/SLVERR/DECERR
  • RLAST:最后一个数据时拉高,告诉Master“这次突发结束了”

写地址通道(AW)

  • AWADDRAWLENAWSIZEAWBURST:和读通道类似

写数据通道(W)

  • WDATA:要写的数据
  • WSTRB:字节选通信号,每个bit对应一个字节,1表示该字节有效
  • WLAST:最后一个数据时拉高

写响应通道(B)

  • BRESP:写响应状态

小技巧:WSTRB这个信号很多人容易忽略。比如你要写一个32位总线中的第2个字节,WSTRB就设成4'b0010。如果不设对,Slave可能会把不该写的数据也写进去。我调试DDR控制器时就遇到过这种问题,数据总是对不上,最后发现是WSTRB没处理好。

4.4 突发传输与乱序传输

突发传输是AXI4的杀手锏。说白了,就是一次地址握手,后面连续传多个数据,不用每个数据都重新发地址。

举个例子:你要从地址0x1000开始连续读8个32位数据。如果没有突发,你得发8次地址、收8次数据。有了突发,你只需要发一次地址,Slave就会连续返回8个数据。

突发类型有三种:

ARBURST/AWBURST 类型 说明
2'b00 FIXED 固定地址,所有数据访问同一个地址
2'b01 INCR 增量地址,地址依次递增
2'b10 WRAP 回绕地址,地址递增到边界后回到起始

乱序传输呢?这个更高级。AXI4允许Master同时发出多个地址请求,Slave可以按任意顺序返回数据。你想想看,如果Slave内部有多个存储体,有的快有的慢,乱序传输就能让快的先返回,不用等慢的。

乱序靠两个东西实现:ID信号事务ID。每个事务都有一个唯一的ID,返回数据时带上同样的ID,Master就知道这个数据属于哪个事务了。

注意:乱序传输虽然能提高效率,但实现复杂度也上去了。如果你的设计不需要乱序,可以把ID设成固定值,强制顺序返回。我一般建议初学者先做顺序传输,跑通了再考虑乱序优化。

4.5 AXI4-Lite与AXI4-Stream

AXI4有两个简化版本,专门针对不同场景。

AXI4-Lite

AXI4-Lite是AXI4的轻量版。它去掉了突发传输,每次只能传一个数据。信号也简化了,没有ID、没有突发长度、没有WSTRB(其实有,但固定全有效)。

什么时候用AXI4-Lite?

  • 配置寄存器:比如设置DMA的源地址、目的地址
  • 控制状态寄存器:比如启动、停止、查询状态
  • 低速外设:比如GPIO、UART的控制接口

我个人习惯把所有控制类接口都用AXI4-Lite。原因很简单——逻辑少、时序好、不容易出错。你想想看,配置寄存器又不需要高带宽,用全功能AXI4纯属浪费。

AXI4-Stream

AXI4-Stream就更极端了,它连地址都去掉了。只有数据通道,没有地址通道,也没有写响应通道。数据像流水一样从Master流到Slave。

信号也简化到极致:

  • TDATA:数据
  • TVALID:数据有效
  • TREADY:接收方准备好
  • TLAST:最后一个数据
  • TKEEP:字节有效指示(可选)
  • TUSER:用户自定义信号(可选)

AXI4-Stream最适合什么场景?

  • 高速数据流:比如ADC采样数据、视频像素流
  • DMA数据传输:数据从一个外设搬到另一个外设
  • FIFO接口:本质上就是带握手的FIFO读写

经验之谈:AXI4-Stream的握手机制和AXI4完全一样,也是VALID+READY。所以如果你已经理解了AXI4的握手,Stream就是小菜一碟。区别只在于Stream没有地址,数据怎么解释完全由用户自己定义。

嗯,到这里AXI4的核心内容就讲完了。从五个通道到握手机制,从突发传输到乱序,再到Lite和Stream两个变种,这些东西你吃透了,后面做FPGA内存控制器和RISC-V总线接口就会轻松很多。