3. AXI4-Lite从机接口信号详解

AXI4-Lite是AXI4协议的精简子集,专为轻量级、低吞吐量的控制寄存器访问而设计。它去除了突发传输(Burst)、独占访问(Locked)和高级数据管理特性,仅保留最基本的握手与传输机制。对于FPGA逻辑设计而言,AXI4-Lite从机接口是实现“软核寄存器映射”的标准方式——CPU通过该接口读写FPGA内部的配置/状态寄存器。

AXI4-Lite从机接口包含5个独立通道,每个通道均使用VALID/READY握手协议实现点对点传输。本章将逐一拆解每个通道的信号定义、时序规则与设计要点。

3.1 通道概览与信号分类

下表列出了AXI4-Lite从机接口的全部5个通道及其核心信号。所有信号均以s_axi_前缀标识从机侧。

通道名称方向(从机视角)核心信号位宽功能简述
写地址通道输入AWADDR, AWVALID, AWREADYADDR_WIDTH接收主机发起的写地址
写数据通道输入WDATA, WSTRB, WVALID, WREADYDATA_WIDTH接收主机写入的数据与字节使能
写响应通道输出BRESP, BVALID, BREADY2向主机返回写传输完成状态
读地址通道输入ARADDR, ARVALID, ARREADYADDR_WIDTH接收主机发起的读地址
读数据通道输出RDATA, RRESP, RVALID, RREADYDATA_WIDTH向主机返回读数据与状态
设计提示:AXI4-Lite的地址与数据通道是分离的,写地址与写数据可以独立握手,但写响应必须在写地址和写数据都完成后才能发出。读操作则严格按“地址→数据”顺序进行。

3.2 写地址通道(Write Address Channel)

写地址通道负责从主机向从机传输写操作的目标地址。AXI4-Lite不支持突发,因此每次写传输仅包含一个地址。

3.2.1 信号定义

信号位宽方向描述
s_axi_awaddrADDR_WIDTH输入写地址。字节地址,必须与数据总线宽度对齐(32位数据时,低2位为0)
s_axi_awvalid1输入地址有效标志。高电平时表示awaddr上的地址有效
s_axi_awready1输出从机就绪标志。高电平时表示从机已准备好接收地址

3.2.2 握手规则

  • VALID先置:主机在地址有效后将awvalid置高。
  • READY可早可晚:从机可以预先置高awready(提前就绪),也可以在awvalid有效后再置高(被动就绪)。
  • 传输完成条件:awvalid与awready同时为高时,地址被从机捕获,该通道握手完成。
设计要点:在从机逻辑中,awready通常与awvalid组合产生内部写地址锁存使能。建议在awready置高的同一时钟沿锁存awaddr,避免地址丢失。

3.3 写数据通道(Write Data Channel)

写数据通道传输实际要写入的数据以及字节使能(WSTRB)信号。AXI4-Lite的数据总线宽度固定为32位或64位,不支持窄位宽传输。

3.3.1 信号定义

信号位宽方向描述
s_axi_wdataDATA_WIDTH输入写数据。与地址通道无固定时序关系
s_axi_wstrbDATA_WIDTH/8输入字节使能。每bit对应一个字节,1表示该字节有效
s_axi_wvalid1输入数据有效标志
s_axi_wready1输出从机就绪标志

3.3.2 字节使能(WSTRB)详解

WSTRB的位宽等于数据总线宽度除以8。对于32位数据总线,WSTRB为4位:

  • wstrb[0] 对应 wdata[7:0](字节0)
  • wstrb[1] 对应 wdata[15:8](字节1)
  • wstrb[2] 对应 wdata[23:16](字节2)
  • wstrb[3] 对应 wdata[31:24](字节3)
常见错误:许多初学者忽略WSTRB,直接写入全部32位数据。如果主机只写单个字节(如只写寄存器低8位),WSTRB会指示哪些字节有效。从机必须根据WSTRB屏蔽无效字节,否则会破坏寄存器中其他字节的内容。

3.4 写响应通道(Write Response Channel)

写响应通道是AXI4-Lite写传输的结束标志。从机在完成写操作后,通过该通道向主机返回传输状态。

3.4.1 信号定义

