FPGA--AXI4

第一部分:AXI协议的第一性原理

1. 核心问题

在一个复杂的片上系统(SoC)中,有多个“主设备”(Masters,如CPU、DMA引擎)需要与多个“从设备”(Slaves,如DDR4控制器、Block RAM、自定义IP)进行数据交换。如何设计一个高性能、高效率、可扩展的通信框架来管理这些交互?

2. AXI的解决方案 - “高速公路”模型

解耦的通道 (Decoupled Channels): 这是AXI的灵魂。传统的总线(如Avalon-MM)通常是地址、数据、控制信号在同一个周期内发出,必须等待从机响应。AXI则将一次完整的读/写操作分解为五个独立的、并行的“车道”(通道)。

写操作: 地址车道、数据车道、响应车道。

读操作: 地址车道、数据车道。

类比: 想象在网上购物。你先下订单(地址通道),然后商品开始打包发货(数据通道),最后你收到一条“已签收”的短信(响应通道)。这三个动作是异步、独立的。你可以在等待A商品发货的同时,去下B商品的订单。

基于“VALID/READY”的握手: 这是AXI实现通道间异步通信的物理基础。每条通道都有两根核心控制线:

`xVALID`: 由信息源(Source)驱动。当`VALID`为高时,表示“我这条车道上的信息(地址/数据)是有效的,请查收”。

 `xREADY`: 由信息目的地(Destination)驱动。当`READY`为高时,表示“我已经准备好了,可以接收你车道上的信息”。

握手成功: 只有在同一个时钟周期,`VALID`和`READY`同时为高时,一次信息传输才算成功完成。这个机制优雅地解决了不同模块处理速度不匹配的问题,实现了自然的流控(Flow Control)。

支持突发传输 (Burst Transactions): AXI天生为处理数据块而生。Master可以在地址通道只发一次地址,就连续读/写一大块数据(最多256个beat)。这极大地减少了地址传输的开销,最大化了数据总线的利用率,是实现高带宽的关键。

第二部分:AXI4协议详解

AXI4是目前最主流的版本,它有三种主要类型:

1. AXI4 (Full AXI): 标准的全功能版本,包含读写五个通道。

2. AXI4-Lite: 一个轻量级版本,用于访问简单的控制/状态寄存器。它不支持突发传输,每次只能读写一个字(32位或64位)。通道和信号也大大简化。

3. AXI4-Stream: 只用于单向的、连续的数据流传输(如视频流、无线数据包)。它没有地址概念,只有`TDATA`, `TVALID`, `TREADY`等信号,可以看作是一个简化版的写数据通道。 我们重点讲解全功能的AXI4。

AXI4的五个独立通道

1. 写地址通道 (Write Address Channel - AW)

方向: Master -> Slave

作用: Master发起一次写突发传输。

关键信号:

`AWVALID`: Master置位,表示地址信息有效。

`AWREADY`: Slave置位,表示准备好接收地址。

`AWADDR`: 突发传输的起始地址。

`AWLEN[7:0]`: 突发传输的长度,`N-1`。例如,`AWLEN=0`表示1个beat,`AWLEN=7`表示8个beat。

`AWSIZE[2:0]`: 每个beat的大小(如`3'b010`表示32位)。

`AWBURST[1:0]`: 突发类型 (`FIXED`, `INCR`, `WRAP`)。`INCR`(地址递增)最常用。

AWID`: 事务ID。用于乱序执行。

2. 写数据通道 (Write Data Channel - W)

方向: Master -> Slave

作用: Master传输突发中的实际数据。

关键信号:  

`WVALID`: Master置位,表示数据有效。

`WREADY`: Slave置位,表示准备好接收数据。

`WDATA`: 写数据总线(位宽可以是32, 64, ..., 1024)。

`WSTRB`: 写选通,字节使能。例如,在32位总线上,`WSTRB=4'b0011`表示只写入低16位。

`WLAST`: Master置位,表示这是本次突发的最后一个beat。

`WID`: 事务ID,必须与AW通道的ID匹配。

3. 写响应通道 (Write Response Channel - B)

方向: Slave -> Master

作用: Slave告知Master写操作已完成。

关键信号:

`BVALID`: Slave置位,表示响应有效。

`BREADY`: Master置位,表示准备好接收响应。

`BRESP[1:0]`: 响应状态(`OKAY`, `EXOKAY`, `SLVERR`, `DECERR`)。

