跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C算法

AXI 总线详解与 FPGA 实现实战指南

AXI 总线是 ARM AMBA 协议簇中的高性能片上互联标准,核心在于五通道独立设计与 READY-VALID 握手机制。FPGA 开发中主要涉及 AXI4-Lite、AXI4 和 AXI4-Stream 三种子集。实现方式首选调用官方 IP 核进行图形化配置互联,零手写协议逻辑;进阶场景可手动编写接口适配层,重点掌握握手时序与数据映射。掌握 AXI 总线是 FPGA 高速数据交互、DDR 读写及异构计算的关键技能。

微码行者发布于 2026/4/8更新于 2026/9/952 浏览
AXI 总线详解与 FPGA 实现实战指南

AXI 总线详解与 FPGA 实现实战指南

AXI 总线作为 ARM AMBA 协议簇的核心成员,是高性能片上互联的事实标准。在 FPGA 与 SoC 开发中,它是连接 CPU、DDR、DMA 及各类外设 IP 的高速桥梁,掌握其机制对于理解芯片内部数据交互至关重要。

1. AXI 总线的核心特性

AXI 之所以成为主流,源于其设计上的几个关键特性,所有设计都围绕「提升传输效率、降低复杂度」展开:

  1. 地址与控制信号分离:地址和控制信息先传输,数据随后独立传输,互不阻塞,大幅提升利用率。
  2. 5 个独立的单向传输通道:这是 AXI 高性能的核心,通道间完全独立、互不干扰。
  3. 支持突发传输(Burst Transfer):只需发送一次地址 + 控制信息,即可连续传输多拍数据,适合大数据块读写。
  4. READY-VALID 流控握手:所有通道遵循这套异步握手机制,无时钟同步要求。只有当 VALID & READY = 1 时,本次传输才算真正完成。这完美解决了总线拥塞和跨时钟域问题。
  5. 读写分离:读操作和写操作的通道完全独立,可同时进行。

2. AXI 的三大核心子集

在 FPGA 开发中,我们主要用到以下三个子集,它们定位不同但设计思想一致:

2.1 AXI4-Lite(轻量级)

用于低速、寄存器级读写。只支持单拍传输,信号线极少,实现难度低。常用于外设 IP 的配置与控制,如 GPIO、SPI、UART 等寄存器的读写。

2.2 AXI4(标准版)

用于高速、大数据块传输。支持 1~256 拍突发传输,位宽灵活。适用于 DDR 读写、DMA 数据搬移等高速场景。

2.3 AXI4-Stream(流式)

无地址线,纯数据流。专为连续串行数据传输设计。核心握手机制为 TVALID-TREADY,可选 TLAST 标记帧结束。这是 FPGA 中最高频的接口,广泛用于视频流、ADC 采集、以太网包处理等。

3. FPGA 实现 AXI 的两种思路

在 FPGA 中实现 AXI 总线,主要有两种方式,建议优先使用第一种。

3.1 调用官方 IP 核(推荐)

FPGA 厂商(Xilinx/Intel)对 AXI4 协议做了原生固化支持。所有官方 IP 核(DDR、DMA、以太网等)的顶层接口均为 AXI 标准接口。

核心优势:内置完整协议逻辑,经过量产验证,稳定性高。

实现流程:

  1. 新建工程,按需添加 AXI IP 核(如 AXI GPIO、AXI DMA)。
  2. 图形化配置参数(位宽、突发长度等)。
  3. 使用 Block Design 或 Platform Designer 工具,拖拽连接各 IP 核的 AXI 接口,工具会自动生成互联逻辑。
  4. 生成 HDL 代码并编译下载。

这种方式相当于'拼积木',无需手写协议细节即可完成大部分开发需求。

3.2 手动编写接口适配(进阶)

当官方 IP 无法满足定制化需求时,需手动编写少量 Verilog 代码实现接口适配。

核心原则:只写「接口适配层」,不写完整协议栈。重点实现 READY/VALID 握手和数据映射。

以下是两个高频场景的代码示例。

案例 1:手动实现 AXI4-Lite 从机