信号位宽方向描述
s_axi_bresp2输出写响应码。00=OKAY, 01=EXOKAY(保留), 10=SLVERR, 11=DECERR
s_axi_bvalid1输出响应有效标志。从机置高表示bresp有效
s_axi_bready1输入主机就绪标志。主机置高表示已准备好接收响应

3.4.2 响应码含义

  • OKAY (00):正常传输完成。
  • SLVERR (10):从机错误。例如写入只读寄存器、地址未映射、写保护违规。
  • DECERR (11):地址译码错误。通常由互联逻辑产生,从机一般不返回此码。
设计要点:写响应通道的bvalid必须在写地址和写数据都完成之后才能置高。具体来说,从机需要同时检测到awvalid & awready和wvalid & wready都发生过,然后执行内部寄存器写入,最后置高bvalid。

3.5 读地址通道(Read Address Channel)

读地址通道与写地址通道结构对称,但用于读操作。主机通过该通道发送要读取的地址。

3.5.1 信号定义

信号位宽方向描述
s_axi_araddrADDR_WIDTH输入读地址。字节地址,需对齐
s_axi_arvalid1输入读地址有效标志
s_axi_arready1输出从机就绪标志

3.5.2 与写地址通道的差异

  • 读地址通道没有对应的数据通道并行传输,地址必须先被从机捕获,然后从机才能准备读数据。
  • 读地址通道的握手独立于读数据通道,但读数据通道的rvalid必须在地址捕获之后才能置高。

3.6 读数据通道(Read Data Channel)

读数据通道是AXI4-Lite从机向主机返回读数据与状态的唯一通道。

3.6.1 信号定义

信号位宽方向描述
s_axi_rdataDATA_WIDTH输出读数据。从机将寄存器值驱动到此总线上
s_axi_rresp2输出读响应码。00=OKAY, 10=SLVERR, 11=DECERR
s_axi_rvalid1输出读数据有效标志。从机置高表示rdata和rresp有效
s_axi_rready1输入主机就绪标志。主机置高表示已准备好接收数据

3.6.2 读传输的依赖关系

读数据通道的rvalid必须满足以下条件才能置高:

  1. 读地址通道已完成握手(arvalid & arready)。
  2. 从机已根据地址完成内部寄存器读取。
  3. 读数据已稳定在rdata总线上。
设计提示:读数据通道的rresp与写响应通道的bresp使用相同的编码。对于简单的寄存器映射从机,如果地址有效且映射正确,返回OKAY;如果地址未映射或读取只写寄存器,返回SLVERR。

3.7 五通道握手依赖关系图

下图展示了AXI4-Lite从机接口五个通道之间的时序依赖关系。箭头表示“必须在之前完成”。

AXI4-Lite 五通道握手依赖关系 AXI4-Lite 五通道握手依赖关系 写地址通道 AWADDR, AWVALID, AWREADY 写数据通道 WDATA, WSTRB, WVALID, WREADY 写响应通道 BRESP, BVALID, BREADY 读地址通道 ARADDR, ARVALID, ARREADY 读数据通道 RDATA, RRESP, RVALID, RREADY 从机内部寄存器读写逻辑 写地址 写数据 写响应 读地址 读数据 内部逻辑 依赖关系

3.8 典型从机接口Verilog代码框架

以下代码展示了AXI4-Lite从机接口的顶层信号声明与写/读通道的握手逻辑骨架。完整实现需包含地址译码与寄存器读写。

