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握手成功的判断。
五组信号的完整握手流程
现在我们把三组通道串起来,看看一次完整的写操作是怎么进行的:
- 地址握手:主设备拉高AWVALID,从设备拉高AWREADY,完成地址传输。
- 数据握手:主设备拉高WVALID(同时发送数据),从设备拉高WREADY。重复直到最后一个数据(WLAST为高)。
- 响应握手:从设备拉高BVALID(携带响应状态),主设备拉高BREADY,完成响应传输。
这三步是顺序执行的。地址握手必须在数据握手之前完成?不一定。AXI协议允许地址和数据通道独立握手,但响应通道必须等数据通道完成后才能开始。
核心规则:
- 地址通道和数据通道可以并行握手
- 响应通道必须等待数据通道的WLAST握手成功
- 所有通道的握手都必须遵守VALID/READY协议
时序约束中的关键路径
从时序约束的角度看,写通道涉及以下关键路径:
| 路径 | 起点 | 终点 | 说明 |
|---|---|---|---|
| 地址路径 | 主设备时钟域 | 从设备时钟域 | AWVALID → AWREADY |
| 数据路径 | 主设备时钟域 | 从设备时钟域 | WVALID → WREADY |
| 响应路径 | 从设备时钟域 | 主设备时钟域 | BVALID → BREADY |
这些路径都需要在时序约束中明确声明。我个人的做法是:对每个通道单独设置set_max_delay约束,而不是统一约束。因为地址通道的时序要求通常比数据通道宽松一些。
SVG流程图:写通道握手时序
下面这张图展示了写通道三组信号的握手时序关系。我特意把依赖关系用箭头标出来了,方便你理解。
图中标出了三个握手成功点:
- 点1:地址握手成功(AWVALID & AWREADY)
- 点2:数据握手成功(WVALID & WREADY)
- 点3:响应握手成功(BVALID & BREADY)
注意看那条虚线箭头——它表示BVALID的拉高依赖于WLAST的握手成功。这是写通道时序中最容易忽略的依赖关系。
避坑指南
最后,我总结几个写通道时序设计中常见的坑:
- BVALID过早拉高:必须在WLAST握手成功后才能拉高BVALID。否则响应结果可能不准确。
- AWREADY持续拉高:如果从设备一直拉高AWREADY,主设备可能会连续发起多个写操作。确保从设备有足够的缓冲能力。
- WREADY拉低不及时:从设备接收FIFO满时,必须及时拉低WREADY。否则数据会丢失。
- 跨时钟域处理:如果主设备和从设备工作在不同时钟域,所有握手信号都需要做同步处理。我习惯用两级触发器同步。
我的小技巧:在仿真阶段,我会特意制造握手信号延迟的场景,测试从设备在各种时序条件下的表现。比如让WREADY随机拉高拉低,看看数据会不会丢。这种压力测试能发现很多隐藏问题。
写通道的时序约束,说白了就是确保五组信号在正确的时间点握手成功。只要抓住「地址先于数据,数据先于响应」这个核心逻辑,再加上对每个通道单独做时序约束,基本就不会出大问题。
可可精品资料库