3. AXI总线协议详解:AXI4、AXI4-Lite、AXI4-Stream协议对比、握手信号与时序、在Zynq中的实际应用
AXI总线,说白了就是Zynq里PS和PL之间沟通的“高速公路”。我刚接触Zynq时,总觉得协议细节太多,后来踩了几个坑才明白——搞懂AXI,硬件加速就成功了一半。
本章咱们把三种AXI协议掰开揉碎,看看它们到底有什么区别,握手怎么握,以及在Zynq里怎么用。
3.1 三种AXI协议:各司其职
AXI家族有三个成员,每个都有自己的定位。我习惯这么记:AXI4是“大卡车”,拉得多跑得快;AXI4-Lite是“自行车”,轻便但载重小;AXI4-Stream是“传送带”,只管流数据不管地址。
| 特性 | AXI4 | AXI4-Lite | AXI4-Stream |
|---|---|---|---|
| 数据宽度 | 8~1024位,支持突发 | 固定32位,不支持突发 | 任意宽度,流式传输 |
| 地址通道 | 有,支持多地址 | 有,单地址 | 无地址 |
| 典型场景 | DDR读写、大数据块传输 | 寄存器配置、状态读取 | 视频流、数据流处理 |
| 握手复杂度 | 高(5个独立通道) | 中(5个通道但简化) | 低(仅数据通道) |
核心区别一句话:AXI4面向高性能内存映射传输,AXI4-Lite面向控制寄存器访问,AXI4-Stream面向连续数据流处理。
3.2 握手信号与时序:VALID/READY机制
三种AXI协议都使用相同的握手方式——VALID/READY。这个机制其实很简单:发送方说“我有数据”(VALID拉高),接收方说“我能接收”(READY拉高),两者同时有效时,数据就传过去了。
我曾经在调试一个视频加速器时,发现数据总是丢帧。查了两天才找到原因——发送端的VALID信号在READY没准备好时就撤回了。嗯,这里要注意:VALID一旦拉高,必须等到握手成功才能拉低,这是协议的铁律。
握手有三种典型时序:
- READY先于VALID:接收方提前准备好,发送方随时可以发起传输
- VALID先于READY:发送方准备好数据,等待接收方就绪
- 同时有效:一拍完成传输,效率最高
我的设计习惯:在写AXI从机逻辑时,我会让READY默认拉高(除非内部FIFO满),这样只要VALID有效就能立即握手,减少等待周期。
3.3 AXI4:高性能内存映射传输
AXI4有5个独立通道:读地址、读数据、写地址、写数据、写响应。每个通道都有自己的VALID/READY握手。
突发传输是AXI4的精髓。你可以一次发起一个突发,指定起始地址和长度(1~256拍),然后连续传输数据。我做过一个图像处理加速器,用AXI4从DDR读取一帧图像,突发长度设为256,带宽利用率能达到90%以上。
// AXI4写事务示例(Verilog伪代码)
always @(posedge clk) begin
if (awvalid & awready) begin
// 写地址握手成功,记录起始地址和突发长度
addr_q <= awaddr;
burst_len_q <= awlen; // 实际长度 = awlen + 1
end
if (wvalid & wready) begin
// 写数据握手成功,数据写入内部FIFO
fifo_wr_data <= wdata;
wstrb_q <= wstrb; // 字节使能,用于部分写入
beat_cnt <= beat_cnt + 1;
end
if (beat_cnt == burst_len_q & wlast) begin
// 最后一拍数据,发送写响应
bvalid <= 1'b1;
bresp <= 2'b00; // OKAY响应
end
end
避坑指南:我曾经在AXI4写响应通道上吃过亏——主机发出写数据后,从机必须在有限拍内返回写响应。如果从机处理不及时,主机可能挂死。所以,写响应逻辑一定要用状态机独立处理,别跟数据通路混在一起。
3.4 AXI4-Lite:轻量级控制通道
AXI4-Lite是AXI4的简化版。它不支持突发,每次只能读写一个32位数据。但正因为简单,它特别适合做寄存器配置。
在Zynq里,PS通过AXI4-Lite访问PL中的控制寄存器。我一般这样分配地址空间:
- 基地址+0x00:控制寄存器(启动/停止加速器)
- 基地址+0x04:状态寄存器(忙/完成/错误标志)
- 基地址+0x08~0x1C:参数寄存器(图像尺寸、阈值等)
AXI4-Lite的时序比AXI4简单得多。写事务只需要地址握手、数据握手、响应握手三步。读事务则是地址握手后,从机在数据通道返回数据。
实用技巧:AXI4-Lite的地址通道和数据通道可以并行处理。我习惯让地址通道先握手,数据通道在下一拍再握手,这样时序更容易收敛。
3.5 AXI4-Stream:无地址的流式传输
AXI4-Stream是三种协议里最特殊的——它没有地址通道,只有数据通道。数据从上游流到下游,每个时钟周期可以传输一拍数据。
它的核心信号只有几个:
| 信号 | 宽度 | 说明 |
|---|---|---|
| TVALID | 1 | 发送方数据有效 |
| TREADY | 1 | 接收方可以接收 |
| TDATA | 8/16/32/64/128... | 数据总线 |
| TLAST | 1 | 数据包结束标志 |
| TKEEP | TDATA/8 | 字节有效标志 |
我在做视频处理时,AXI4-Stream用得最多。摄像头采集的数据通过Stream流入,经过滤波、缩放等处理,再通过Stream流出。整个过程不需要地址,数据像流水一样自动推进。
设计经验:AXI4-Stream的TLAST信号很容易被忽略。我建议在数据包的第一拍就确定包长,并在最后一拍拉高TLAST。如果包长不确定,可以用TKEEP来标记有效字节。
3.6 在Zynq中的实际应用
Zynq里,三种AXI协议各司其职,配合使用:
- PS→PL:通过AXI4-Lite配置加速器参数,通过AXI4传输大数据块
- PL内部:模块之间用AXI4-Stream连接,形成流水线
- PL→PS:处理结果通过AXI4写回DDR,状态通过AXI4-Lite上报
下面这张图展示了典型的硬件加速系统架构:
实际项目案例:我做过一个实时边缘检测加速器。PS通过AXI4-Lite配置阈值参数,通过AXI4将图像帧从DDR搬入PL。PL内部用AXI4-Stream连接Sobel算子模块和阈值模块。处理完一帧后,PL通过AXI4将结果写回DDR,并触发中断通知PS。整个流水线延迟只有几微秒。
3.7 协议选择指南
总结一下,在Zynq项目里怎么选:
- 控制通路:用AXI4-Lite,简单可靠,时序容易收敛
- 数据通路(大块传输):用AXI4,突发传输效率高
- 数据通路(流式处理):用AXI4-Stream,无地址开销,适合流水线
最后提醒:AXI4-Stream虽然简单,但要注意TLAST和TKEEP的正确使用。我见过有人把TLAST漏掉,结果下游模块永远不知道数据包什么时候结束,整个系统卡死。嗯,这种bug最难查,因为波形上看不出明显错误。