二、总线协议基础: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协议选择决策树 数据需要地址吗? 不需要地址 → AXI4-Stream 需要地址 → AXI4-Full 典型应用:视频流、FIFO、ADC 特点:简单、低延迟、单向 典型应用:DDR、寄存器、SRAM 特点:复杂、支持乱序、双向

这张图是我画的一个简单决策树。你拿到一个设计需求,先问自己:数据需不需要地址?答案出来了,协议也就定了。

总结一下:AXI4-Stream适合做数据搬运工,AXI4-Full适合做数据管理员。两者没有好坏之分,只有合不合适。我见过有人用Full接口做视频流,结果资源翻了三倍;也见过有人用Stream接口做寄存器配置,结果地址信息无处安放。选对协议,事半功倍。


公众号:蓝海资料掘金营,微信deep3321