AXI写通道时序:五组信号的握手博弈

写通道,说白了就是主设备把数据写进从设备的过程。这个过程涉及五组关键信号:地址通道的AWVALID/AWREADY、数据通道的WVALID/WREADY、以及响应通道的BVALID/BREADY。它们之间不是各玩各的,而是有着严格的依赖关系。

我刚开始接触AXI协议时,总觉得这些握手信号挺乱的。后来画了一张时序图,才真正看明白。今天我就把这五组信号的握手关系,掰开揉碎了讲给你听。

写地址通道:AWVALID与AWREADY

写地址通道负责传输写操作的起始地址。主设备通过AWVALID告诉从设备:「地址准备好了」。从设备通过AWREADY回应:「我收到了」。

握手成功的条件很简单:AWVALID和AWREADY同时为高。但这里有个细节——谁先拉高?

  • 主设备先拉高AWVALID:这是最常见的情况。主设备准备好地址后,拉高AWVALID,等待从设备拉高AWREADY。
  • 从设备先拉高AWREADY:从设备可以提前拉高AWREADY,表示「我随时可以接收」。主设备看到后,拉高AWVALID完成握手。

关键点:AWVALID一旦拉高,必须等到握手成功才能拉低。不能中途反悔。

我在项目中遇到过一个问题:从设备在复位期间把AWREADY拉高了,结果主设备复位释放后立刻发起传输,但此时从设备内部还没准备好。嗯,这里要注意——从设备的AWREADY必须在内部状态稳定后才能拉高,否则会出乱子。

写数据通道:WVALID与WREADY

数据通道的握手逻辑和地址通道类似。主设备通过WVALID表示数据有效,从设备通过WREADY表示可以接收。

但数据通道有个特殊之处:WLAST信号。它表示当前传输的是最后一个数据。从设备看到WLAST为高时,就知道这次突发传输结束了。

我的习惯:设计从设备时,我会让WREADY在内部FIFO有空位时才拉高。这样能避免数据溢出。你想想看,如果从设备接收速度跟不上,主设备又一直发数据,那不就丢数据了吗?

数据通道的握手时序,说白了就是主设备发数据,从设备收数据。两者节奏必须匹配。我曾经见过一个设计,主设备连续发了16个数据,但从设备只收了8个就罢工了——因为WREADY拉低得太晚,导致FIFO写满。

写响应通道:BVALID与BREADY

写响应通道是写操作的收尾环节。从设备完成写操作后,通过BVALID返回响应状态(OKAY、EXOKAY、SLVERR、DECERR)。主设备通过BREADY表示收到了响应。

这里有个容易踩的坑:BVALID必须在WLAST握手成功之后才能拉高。为什么?因为从设备必须确认所有数据都收到了,才能给出响应。你想想看,如果数据还没传完,从设备就返回响应,那响应结果能准吗?

我曾经踩过的坑:在设计一个DMA控制器时,我把BVALID和WLAST的依赖关系搞反了。结果仿真时发现,从设备在数据还没传完时就返回了SLVERR。查了三天才找到原因——BVALID的拉高条件里少了一个WLAST握手成功的判断。

五组信号的完整握手流程

现在我们把三组通道串起来,看看一次完整的写操作是怎么进行的:

  1. 地址握手:主设备拉高AWVALID,从设备拉高AWREADY,完成地址传输。
  2. 数据握手:主设备拉高WVALID(同时发送数据),从设备拉高WREADY。重复直到最后一个数据(WLAST为高)。
  3. 响应握手:从设备拉高BVALID(携带响应状态),主设备拉高BREADY,完成响应传输。

这三步是顺序执行的。地址握手必须在数据握手之前完成?不一定。AXI协议允许地址和数据通道独立握手,但响应通道必须等数据通道完成后才能开始。

核心规则:

  • 地址通道和数据通道可以并行握手
  • 响应通道必须等待数据通道的WLAST握手成功
  • 所有通道的握手都必须遵守VALID/READY协议

时序约束中的关键路径

从时序约束的角度看,写通道涉及以下关键路径:

路径 起点 终点 说明
地址路径 主设备时钟域 从设备时钟域 AWVALID → AWREADY
数据路径 主设备时钟域 从设备时钟域 WVALID → WREADY
响应路径 从设备时钟域 主设备时钟域 BVALID → BREADY

这些路径都需要在时序约束中明确声明。我个人的做法是:对每个通道单独设置set_max_delay约束,而不是统一约束。因为地址通道的时序要求通常比数据通道宽松一些。

SVG流程图:写通道握手时序

下面这张图展示了写通道三组信号的握手时序关系。我特意把依赖关系用箭头标出来了,方便你理解。

AXI写通道握手时序 CLK AWVALID AWREADY 1 WVALID WREADY WLAST 2 BVALID BREADY 3 依赖 主设备驱动 从设备驱动 握手成功点 依赖关系

图中标出了三个握手成功点:

  • 点1:地址握手成功(AWVALID & AWREADY)
  • 点2:数据握手成功(WVALID & WREADY)
  • 点3:响应握手成功(BVALID & BREADY)

注意看那条虚线箭头——它表示BVALID的拉高依赖于WLAST的握手成功。这是写通道时序中最容易忽略的依赖关系。

避坑指南

最后,我总结几个写通道时序设计中常见的坑:

  • BVALID过早拉高:必须在WLAST握手成功后才能拉高BVALID。否则响应结果可能不准确。
  • AWREADY持续拉高:如果从设备一直拉高AWREADY,主设备可能会连续发起多个写操作。确保从设备有足够的缓冲能力。
  • WREADY拉低不及时:从设备接收FIFO满时,必须及时拉低WREADY。否则数据会丢失。
  • 跨时钟域处理:如果主设备和从设备工作在不同时钟域,所有握手信号都需要做同步处理。我习惯用两级触发器同步。

我的小技巧:在仿真阶段,我会特意制造握手信号延迟的场景,测试从设备在各种时序条件下的表现。比如让WREADY随机拉高拉低,看看数据会不会丢。这种压力测试能发现很多隐藏问题。

写通道的时序约束,说白了就是确保五组信号在正确的时间点握手成功。只要抓住「地址先于数据,数据先于响应」这个核心逻辑,再加上对每个通道单独做时序约束,基本就不会出大问题。

可可精品资料库