3. AXI握手协议:VALID/READY机制、握手依赖关系、传输完成条件

AXI总线最核心的机制,就是VALID和READY这对握手信号。说白了,它们就像两个人打电话——一个人说“我有话要说”(VALID),另一个人说“我准备好了听”(READY)。只有两边都准备好了,信息才能传过去。

我在项目中见过不少新手,上来就写AXI代码,结果仿真死活不通。最后发现,都是握手协议没搞明白。嗯,今天我们就把它彻底讲清楚。

3.1 VALID/READY基本握手规则

AXI的每个通道(地址、数据、写响应)都遵循同样的握手规则。规则其实就三条:

  • VALID不能依赖READY:发送方可以随时拉高VALID,不需要等接收方准备好。这是协议明确规定的。
  • READY可以等VALID:接收方可以在VALID拉高后再拉高READY,也可以提前拉高。两种都合法。
  • 传输只在VALID和READY同时为高时发生:这是铁律,没有例外。

重要:一旦VALID拉高,就不能再拉低,直到握手成功。这是很多新手容易犯的错——以为可以反悔。不行!VALID必须保持稳定,直到READY也拉高,传输完成。

3.2 三种握手场景

实际项目中,握手有三种常见场景。我习惯把它们画成时序图来理解:

场景 描述 典型应用
VALID先到 发送方先拉高VALID,接收方稍后拉高READY 从设备处理速度慢于主设备时
READY先到 接收方提前拉高READY,等待发送方拉高VALID 从设备始终准备好接收数据时
同时到达 VALID和READY在同一时钟沿同时拉高 零等待传输,性能最优

你想想看,第三种场景是不是最理想?没错,零等待传输是性能调优的目标之一。但实际中,从设备往往需要几个周期才能准备好,所以第一种场景更常见。

3.3 握手依赖关系——这个坑我踩过

AXI协议里有个容易忽略的点:通道间的握手依赖关系。说白了,就是不同通道的VALID和READY之间,存在隐形的先后顺序。

我曾经在一个项目中,设计了一个写数据通道,结果仿真时发现数据总是丢。查了两天才发现,是写地址通道和写数据通道的握手顺序搞反了。

避坑指南:我曾经在调试一个DMA控制器时,让写数据通道的VALID等写地址通道的READY。结果协议分析仪报错——这违反了AXI的依赖规则。正确的做法是:写地址和写数据通道可以独立握手,但写响应通道必须等写数据通道完成后才能开始。

具体来说,依赖关系是这样的:

  • 读地址通道:独立,不依赖其他通道
  • 读数据通道:必须等读地址通道握手完成后才能开始
  • 写地址通道:独立,不依赖其他通道
  • 写数据通道:独立,不依赖其他通道
  • 写响应通道:必须等写地址和写数据通道都完成后才能开始

嗯,这里要注意:写地址和写数据通道是独立并行的。它们可以同时握手,也可以一先一后。但写响应必须等两者都完成。

3.4 传输完成条件

一个AXI传输什么时候算完成?很多人以为只要数据过去了就行。其实没那么简单。

一个完整的AXI传输,需要满足三个条件:

  1. 地址通道握手成功:地址和控制信息已经传递给从设备
  2. 数据通道握手成功:所有数据(包括最后的last信号)已经传递完成
  3. 响应通道握手成功:从设备返回了BRESP或RRESP响应

对于突发传输(burst),数据通道的传输完成条件更严格:

  • 每个数据节拍(beat)都需要VALID和READY同时为高
  • 最后一个数据节拍必须同时拉高LAST信号
  • 所有数据节拍完成后,才能开始响应通道的握手

小技巧:我习惯在验证环境中加一个断言,检查LAST信号是否在最后一个数据节拍时拉高。这个断言帮我抓到了至少三个bug。你可以在自己的testbench里试试。

3.5 握手协议的核心逻辑图

下面我用一张流程图,把整个握手协议的知识体系串起来。这张图是我自己总结的,每次带新人时都会拿出来讲一遍。

AXI握手协议核心逻辑 传输开始 VALID=1? 否 等待VALID 是 READY=1? 否 等待READY 传输完成 检查通道依赖关系 传输结束 开始/结束 判断节点 完成节点 依赖检查

这张图的核心逻辑很简单:VALID和READY必须同时为高,传输才能发生。但实际项目中,你还要考虑通道间的依赖关系。我建议你在写RTL代码时,先把这张图的逻辑理清楚,再动手写代码。

3.6 实战中的几个要点

最后,分享几个我在项目中总结的要点:

  • 不要用组合逻辑产生VALID:VALID应该由寄存器输出,否则时序容易出问题。我见过有人用组合逻辑,结果后仿时一堆setup违例。
  • READY可以提前拉高:如果从设备始终能接收数据,READY可以一直拉高。这样主设备发数据时就能零等待传输。
  • 小心死锁:如果两个模块互相等待对方的VALID和READY,就会死锁。我曾经在一个多主设备系统中遇到过,最后加了一个超时机制才解决。
  • 验证时覆盖所有握手场景:三种握手场景都要验证到。我习惯在testbench里用约束随机,确保三种场景都能覆盖。

个人习惯:我写AXI从设备时,会先让READY默认拉高,然后根据内部状态再拉低。这样大部分传输都能零等待,性能最好。只有在FIFO快满时,才拉低READY进行反压。

好了,AXI握手协议就讲到这里。记住三条规则、三种场景、五个依赖关系,你就能搞定大部分AXI设计问题了。

可可精品资料库