AXI协议基础回顾:通道、握手与事务流程
做芯片验证这么多年,我接触最多的总线协议就是AXI。说实话,刚入行那会儿觉得AXI协议挺复杂的——五个通道、各种握手规则、还有地址对齐的问题。但后来我发现,只要把几个核心概念吃透了,剩下的都是套路。
今天咱们就一起回顾一下AXI协议的基础。这部分内容虽然基础,但却是排查约束冲突的根基。你想想看,如果连握手信号怎么工作都搞不清楚,后面分析时序问题肯定会一头雾水。
一、AXI的五个独立通道
AXI协议最鲜明的特点,就是采用了通道分离的架构。它把读写操作拆成了五个独立的通道:
| 通道名称 | 方向(Master→Slave) | 方向(Slave→Master) | 传输内容 |
|---|---|---|---|
| 读地址通道(AR) | ✓ | 读请求的地址、长度、大小等 | |
| 读数据通道(R) | ✓ | 读回来的数据,以及响应信号 | |
| 写地址通道(AW) | ✓ | 写请求的地址、长度、大小等 | |
| 写数据通道(W) | ✓ | 要写入的数据,每拍带字节使能 | |
| 写响应通道(B) | ✓ | 写操作完成后的状态响应 |
我个人习惯把AXI想象成一条双向四车道的高速公路。读和写各走各的道,互不干扰。这也是AXI能实现高吞吐量的原因之一。
关键点:五个通道之间是解耦的。这意味着读操作和写操作可以完全并行执行。我在项目中遇到过不少新人,总以为读操作必须等写操作完成才能开始——其实完全不用。
二、握手信号与VALID/READY机制
每个通道都有一对核心握手信号:VALID 和 READY。说白了,这就是一个「我准备好了,你准备好了吗?」的对话机制。
- VALID:发送方告诉接收方「我这边的数据/地址已经有效了,你可以取了」
- READY:接收方告诉发送方「我准备好接收了,你随时可以发」
握手成功(即传输发生)的条件只有一个:VALID和READY同时为高,并且在时钟上升沿被采样到。
这里有个常见的握手时序场景:
// 场景1:VALID先有效,READY后有效
// 发送方先准备好数据,等待接收方
always @(posedge clk) begin
if (rst) begin
valid <= 1'b0;
end else begin
// 数据准备好后,拉高VALID
valid <= data_ready;
end
end
// 场景2:READY先有效,VALID后有效
// 接收方先表示可以接收,发送方再给出数据
always @(posedge clk) begin
if (rst) begin
ready <= 1'b1; // 默认准备好接收
end else begin
// 根据内部状态控制READY
ready <= can_accept;
end
end
我的经验:在做时序约束时,VALID和READY路径的约束要特别小心。我曾经在一个项目中,因为READY信号路径上插了太多组合逻辑,导致握手时序紧张。后来我建议把READY做成寄存器输出,问题就解决了。
三、读写事务流程
咱们分别看看读和写是怎么走的。
读事务流程
- Master 通过 AR通道 发送读地址和控制信息
- Slave 收到后,开始准备数据
- Slave 通过 R通道 返回数据,同时携带 RLAST 信号(最后一拍时拉高)
- Master 收到 RLAST 为高的数据后,读事务结束
读事务中,Master发出地址后,可以不等数据回来就发下一个地址。这就是乱序传输的基础。嗯,这里要注意,Slave返回数据时,必须保证和地址的对应关系正确。
写事务流程
- Master 通过 AW通道 发送写地址
- Master 通过 W通道 发送写数据,最后一拍拉高 WLAST
- Slave 接收完所有数据后,通过 B通道 返回写响应
写事务有个特点:地址和数据可以同时发送,也可以地址先发、数据后发。我在项目中见过一种优化写法——把AW和W的VALID同时拉高,这样Slave可以一次性处理,减少等待周期。
避坑指南:我曾经在一个DMA控制器验证中,发现写响应B通道的时序约束总是报错。排查了半天,原来是Slave在收到WLAST之前就返回了B响应——这违反了协议规范。记住:写响应必须在所有数据都接收完成后才能返回。
四、突发传输与地址对齐
AXI支持突发传输(Burst),也就是一次地址请求可以传输多个数据。突发传输有三个关键参数:
- AxLEN:突发长度,表示传输的数据拍数。注意:实际拍数 = AxLEN + 1
- AxSIZE:每拍数据的字节数。比如 2 表示 4 字节,3 表示 8 字节
- AxBURST:突发类型。FIXED(固定地址)、INCR(递增地址)、WRAP(回环地址)
地址对齐是约束排查中经常踩坑的地方。什么叫地址对齐?说白了就是:起始地址必须能被每拍数据的大小整除。
举个例子:
// 假设 AxSIZE = 2(4字节),AxLEN = 3(4拍)
// 起始地址 0x1000 —— 对齐,因为 0x1000 % 4 == 0
// 起始地址 0x1001 —— 不对齐!因为 0x1001 % 4 != 0
// 不对齐时,AXI协议允许Master发送非对齐地址
// 但Slave必须能正确处理,否则会出问题
为什么地址对齐这么重要?因为很多Slave(比如DDR控制器、SRAM接口)只支持对齐访问。如果Master发了一个非对齐地址,Slave要么报错,要么默默丢弃低几位地址——这就会导致数据错位。
核心结论:在做时序约束时,地址通道的路径必须考虑对齐逻辑。如果设计中包含了地址对齐的修正逻辑(比如把非对齐地址拆成多个对齐访问),那这部分逻辑的时序一定要重点检查。
五、知识体系总览
下面这张图是我自己整理的AXI基础知识框架,涵盖了咱们刚才讲的所有内容:
这张图把AXI的五个通道、握手机制、读写事务流程和突发传输串在了一起。我个人觉得,做时序约束时最需要关注的就是握手路径和地址对齐逻辑这两块——它们往往是约束冲突的高发区。
好了,AXI协议的基础就回顾到这里。这些内容虽然看起来简单,但实际项目中遇到的很多时序问题,追根溯源都能回到这些基本概念上。记住:协议理解得越深,约束做得越稳。
一个小建议:如果你刚开始接触AXI时序约束,不妨先从单个通道的VALID/READY路径入手。把一条路径的约束做对了,其他通道就是依葫芦画瓢。我当年就是这么过来的。