`BID`: 事务ID,必须与AW/W通道的ID匹配。

4. 读地址通道 (Read Address Channel - AR)

方向: Master -> Slave

作用: Master发起一次读突发传输。

关键信号: 与写地址通道(AW)的信号几乎完全相同,只是前缀为`AR`。

5. 读数据通道 (Read Data Channel - R)

方向: Slave -> Master

作用: Slave将读取的数据回传给Master。

关键信号:

`RVALID`: Slave置位,表示数据有效。

`RREADY`: Master置位,表示准备好接收数据。

`RDATA`: 读数据总线。

`RLAST`: Slave置位,表示这是本次突发的最后一个beat。

`RRESP[1:0]`: 响应状态

`RID`: 事务ID,必须与AR通道的ID匹配。

第三部分:应用中的重难点

1. 乱序执行 (Out-of-Order Execution)

是什么: AXI允许Master发出多个不同ID的读/写请求,而Slave可以不按接收顺序完成这些请求。例如,Master先发出ID=1的读请求(访问慢速的DDR4),紧接着发出ID=2的读请求(访问快速的BRAM)。Slave可以先完成ID=2的请求并返回数据,然后再返回ID=1的数据。

难点

Master设计: Master必须能够同时跟踪多个正在进行中的事务。它需要根据返回的ID (`RID`/`BID`)来判断是哪个请求完成了。

Slave设计: 如果一个Slave连接到多个Master(通过AXI Interconnect),它也需要能够处理来自不同Master、ID不同的请求,并保证响应的ID正确。

实践建议: 对于初学者或简单的IP设计,可以不支持乱序,即一次只处理一个事务。只有在对性能有极致要求的高性能DMA或处理器接口中,才需要实现复杂的乱序处理逻辑。

2. 突发边界与对齐 (Burst Boundaries & Alignment)

是什么: AXI协议规定,一次`INCR`突发传输不能跨越4KB的地址边界。例如,你不能从地址`0x0FFC`开始,发起一次长度为8、每个beat为4字节的突发。因为`0x0FFC + 8*4 = 0x101C`,这跨越了`0x1000`这个4KB边界。

难点:

Master设计: Master在发起突发传输前,必须进行边界检查。如果一个逻辑上的大数据块跨越了4KB边界,Master必须将其拆分成两次或多次独立的AXI突发传输。

忽略的后果: 不遵守这个规则会导致行为未定义。AXI Interconnect或Slave可能会产生错误,或直接截断你的传输。

实践建议: 永远在你的AXI Master控制器中加入4KB边界检查和拆分逻辑。这是一个常见的bug来源。

3. 性能优化与死锁避免 (Performance & Deadlock)

性能瓶颈: AXI的性能取决于`VALID`/`READY`握手。如果一个Master发出了`AWVALID`,但Slave一直不给`AWREADY`,总线就会被阻塞 (stall)。

死锁风险: 死锁是一个非常危险且难以调试的问题。一个经典的死锁场景: Master A向Slave B发起写请求 (`AWVALID=1`),等待Slave B就绪。

同时,Slave B需要向Master A发起一个读请求(例如,读取一个状态)才能完成写操作。它发出了`ARVALID=1`。

如果Master A的设计是“必须等写响应回来后才能处理读请求”,那么它就不会给Slave B的`ARREADY`。

结果:A在等B,B在等A。系统永久锁死。

难点:

系统级视角: 死锁问题通常不是单个模块的问题,而是多个模块之间循环依赖造成的。你需要有系统级的思维来分析和避免它。

AXI Interconnect的作用: AXI互联矩阵(AXI Interconnect IP)是FPGA设计中用于连接多主多从的“路由器”。它内部有仲裁器和缓冲,能在一定程度上缓解阻塞,但如果存在设计层面的循环依赖,它也无能为力。

实践建议:

遵循依赖规则: 严格遵守AMBA协议推荐的Master/Slave之间的依赖关系,避免循环等待。

使用超时机制: 在Master中设计一个超时计数器。如果一个请求发出去很长时间都没有收到响应,就认为总线超时,产生一个中断或错误标志,以便系统进行恢复。

缓冲设计: 在Master和Slave中合理使用FIFO来缓冲数据,可以吸收临时的总线阻塞,平滑数据流,提高整体吞吐率。


原文链接:,转发请注明来源!