2、AXI通道与握手协议:读地址通道(AR)、读数据通道(R)、写地址通道(AW)、写数据通道(W)、写响应通道(B)、VALID/READY握手机制
AXI协议的核心,说白了就是五个独立的通道加上一套握手机制。很多刚接触AXI的同学会被这五个通道吓到,觉得好复杂。其实你想想看,它就是把一次总线传输拆成了几个独立的阶段,每个阶段各走各的道,互不干扰。
我个人习惯把AXI的通道想象成一条生产线:地址通道是下订单,数据通道是送货,响应通道是签收单。读和写是两条独立的生产线,可以同时开工。
2.1 五个通道概览
AXI5个通道各司其职,我们先看个总览表:
| 通道名称 | 方向 | 传输内容 | 关键信号 |
|---|---|---|---|
| 读地址通道 (AR) | 主机→从机 | 读请求的地址、长度、大小等 | ARVALID, ARREADY, ARADDR, ARLEN, ARSIZE, ARBURST |
| 读数据通道 (R) | 从机→主机 | 读回来的数据,以及读响应状态 | RVALID, RREADY, RDATA, RRESP, RLAST |
| 写地址通道 (AW) | 主机→从机 | 写请求的地址、长度、大小等 | AWVALID, AWREADY, AWADDR, AWLEN, AWSIZE, AWBURST |
| 写数据通道 (W) | 主机→从机 | 要写入的数据,以及字节选通信号 | WVALID, WREADY, WDATA, WSTRB, WLAST |
| 写响应通道 (B) | 从机→主机 | 写操作完成后的状态反馈 | BVALID, BREADY, BRESP |
关键点:读操作只需要2个通道(AR + R),写操作需要3个通道(AW + W + B)。写操作之所以多一个B通道,是因为从机需要告诉主机"数据我已经收好了,写成功了"。
2.2 VALID/READY握手机制
AXI的通道之间靠什么传递信息?就是VALID和READY这一对信号。这是AXI最基础也最重要的机制。
说白了,VALID表示"我有数据要给你",READY表示"我准备好接收了"。只有两者同时有效,数据才算真正传输成功。
2.2.1 三种握手场景
我在项目中调试过很多次握手时序问题,总结下来就三种情况:
- VALID先有效,READY后有效:发送方先准备好数据,等待接收方准备好。这是最常见的场景。
- READY先有效,VALID后有效:接收方提前告知"我准备好了",发送方随后给出数据。
- VALID和READY同时有效:一拍完成传输,效率最高。
嗯,这里要注意:VALID可以依赖READY,但READY不能依赖VALID。什么意思?发送方可以等接收方READY了再拉VALID,但接收方不能等看到VALID才拉READY——除非你明确知道自己在做什么。
避坑指南:我曾经在一个项目中,从机的READY信号设计成"看到VALID才拉READY",结果导致死锁——主机也在等READY才拉VALID,两边互相等待,总线直接卡死。这种组合逻辑依赖链一定要避免。
2.2.2 握手时序图
下面这张图展示了VALID/READY握手的三种场景:
2.3 读操作流程
读操作分两步走:先发地址,再收数据。
2.3.1 读地址通道 (AR)
主机通过AR通道告诉从机:我要读哪个地址,读多少数据。关键信号包括:
- ARADDR:读起始地址
- ARLEN:突发长度,表示一次读操作包含多少笔数据传输(实际笔数 = ARLEN + 1)
- ARSIZE:每笔数据的大小(字节数 = 2^ARSIZE)
- ARBURST:突发类型(FIXED/INCR/WRAP)
小技巧:调试时我习惯先看ARLEN和ARSIZE是否匹配。有一次从机返回的数据总是不对,查了半天发现ARLEN设成了3(4笔),但ARSIZE设成了4(16字节),地址步进算错了。这种参数不匹配的问题在互联调试中非常常见。
2.3.2 读数据通道 (R)
从机通过R通道把数据返回给主机。这里有个重要信号——RLAST,它标志着一笔读突发的最后一笔数据。
举个例子:如果ARLEN=3(共4笔数据),那么第4笔数据时RLAST必须拉高。主机看到RLAST就知道这次读操作结束了。
R通道还有一个RRESP信号,表示读操作的状态:
| RRESP[1:0] | 含义 | 说明 |
|---|---|---|
| 00 | OKAY | 正常访问成功 |
| 01 | EXOKAY | 独占访问成功 |
| 10 | SLVERR | 从机错误(地址未映射、不支持等) |
| 11 | DECERR | 译码错误(地址不在任何从机范围内) |
2.4 写操作流程
写操作比读操作多一个通道,因为写完后从机需要给个回执。
2.4.1 写地址通道 (AW)
和AR通道几乎一样,只是方向不同。AWADDR、AWLEN、AWSIZE、AWBURST这些信号的含义和读通道完全对应。
2.4.2 写数据通道 (W)
主机通过W通道发送要写入的数据。这里多了一个WSTRB信号,它是字节选通信号,用来控制哪些字节被真正写入。
比如数据总线是32位(4字节),WSTRB[3:0]的每一位对应一个字节。如果只想写最低字节,就把WSTRB设为4'b0001。
我曾经踩过的坑:有一次写数据总是写不进去,波形上看WDATA和WSTRB都对,但就是没反应。最后发现是WVALID和WREADY握手完成后,WSTRB在下一拍才稳定。从机在握手成功的时钟沿采样WSTRB,采到的值是错的。记住:所有信号必须在VALID和READY同时有效的时钟沿保持稳定。
2.4.3 写响应通道 (B)
从机收完所有写数据后,通过B通道返回写响应。注意:B通道的响应是在整个写突发完成后才发出的,不是每笔数据都发一次。
BRESP的编码和RRESP一样:OKAY、EXOKAY、SLVERR、DECERR。
2.5 通道间的依赖关系
五个通道虽然独立,但存在一些逻辑上的依赖关系。我画了一张图来说明:
2.6 握手协议的关键规则
最后总结几条硬性规则,调试时对照着查:
- 规则1:VALID一旦拉高,必须保持到握手成功(即READY为高且时钟上升沿到来),不能中途撤销。
- 规则2:READY可以拉高后再次拉低,但建议保持到握手成功,避免不必要的逻辑复杂度。
- 规则3:数据和控制信号必须在VALID和READY同时有效的时钟沿保持稳定。
- 规则4:RLAST必须在读突发的最后一笔数据时拉高,WLAST必须在写突发的最后一笔数据时拉高。
- 规则5:B通道的响应必须在所有W数据握手完成后才能发出。
实战建议:刚开始写AXI总线代码时,我建议先画一个简单的握手状态机。把VALID和READY的交互逻辑理清楚再动手写RTL。我见过太多人一上来就写代码,结果仿真时握手时序各种问题,回头改代码比重新写还痛苦。