4. AXI4接口协议:AXI4-Full与AXI4-Stream的区别、握手信号、突发传输
大家好,我是你们的FPGA实战讲师。今天我们来聊聊AXI4协议,这是DDR读写和卷积加速里绕不开的核心。说实话,很多新手一看到AXI的波形图就头大,各种通道、握手、突发,感觉像天书。别急,我用实战经验帮你拆开揉碎了讲。
4.1 AXI4-Full vs AXI4-Stream:到底差在哪?
先问个问题:为什么要有两种AXI4?
我个人习惯把AXI4-Full想象成「带地址的总线快递」。你想从DDR里读数据,得先告诉它地址:我要读地址0x1000开始的256字节。然后DDR控制器找到数据,再打包送回来。整个过程有地址通道、读数据通道、写数据通道,各走各的,互不干扰。
而AXI4-Stream呢?说白了就是「流水线传送带」。没有地址,没有握手之外的任何控制。数据从上游流到下游,一拍一拍往前推。我在做图像处理加速时,像素数据就是典型的Stream流——一个时钟进来一个像素,处理完再流出去,根本不需要地址。
| 对比项 | AXI4-Full | AXI4-Stream |
|---|---|---|
| 地址通道 | 有(读地址/写地址) | 无 |
| 数据通道 | 读数据/写数据分开 | 单一数据流 |
| 握手信号 | VALID/READY + 其他控制 | VALID/READY + TLAST/TKEEP等 |
| 典型应用 | DDR读写、寄存器配置 | 视频流、DMA数据搬运 |
嗯,这里要注意:AXI4-Stream其实可以看作是AXI4-Full的简化版。如果你只需要搬数据,不需要随机访问,那就用Stream。我在卷积加速项目里,输入特征图走Stream,权重走Stream,但DDR的读写必须走Full——因为你要告诉DDR「从哪个地址开始读」。
4.2 握手信号:VALID和READY的默契配合
AXI的握手,核心就两个信号:VALID和READY。但很多人在这个地方翻过车。
简单说:发送方拉高VALID,表示「我这拍数据有效」;接收方拉高READY,表示「我这拍能收数据」。数据在VALID和READY同时为高的时钟上升沿传输。
我曾经在一个项目里,因为没处理好READY的时序,导致数据丢了一拍。排查了整整两天,最后发现是READY信号在组合逻辑里产生了毛刺。从那以后,我养成了一个习惯:所有READY信号必须用寄存器打一拍,哪怕多一个时钟延迟,也比丢数据强。
握手传输的三种情况:
- 情况A:VALID先高,READY后高——发送方准备好,等接收方。最常见。
- 情况B:READY先高,VALID后高——接收方准备好,等数据来。比如FIFO非满时。
- 情况C:同时拉高——一拍传输,效率最高。理想情况。
你想想看,如果发送方一直拉高VALID,接收方偶尔拉高READY,那数据就是「断断续续地流」。这在Stream里很常见——上游像素源源不断,但下游卷积计算单元偶尔忙不过来,就拉低READY让上游等一等。
4.3 突发传输:为什么DDR读写离不开它?
突发传输(Burst)是AXI4-Full的精髓。没有突发,DDR的带宽利用率会惨不忍睹。
为什么?因为DDR每次访问都有「行激活」和「列选通」的开销。如果你一次只读一个32位数据,那大部分时间都浪费在地址切换上了。突发传输允许你一次发起地址,连续传输多个数据,就像你告诉快递员「把整条街的包裹都取了」,而不是「取一个,回来,再取下一个」。
AXI4-Full的突发有三个关键参数:
- ARLEN/AWLEN:突发长度,表示一次传输多少个数据。比如ARLEN=7表示传8个数据(长度+1)。
- ARSIZE/AWSIZE:每个数据多少字节。2'b010表示4字节,2'b011表示8字节。
- ARBURST/AWBURST:突发类型。固定地址(FIXED)、递增地址(INCR)、回绕地址(WRAP)。
我在DDR读写控制器里,最常用的是INCR模式。比如从地址0x1000开始,突发长度16,每次4字节,那地址就是0x1000、0x1004、0x1008……直到0x103C。DDR控制器会自动递增地址,你只需要在第一个时钟给出起始地址和突发参数,后面就等着收数据就行了。
实战小技巧:突发长度不要设得太大。虽然理论上可以设到256,但DDR控制器内部有FIFO深度限制。我一般设16或32,既能充分利用带宽,又不会让控制器溢出。具体值要看你的DDR IP核手册。
4.4 核心逻辑:一张图看懂AXI4-Full读写流程
下面这张图是我自己画的,把AXI4-Full的读操作流程画清楚了。写操作类似,只是多了写响应通道。
这张图里,读地址通道和读数据通道是分开的。主设备先发地址,从设备收到后开始准备数据,然后通过读数据通道返回。注意RLAST信号——它在最后一拍数据时拉高,告诉主设备「这次突发结束了」。
避坑指南:我曾经在写AXI4-Full从机时,忘了处理RLAST信号。结果主设备一直等下一拍数据,系统死锁。记住:突发传输必须有RLAST(读)或WLAST(写)来标记结束,否则对方不知道什么时候该停。
4.5 Stream的握手:更简单,但别大意
AXI4-Stream的握手和Full一样,也是VALID/READY。但Stream多了一个TLAST信号——它标记帧的结束。比如一帧图像有1920个像素,那第1920个像素传输时,TLAST必须拉高。
我在做卷积加速时,输入特征图是Stream流,但卷积核是3x3的滑动窗口。这时候TLAST就很重要——它告诉卷积控制器「这一行结束了,下一行要开始了」。如果没有TLAST,控制器就不知道什么时候该换行,卷积结果会完全错乱。
Stream还有一个TKEEP信号,用来标记哪些字节是有效的。比如你传的数据宽度是64位,但最后一拍只有32位有效,那就用TKEEP来指示。不过说实话,大部分场景下TKEEP可以固定为全1,除非你做数据打包解包。
4.6 实战经验总结
最后,我把自己踩过的坑和心得列出来,希望对你有帮助:
- 握手信号必须寄存:组合逻辑的READY容易出毛刺,用寄存器打一拍,稳如老狗。
- 突发长度别贪大:16或32是黄金值,既能利用带宽,又不会撑爆FIFO。
- RLAST/WLAST不能忘:没有结束标记,总线会一直等,系统死锁。
- Stream的TLAST一定要对齐:帧结束标记错位,数据流就全乱了。
- 仿真时多检查握手时序:用$display打印VALID和READY的波形,一眼就能看出问题。
嗯,AXI4协议就讲到这里。记住一句话:Full负责「去哪拿」,Stream负责「流过去」。搞懂了这两个的区别和握手细节,DDR读写和卷积加速的接口设计就成功了一半。