4. AXI4总线协议详解:AXI4-Full、AXI4-Lite、AXI4-Stream协议分析、握手与时序

说到Zynq开发,AXI总线是绕不开的核心。我刚开始接触Zynq时,面对AXI4-Full、AXI4-Lite、AXI4-Stream这三兄弟,说实话有点懵。它们名字相似,但用法天差地别。今天咱们就把它们彻底理清楚。

4.1 为什么是AXI?

AXI是ARM公司推出的AMBA总线家族中的一员。Zynq之所以选择它,是因为它高性能、高带宽,而且支持乱序传输。说白了,就是快且灵活。

我在第一个Zynq项目里,用AXI-Lite配置寄存器,用AXI-Stream传高速数据流,用AXI-Full做DMA批量搬运。三种协议各司其职,配合得非常好。

4.2 三种AXI4协议对比

特性 AXI4-Full AXI4-Lite AXI4-Stream
地址/数据通道 分离的地址、数据通道 分离的地址、数据通道 无地址通道
突发传输 支持(最多256拍) 不支持(单拍传输) 支持无限长度
数据宽度 8~1024位 32位固定 8~1024位
典型用途 DMA、DDR控制器 寄存器配置、状态读取 视频流、音频流、高速数据
握手信号 VALID/READY + 多通道 VALID/READY + 简化通道 VALID/READY + 用户自定义

核心要点:AXI4-Lite是AXI4-Full的简化版,去掉了突发传输。AXI4-Stream则完全抛弃了地址概念,专注于数据流的搬运。

4.3 握手协议:VALID/READY机制

三种AXI协议都使用相同的握手方式——VALID/READY。这是AXI的精髓所在。

简单来说:

  • VALID:发送方告诉接收方“数据准备好了”
  • READY:接收方告诉发送方“我可以接收了”

数据只在VALID和READY同时为高时传输。这个机制的好处是,发送方和接收方可以各自控制节奏,互不阻塞。

握手有三种情况:

  1. VALID先有效,READY后有效:发送方先准备好,等待接收方
  2. READY先有效,VALID后有效:接收方先准备好,等待发送方
  3. 同时有效:一拍完成传输

我的经验:设计AXI从机时,我习惯让READY信号在复位后默认拉高。这样主机发数据时,只要VALID有效就能直接传输,减少等待周期。但要注意,如果从机来不及处理,必须能拉低READY进行反压。

4.4 AXI4-Full:完整的存储映射协议

AXI4-Full有五个独立通道:

  • 读地址通道(AR)
  • 读数据通道(R)
  • 写地址通道(AW)
  • 写数据通道(W)
  • 写响应通道(B)

每个通道都有自己的VALID/READY握手。这种分离设计让读写可以并行,大大提高了总线利用率。

突发传输是AXI4-Full的杀手锏。一次地址传输后,可以连续传输1~256拍数据。我做过一个图像处理加速器,用AXI4-Full从DDR搬数据,一次突发256个64位数据,带宽利用率接近100%。

避坑指南:我曾经在突发传输中忘记处理地址对齐问题。AXI要求突发地址必须与数据宽度对齐。比如32位数据总线,地址必须是4的倍数。否则会触发SLVERR错误,调试起来非常头疼。

4.5 AXI4-Lite:轻量级配置接口

AXI4-Lite是AXI4-Full的简化版。它不支持突发,每次只能传输一个数据。数据宽度固定为32位。

它的通道和AXI4-Full一样,也是五个。但信号数量少了很多,实现起来简单。

我通常用它来做:

  • 控制寄存器配置
  • 状态寄存器读取
  • 中断控制
  • 小数据量交互

为什么不用AXI4-Full?因为AXI4-Lite逻辑简单,占用的LUT少。对于配置类操作,性能不是瓶颈,资源才是。

4.6 AXI4-Stream:无地址的数据高速公路

AXI4-Stream是三种协议中最特殊的。它没有地址通道,只有数据通道。数据像流水一样从上游流向下游。

它的信号包括:

  • TVALID:上游告诉下游数据有效
  • TREADY:下游告诉上游可以接收
  • TDATA:数据总线
  • TLAST:指示数据包结束
  • TKEEP:指示哪些字节有效
  • TUSER:用户自定义信号

AXI4-Stream特别适合:

  • 视频像素流
  • 音频采样流
  • 网络数据包
  • FFT输入输出

关键点:AXI4-Stream没有地址,所以不能直接连到DDR或外设。它需要DMA或AXI Interconnect做地址映射。我习惯在加速器两端都挂AXI-Stream接口,中间用DMA连接DDR,这样数据流非常顺畅。

4.7 时序分析:一个完整的写传输

咱们看一个AXI4-Full的写传输时序。假设主机要写地址0x1000,数据0xAABBCCDD。

时钟周期:  T0   T1   T2   T3   T4   T5
AWVALID:    0    1    1    0    0    0
AWREADY:    0    0    1    0    0    0
AWADDR:     X  0x1000 0x1000  X    X    X
WVALID:     0    0    0    1    1    0
WREADY:     0    0    0    0    1    0
WDATA:      X    X    X    X  0xAABBCCDD  X
WLAST:      0    0    0    0    1    0
BVALID:     0    0    0    0    0    1
BREADY:     0    0    0    0    0    1
BRESP:      X    X    X    X    X   OKAY

这个时序里:

  • T0-T1:主机发写地址,从机在T2才接收
  • T2-T3:主机发写数据,从机在T4才接收
  • T5:从机返回写响应

注意地址和数据是分开握手的。地址在T2传输,数据在T4传输。这就是AXI的灵活性——地址和数据可以不同步。

4.8 知识结构图:AXI4协议体系

AXI4协议体系 AXI4 协议 AXI4-Full AXI4-Lite AXI4-Stream 特性 • 突发传输 • 5个独立通道 • 存储映射 特性 • 单拍传输 • 5个简化通道 • 32位固定宽度 特性 • 无地址通道 • 无限数据流 • 用户自定义 典型用途 DMA、DDR控制器 高速外设 典型用途 寄存器配置 状态读取 典型用途 视频流、音频流 高速数据采集 核心握手机制:VALID / READY

4.9 实际项目中的选择策略

在Zynq项目中,我总结了一套选择策略:

场景 推荐协议 原因
配置加速器寄存器 AXI4-Lite 简单、资源少、够用
从DDR搬数据到加速器 AXI4-Full 需要突发、高带宽
加速器之间传数据 AXI4-Stream 无地址开销、流水线友好
CPU访问外设FIFO AXI4-Lite 单次读写即可
视频帧缓冲 AXI4-Stream + DMA 流式处理、带宽高

曾经踩过的坑:我在一个项目中,用AXI4-Lite去读一个高速更新的状态寄存器。结果发现读到的值总是旧的。后来才意识到,AXI4-Lite没有缓存一致性协议。解决办法是在读之前加一个同步屏障,或者用AXI4-Full的锁定传输。嗯,这个坑让我多花了两天调试。

4.10 小结

AXI4三种协议各有定位。AXI4-Full是全能选手,AXI4-Lite是轻量配置,AXI4-Stream是数据专线。理解它们的握手机制和适用场景,是Zynq开发的基础。

我个人建议,新手先从AXI4-Lite入手,写一个简单的寄存器读写模块。跑通之后,再尝试AXI4-Stream做数据流处理。最后挑战AXI4-Full的突发传输。一步一步来,你会发现AXI其实没那么复杂。