此模块实现一个简单的 AXI4-Lite 从机,包含两个 32 位寄存器。主机可通过 AXI4-Lite 读写这两个寄存器。核心逻辑是处理地址、数据、响应的握手时序。

// AXI4-Lite 从机核心逻辑 (32 位地址/数据)
module axi4_lite_slave(
    input clk,
    input rst_n,
    // 写地址通道
    input [31:0] s_axi_awaddr,
    input s_axi_awvalid,
    output reg s_axi_awready,
    // 写数据通道
    input [31:0] s_axi_wdata,
    input s_axi_wvalid,
    output reg s_axi_wready,
    // 写响应通道
    output reg [1:0] s_axi_bresp,
    output reg s_axi_bvalid,
    input s_axi_bready,
    // 读地址通道
    input [31:0] s_axi_araddr,
    input s_axi_arvalid,
    output reg s_axi_arready,
    // 读数据通道
    output reg [31:0] s_axi_rdata,
    output reg [1:0] s_axi_rresp,
    output reg s_axi_rvalid,
    input s_axi_rready
);

    // 自定义寄存器:地址 0x00=控制寄存器,0x04=状态寄存器
    reg [31:0] ctrl_reg;
    reg [31:0] stat_reg;

    // 写事务:地址握手 + 数据握手 + 响应
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            s_axi_awready <= 1'b0;
            s_axi_wready <= 1'b0;
            s_axi_bvalid <= 1'b0;
            ctrl_reg <= 32'd0;
        end else begin
            // 写地址就绪:当地址有效且数据未就绪时
            if(s_axi_awvalid && !s_axi_awready) begin
                s_axi_awready <= 1'b1;
            end
            // 写数据就绪:当地址已就绪且数据有效时
            if(s_axi_wvalid && !s_axi_wready && s_axi_awready) begin
                s_axi_wready <= 1'b1;
                // 根据地址写寄存器
                case(s_axi_awaddr)
                    32'h00000000: ctrl_reg <= s_axi_wdata;
                    32'h00000004: stat_reg <= s_axi_wdata;
                    default: ;
                endcase
                // 写响应有效
                s_axi_bvalid <= 1'b1;
                s_axi_bresp <= 2'b00; // 响应:成功
            end
            // 响应握手完成,清零就绪和有效信号
            if(s_axi_bvalid && s_axi_bready) begin
                s_axi_awready <= 1'b0;
                s_axi_wready <= 1'b0;
                s_axi_bvalid <= 1'b0;
            end
        end
    end

    // 读事务:地址握手 + 数据握手
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            s_axi_arready <= 1'b0;
            s_axi_rvalid <= 1'b0;
            s_axi_rdata <= 32'd0;
        end else begin
            // 读地址就绪:当地址有效且数据未就绪时
            if(s_axi_arvalid && !s_axi_arready) begin
                s_axi_arready <= 1'b1;
                // 根据地址读寄存器
                case(s_axi_araddr)
                    32'h00000000: s_axi_rdata <= ctrl_reg;
                    32'h00000004: s_axi_rdata <= stat_reg;
                    default: s_axi_rdata <= 32'h00000000;
                endcase
                // 读数据有效
                s_axi_rvalid <= 1'b1;
                s_axi_rresp <= 2'b00; // 响应:成功
            end
            // 读数据握手完成,清零就绪和有效信号
            if(s_axi_rvalid && s_axi_rready) begin
                s_axi_arready <= 1'b0;
                s_axi_rvalid <= 1'b0;
            end
        end
    end
endmodule
案例 2:手动实现 AXI4-Stream 数据转发

将一路 AXI4-Stream 输入数据流,无修改转发到一路输出数据流。核心是实现 TVALID-TREADY 握手和 TDATA 数据传输。

