二、总线协议基础:AXI4-Stream与AXI4-Full详解
好,咱们进入第二章。这一章我打算聊聊总线协议,具体就是AXI4-Stream和AXI4-Full。说实话,总线协议这东西,刚接触时容易觉得枯燥。但你要是做过几个高速项目,就会明白——选对协议,设计就成功了一半。
2.1 AXI4-Stream协议详解
AXI4-Stream,我习惯叫它“流式接口”。它特别简单,说白了就是一条单向的数据管道。没有地址,没有握手响应,数据只管往前推。
核心信号就这几个:
- TVALID:发送端说“我有数据了”
- TREADY:接收端说“我准备好了”
- TDATA:数据总线,宽度可以自定义
- TLAST:告诉对方“这是最后一个数据”
- TKEEP:指示哪些字节是有效的
你想想看,一个视频流、一个ADC采样流,或者一个FIFO的输出,用AXI4-Stream再合适不过了。我在做图像处理加速器时,整个数据通路全是Stream接口,一个模块接一个模块,像流水线一样。
握手规则:TVALID和TREADY同时为高时,数据才被传输。这个规则简单,但容易出错。我曾经踩过一个坑——TVALID在复位后没拉低,导致接收端误以为有数据。
一个典型的Stream传输示例:
// AXI4-Stream发送端示例
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
tvalid <= 1'b0;
tdata <= 'd0;
tlast <= 1'b0;
end else begin
if (tvalid && tready) begin
// 数据被成功发送
tvalid <= 1'b0;
tdata <= next_data;
tlast <= (cnt == PKT_LEN-1);
end else if (data_ready) begin
// 准备好发送新数据
tvalid <= 1'b1;
end
end
end
嗯,这里要注意:TLAST信号只在包边界有效。如果你传输的是连续流,没有包的概念,那TLAST可以一直拉低。
2.2 AXI4-Full协议详解
AXI4-Full就复杂多了。它有五个独立通道:读地址、读数据、写地址、写数据、写响应。每个通道都有自己的握手信号。
五个通道分别是:
- AR通道:读地址,主机告诉从机“我要读哪里”
- R通道:读数据,从机把数据返回给主机
- AW通道:写地址,主机告诉从机“我要写哪里”
- W通道:写数据,主机把数据发给从机
- B通道:写响应,从机告诉主机“写完了”
我个人觉得,AXI4-Full最牛的地方在于它的乱序传输能力。每个事务都有一个ID标签,从机可以按任意顺序返回数据,主机根据ID重新排序。这在多端口访问时特别有用。
我的经验:在做DDR控制器时,我用了AXI4-Full接口。一开始没处理好ID的分配,导致读数据乱序后无法正确重组。后来我规定每个master使用不同的ID,问题就解决了。
突发传输示例:
// AXI4-Full写突发示例
// 地址通道
assign awaddr = base_addr + (burst_cnt << 2);
assign awlen = 8'd15; // 16次传输
assign awsize = 3'b010; // 4字节
assign awburst = 2'b01; // INCR模式
// 数据通道
always @(posedge clk) begin
if (wready && wvalid) begin
wdata <= wdata + 32'h1;
wlast <= (wcnt == awlen);
end
end
AXI4-Full支持三种突发类型:FIXED(固定地址)、INCR(递增地址)、WRAP(回环地址)。我建议新手先从INCR开始用,它最直观。
2.3 协议选择与对比
好,现在我们来聊聊怎么选。这个问题我经常被问到。
| 特性 | AXI4-Stream | AXI4-Full |
|---|---|---|
| 地址总线 | 无 | 有 |
| 数据方向 | 单向 | 双向 |
| 乱序支持 | 不支持 | 支持(通过ID) |
| 突发传输 | 隐式(通过TLAST) | 显式(AWLEN等) |
| 典型应用 | 视频流、FIFO、DMA | DDR、寄存器、SRAM |
| 复杂度 | 低 | 高 |
我的选择原则:
- 如果数据是流式处理,没有随机访问需求——用Stream。比如视频缩放、FFT、滤波器。
- 如果需要随机读写某个地址空间——用Full。比如CPU访问DDR、配置寄存器。
- 如果两者都需要——可以考虑用Full封装一个Stream接口,或者用两个独立的Stream。
避坑指南:我曾经在一个项目里,把Stream接口强行改成了类似Full的地址模式,结果时序收敛不了。后来我意识到,Stream的设计初衷就是简单,不要给它加太多功能。
你想想看,一个视频处理链路上,每个模块都用Full接口会怎样?地址线、响应线、ID线...光布线就把你绕晕了。而用Stream,一根数据线从头串到尾,清爽多了。
反过来,如果你在做DDR控制器,用Stream就不合适了。因为你需要告诉DDR“我要读地址0x1000”,Stream没有地址通道,你没法表达这个信息。
嗯,协议选择说白了就是一句话:看你的数据有没有“地址”这个概念。有地址,用Full;没有地址,用Stream。就这么简单。
这张图是我画的一个简单决策树。你拿到一个设计需求,先问自己:数据需不需要地址?答案出来了,协议也就定了。
总结一下:AXI4-Stream适合做数据搬运工,AXI4-Full适合做数据管理员。两者没有好坏之分,只有合不合适。我见过有人用Full接口做视频流,结果资源翻了三倍;也见过有人用Stream接口做寄存器配置,结果地址信息无处安放。选对协议,事半功倍。
公众号:蓝海资料掘金营,微信deep3321