module axi4_lite_slave #(
    parameter ADDR_WIDTH = 12,
    parameter DATA_WIDTH = 32
)(
    input  wire                     s_axi_aclk,
    input  wire                     s_axi_aresetn,
    
    // 写地址通道
    input  wire [ADDR_WIDTH-1:0]    s_axi_awaddr,
    input  wire                     s_axi_awvalid,
    output reg                      s_axi_awready,
    
    // 写数据通道
    input  wire [DATA_WIDTH-1:0]    s_axi_wdata,
    input  wire [DATA_WIDTH/8-1:0]  s_axi_wstrb,
    input  wire                     s_axi_wvalid,
    output reg                      s_axi_wready,
    
    // 写响应通道
    output reg  [1:0]               s_axi_bresp,
    output reg                      s_axi_bvalid,
    input  wire                     s_axi_bready,
    
    // 读地址通道
    input  wire [ADDR_WIDTH-1:0]    s_axi_araddr,
    input  wire                     s_axi_arvalid,
    output reg                      s_axi_arready,
    
    // 读数据通道
    output reg  [DATA_WIDTH-1:0]    s_axi_rdata,
    output reg  [1:0]               s_axi_rresp,
    output reg                      s_axi_rvalid,
    input  wire                     s_axi_rready
);

    // 内部寄存器与状态机
    reg [DATA_WIDTH-1:0] reg0, reg1;  // 示例寄存器
    
    // 写地址握手:awready 在复位后默认置高(提前就绪)
    always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
        if (!s_axi_aresetn)
            s_axi_awready <= 1'b1;
        else if (s_axi_awvalid && s_axi_awready)
            s_axi_awready <= 1'b0;  // 捕获地址后拉低,直到写响应完成再置高
        else if (/* 写响应完成条件 */)
            s_axi_awready <= 1'b1;
    end
    
    // 写数据握手:类似逻辑
    always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
        if (!s_axi_aresetn)
            s_axi_wready <= 1'b1;
        else if (s_axi_wvalid && s_axi_wready)
            s_axi_wready <= 1'b0;
        else if (/* 写响应完成条件 */)
            s_axi_wready <= 1'b1;
    end
    
    // 写响应:在地址和数据都捕获后,执行写入并返回响应
    always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
        if (!s_axi_aresetn) begin
            s_axi_bvalid <= 1'b0;
            s_axi_bresp  <= 2'b00;
        end else if (/* 地址和数据都已捕获 */) begin
            // 执行寄存器写入(根据wstrb屏蔽)
            if (s_axi_wstrb[0]) reg0[7:0]   <= s_axi_wdata[7:0];
            if (s_axi_wstrb[1]) reg0[15:8]  <= s_axi_wdata[15:8];
            // ...
            s_axi_bresp  <= 2'b00;  // OKAY
            s_axi_bvalid <= 1'b1;
        end else if (s_axi_bvalid && s_axi_bready) begin
            s_axi_bvalid <= 1'b0;
        end
    end
    
    // 读地址握手
    always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
        if (!s_axi_aresetn)
            s_axi_arready <= 1'b1;
        else if (s_axi_arvalid && s_axi_arready)
            s_axi_arready <= 1'b0;
        else if (/* 读数据完成 */)
            s_axi_arready <= 1'b1;
    end
    
    // 读数据:根据地址读取寄存器
    always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
        if (!s_axi_aresetn) begin
            s_axi_rvalid <= 1'b0;
            s_axi_rdata  <= 32'h0;
            s_axi_rresp  <= 2'b00;
        end else if (/* 地址已捕获 */) begin
            case (s_axi_araddr)
                12'h000: s_axi_rdata <= reg0;
                12'h004: s_axi_rdata <= reg1;
                default: begin
                    s_axi_rdata <= 32'h0;
                    s_axi_rresp <= 2'b10;  // SLVERR
                end
            endcase
            s_axi_rvalid <= 1'b1;
        end else if (s_axi_rvalid && s_axi_rready) begin
            s_axi_rvalid <= 1'b0;
        end
    end

endmodule

3.9 通道信号设计检查清单

在编写AXI4-Lite从机逻辑时,请逐项核对以下要点:

通道检查项常见错误
写地址awready是否在复位后默认置高?地址是否在握手沿锁存?awready常低导致主机超时;地址锁存时序错误
写数据wready是否与awready独立控制?wstrb是否用于字节屏蔽?wready与awready绑定;忽略wstrb导致数据覆盖
写响应bvalid是否在地址和数据都完成后才置高?bready是否被正确等待?bvalid在数据未到时就置高;bvalid未等待bready就拉低
读地址arready是否在复位后默认置高?地址是否在握手沿锁存?arready常低;地址锁存与读数据流水冲突
读数据rvalid是否在地址捕获后才置高?rdata是否在rvalid置高前稳定?rvalid与arvalid同时置高;rdata在rvalid置高后变化
总结:AXI4-Lite从机接口的五个通道虽然独立,但通过握手信号形成了严格的依赖关系。写操作需要地址和数据都到达后才能响应;读操作需要先捕获地址再返回数据。掌握每个通道的信号定义与握手规则,是设计正确、健壮的AXI4-Lite从机逻辑的基础。