// AXI4-Stream 数据流转发模块 (64 位数据位宽,带 TLAST 帧结束)
module axi4_stream_forward(
    input clk,
    input rst_n,
    // AXI4-Stream 输入接口
    input [63:0] s_axis_tdata,
    input s_axis_tvalid,
    output reg s_axis_tready,
    input s_axis_tlast,
    // AXI4-Stream 输出接口
    output reg [63:0] m_axis_tdata,
    output reg m_axis_tvalid,
    input m_axis_tready,
    output reg m_axis_tlast
);

    // 核心逻辑:READY-VALID 握手 + 数据透传
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            s_axis_tready <= 1'b0;
            m_axis_tvalid <= 1'b0;
            m_axis_tdata <= 64'd0;
            m_axis_tlast <= 1'b0;
        end else begin
            // 接收就绪:当输出端就绪时,才允许输入端传输
            s_axis_tready <= m_axis_tready;
            // 输出有效:当输入端有效且接收就绪时
            if(s_axis_tvalid && s_axis_tready) begin
                m_axis_tvalid <= 1'b1;
                m_axis_tdata <= s_axis_tdata;
                m_axis_tlast <= s_axis_tlast;
            end else begin
                m_axis_tvalid <= 1'b0;
            end
        end
    end
endmodule

4. 关键设计要点

  1. 严格遵循 READY-VALID 握手规则:永远不要省略 READY 信号,否则会导致数据丢失或总线死锁。VALID 由发送方控制,READY 由接收方控制。
  2. 时钟域同步处理:AXI4-Stream 常跨时钟域,必须用官方的 AXI 同步 IP 核,不要自己写跨时钟域逻辑。
  3. 位宽匹配与转换:不同 AXI 模块的位宽可能不同,调用官方的 AXI Width Converter IP 核一键完成转换。
  4. AXI4 突发传输地址对齐:地址必须对齐到数据位宽,否则会触发错误响应。
  5. AXI4-Stream 的 TLAST 信号必做:对于分包的数据流,TLAST 是唯一的帧结束标记,必须正确赋值。

总结

AXI 总线是 FPGA 开发的必修课。核心在于掌握 5 个独立单向通道与 READY-VALID 握手机制。实现上,新手首选调用官方 IP 核拼积木,进阶需求再手动编写接口适配层。熟练掌握后,便能轻松驾驭高速数据交互、DDR 读写及异构计算等核心场景。

目录

  1. AXI 总线详解与 FPGA 实现实战指南
  2. 1. AXI 总线的核心特性
  3. 2. AXI 的三大核心子集
  4. 2.1 AXI4-Lite(轻量级)
  5. 2.2 AXI4(标准版)
  6. 2.3 AXI4-Stream(流式)
  7. 3. FPGA 实现 AXI 的两种思路
  8. 3.1 调用官方 IP 核(推荐)
  9. 3.2 手动编写接口适配(进阶)
  10. 案例 1:手动实现 AXI4-Lite 从机
  11. 案例 2:手动实现 AXI4-Stream 数据转发
  12. 4. 关键设计要点
  13. 总结

更多推荐文章

查看全部
  • 《Agent Runtime 工程化》第一章 Agent Runtime 全景:导读
  • 通义万相 2.1 模型升级与应用拓展实践
  • 大模型本地部署与优化实战指南
  • CycleGAN 详解与实现:图像风格转换技术
  • LLaMA-Factory 微调 DeepSeek-R1 模型入门教程
  • 低空无人机 AI 算法全景:74 种行业场景应用解析
  • 机器人远程监控与 OTA 升级技术架构
  • Flutter 三方库 arcane_helper_utils 鸿蒙化适配指南
  • GESP C++ 七级真题解析:金币收集
  • 基于 SpringBoot 与 Vue 的电子产品销售系统设计与实现
  • 大语言模型微调技术详解与 LoRA 实践
  • 密码安全指南:从弱口令风险到多因素认证实践
  • Stable Diffusion WebUI 完整安装与实战指南
  • 【教程】CLAUDE.md 与 AGENTS.md 完全指南:让 AI 编程助手更懂你的项目
  • Android 大厂面试核心考点与问题汇总
  • AI 编程工具 Cursor 核心功能与技术架构解析
  • Ubuntu 实体机与虚拟机安装及配置指南
  • Star-Office-UI - 像素风格 AI 办公室看板,可视化 AI 助手工作状态
  • Halcon 20.11 安装避坑指南与 License 配置详解
  • Streamlit 框架介绍:用 Python 快速构建数据应用

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online