3. AXI协议基础:通道分离、握手机制、乱序传输、数据交织

AXI协议,说白了就是ARM公司搞出来的一套高性能总线协议。我当年第一次接触它的时候,心里想的是:这玩意儿怎么这么多通道?后来做存储控制器项目,被它折腾得够呛,但也慢慢摸透了它的脾气。

今天咱们就聊聊AXI协议最核心的几个概念。你把这些搞懂了,后面做总线整合就会顺手很多。

3.1 通道分离:五个独立通道各司其职

AXI协议最显著的特点,就是通道分离。它不像AHB那样只有一个总线,而是拆成了五个独立的通道。我刚开始觉得这太复杂了,后来才发现,这恰恰是它高性能的根源。

这五个通道分别是:

  • 读地址通道(AR):发送读请求的地址和控制信息
  • 读数据通道(R):返回读到的数据,以及读响应信号
  • 写地址通道(AW):发送写请求的地址和控制信息
  • 写数据通道(W):发送要写入的数据
  • 写响应通道(B):返回写操作的完成状态

你想想看,读和写是完全分开的。这意味着,在同一个时刻,你可以同时发送读请求和写请求,互不干扰。这在AHB上是做不到的。

关键点:每个通道都是单向的,数据流方向固定。读地址和数据是从主机到从机?不对,读数据是从从机返回主机的。这个方向千万别搞反了,我在项目中见过有人把读数据通道的方向画反,结果仿真怎么都跑不通。

我画了一张图,帮你直观理解这五个通道的关系:

主机 从机 AR 读地址 R 读数据 AW 写地址 W 写数据 B 写响应 图例:绿色→读地址 蓝色→读数据 红色→写地址 紫色→写数据 橙色→写响应

3.2 握手机制:VALID和READY的舞蹈

每个通道都使用一套独立的握手机制。说白了就是两个信号:VALIDREADY

  • VALID:发送方说「我准备好了,数据/地址有效」
  • READY:接收方说「我准备好了,可以接收」

只有当VALID和READY同时为高时,传输才发生。这个握手规则,我称之为「双方都点头才算数」。

握手有三种情况:

  1. VALID先有效,READY后有效:发送方先准备好,等接收方。这是最常见的情况。
  2. READY先有效,VALID后有效:接收方先准备好,等发送方。从机可以提前声明自己准备好了。
  3. 同时有效:一拍完成传输,效率最高。

我的经验:在设计从机时,我习惯让READY信号在VALID到来之前就拉高。这样一旦主机发送数据,一拍就能完成传输,延迟最小。但要注意,READY不能依赖VALID来产生,否则会形成组合逻辑环路。

看一个简单的握手时序例子:

// 写地址通道握手示例
// 时钟沿1:主机拉高AWVALID,从机AWREADY为低
// 时钟沿2:从机拉高AWREADY,传输发生
// 时钟沿3:主机拉低AWVALID,从机拉低AWREADY

always @(posedge clk) begin
  if (rst) begin
    awready <= 1'b0;
  end else begin
    awready <= 1'b1;  // 我习惯默认准备好
  end
end

// 传输发生条件
assign aw_transfer = awvalid & awready;

3.3 乱序传输:ID标签的妙用

乱序传输是AXI协议的一大亮点。什么意思呢?就是主机可以连续发送多个请求,从机可以不按顺序返回数据。

为什么会这样?你想想看,如果从机是一个DDR控制器,访问不同bank的延迟不一样。先发的请求可能因为bank冲突而延迟,后发的请求反而先完成。如果非要按顺序返回,那效率就太低了。

AXI用ID标签来解决这个问题。每个请求都带一个ID,返回的数据也带同样的ID。主机根据ID来区分数据属于哪个请求。

信号 位宽 说明
ARID 4-8位 读请求的ID标签
RID 4-8位 读数据的ID标签,与ARID匹配
AWID 4-8位 写请求的ID标签
BID 4-8位 写响应的ID标签,与AWID匹配

注意:乱序传输虽然提高了效率,但也增加了设计复杂度。我曾经在一个项目中,因为ID分配逻辑写错了,导致数据错乱,查了整整两天才找到问题。建议你:

  • ID位宽要足够,避免ID溢出
  • 同一ID的事务必须保序
  • 不同ID的事务可以乱序

3.4 数据交织:WSTRB和字节选通

数据交织,说白了就是数据可以不是连续的。AXI支持非对齐传输和字节选通。

WSTRB信号是写数据通道的字节选通信号。每个bit对应一个字节。比如32位数据总线,WSTRB就是4位。哪一位为高,就表示对应的字节有效。

举个例子:

// 32位数据总线,只写低16位
WSTRB = 4'b0011;  // bit0和bit1为高,表示byte0和byte1有效
WDATA = 32'hAABB_CCDD;  // 实际写入的是低16位 0xCCDD

// 非对齐写,地址0x01,写2个字节
WSTRB = 4'b0110;  // byte1和byte2有效
// 数据会写到地址0x01和0x02

我刚开始做存储控制器时,对WSTRB的处理不够严谨。有一次写操作,地址是非对齐的,WSTRB没算对,结果数据写到了错误的位置。从那以后,我每次处理WSTRB都会画个字节位置图,确保万无一失。

核心要点:数据交织和字节选通,让AXI可以灵活处理任意字节位置的读写。这在处理网络包、缓存行等场景下特别有用。但代价是,从机设计要能处理任意WSTRB组合,逻辑会复杂一些。

3.5 小结:这些概念怎么用?

好了,咱们把AXI协议的四个核心概念捋了一遍。你可能会问,这些在实际项目中怎么用?

我举个例子。假设你要设计一个存储控制器,挂载在AXI总线上。你需要:

  • 用通道分离的思路,把读和写的处理逻辑分开
  • 实现标准的VALID/READY握手,注意不要有组合环路
  • 支持乱序传输,用ID标签管理多个未完成的事务
  • 正确处理WSTRB,支持非对齐访问

这些基础打牢了,后面做AHB到AXI的桥接,或者AXI到AHB的转换,就会轻松很多。嗯,今天就先聊到这里。


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