第八篇:AXI4实战案例
本文通过实际设计案例,展示如何基于AXI4协议构建高性能系统,涵盖FPGA外设开发、SoC互联、DMA控制器及流数据处理等场景,结合代码片段与调试技巧,帮助读者将理论落地为实践。
案例1:FPGA中的自定义AXI4-Lite外设
场景 :设计一个FPGA温度传感器控制模块,通过AXI4-Lite接口实现寄存器配置与数据读取。
1. 设计目标
- 支持寄存器读写:
- 0x00 :控制寄存器(启动/停止采样)。
- 0x04 :状态寄存器(忙/空闲)。
- 0x08 :温度数据寄存器(16位)。
- 通过AXI4-Lite接口与CPU(如Zynq PS)通信。
2. 硬件实现
模块接口 (Verilog):
module temp_sensor_axi_lite (
input ACLK,
input ARESETn,
// AXI4-Lite 写地址通道
input [31:0] AWADDR,
input AWVALID,
output AWREADY,
// AXI4-Lite 写数据通道
input [31:0] WDATA,
input WVALID,
output WREADY,
// AXI4-Lite 写响应通道
output [1:0] BRESP,
output BVALID,
input BREADY,
// AXI4-Lite 读地址通道
input [31:0] ARADDR,
input ARVALID,
output ARREADY,
// AXI4-Lite 读数据通道
output [31:0] RDATA,
output [1:0] RRESP,
output RVALID,
input RREADY,
// 温度传感器物理接口
output SAMPLE_EN,
input [15:0] TEMP_DATA
);
寄存器读写状态机 :
// 状态定义
typedef enum {
IDLE,
WRITE_ADDR,
WRITE_DATA,
READ_ADDR,
READ_DATA
} state_t;
// 寄存器映射
reg [31:0] ctrl_reg; // 0x00
reg [31:0] status_reg; // 0x04
reg [31:0] temp_reg; // 0x08
always @(posedge ACLK) begin
if (!ARESETn) begin
ctrl_reg <= 32'h0;
status_reg <= 32'h0;
end else begin
// 写操作
if (AWVALID && AWREADY && WVALID && WREADY) begin
case (AWADDR[7:0])
8'h00: ctrl_reg <= WDATA;
endcase
end
// 读操作
if (ARVALID && ARREADY) begin
case (ARADDR[7:0])
8'h00: RDATA <= ctrl_reg;
8'h04: RDATA <= status_reg;
8'h08: RDATA <= {16'h0, TEMP_DATA};
endcase
end
end
end
3. 验证与调试
- 仿真测试 :
写入控制寄存器启动采样,检查状态寄存器是否置忙。
读取温度寄存器,验证数据是否对齐。 - 硬件调试 :
使用Vivado ILA抓取AXI4-Lite信号,确认握手时序。
案例2:SoC系统中的AXI4互联矩阵
场景 :设计多主(CPU、DMA)多从(DDR、外设)的AXI4交叉开关(Crossbar)。
1. 设计目标
- 支持2个主设备(Master0, Master1)和3个从设备(Slave0-DDR, Slave1-UART, Slave2-GPIO)。
- 实现优先级仲裁与地址路由。
2. 互联矩阵实现
地址映射表 :
从设备 | 地址范围 |
---|---|
Slave0 (DDR) | 0x0000_0000 ~ 0x3FFF_FFFF |
Slave1 (UART) | 0x4000_0000 ~ 0x4000_0FFF |
Slave2 (GPIO) | 0x4001_0000 ~ 0x4001_FFFF |
仲裁逻辑 (Verilog伪代码):
// 主设备请求仲裁
always @(*) begin
if (Master0_REQ && (Master0_QOS > Master1_QOS))
grant = Master0;
else
grant = Master1;
end
// 地址路由
always @(*) begin
case (grant_AWADDR)
32'h4000_0000: slave_sel = SLAVE1;
32'h4001_0000: slave_sel = SLAVE2;
default: slave_sel = SLAVE0;
endcase
end
3. 性能优化
多未完成事务 :允许每个主设备同时发起最多8个事务。
QoS配置 :DMA(Master1)优先级高于CPU(Master0),确保实时数据吞吐。
案例3:AXI4-Stream视频流处理系统
场景 :FPGA实现图像灰度化处理,输入为RGB视频流,输出为灰度视频流。
1. 设计架构
- 输入接口 :AXI4-Stream RGB(24位像素,
TDATA[23:0]
)。 - 处理模块 :实时计算灰度值(Y = 0.299R + 0.587G + 0.114B)。
- 输出接口 :AXI4-Stream灰度(8位像素,
TDATA[7:0]
)。
2. 关键代码
module grayscale_converter (
input ACLK,
input ARESETn,
// 输入流接口
input [23:0] S_AXIS_TDATA,
input S_AXIS_TVALID,
output S_AXIS_TREADY,
// 输出流接口
output [7:0] M_AXIS_TDATA,
output M_AXIS_TVALID,
input M_AXIS_TREADY
);
// 灰度计算逻辑
wire [7:0] R = S_AXIS_TDATA[23:16];
wire [7:0] G = S_AXIS_TDATA[15:8];
wire [7:0] B = S_AXIS_TDATA[7:0];
wire [15:0] Y = (R * 77) + (G * 150) + (B * 29); // 近似公式:(77, 150, 29) ≈ (0.299, 0.587, 0.114) * 256
assign M_AXIS_TDATA = Y[15:8]; // 取高8位
assign M_AXIS_TVALID = S_AXIS_TVALID;
assign S_AXIS_TREADY = M_AXIS_TREADY; // 直通背压
endmodule
3. 时序优化
- 流水线设计 :将乘法与加法拆分为两级流水,提升时钟频率。
- 背压传递 :输入
TREADY
直接连接输出TREADY
,确保数据流连续。
案例4:AXI4 DMA控制器设计
场景 :实现DMA控制器,通过AXI4突发传输将数据从外设搬运到DDR。
1. 功能需求
- 支持寄存器配置:源地址、目标地址、传输长度。
- 支持中断通知(传输完成或错误)。
2. 状态机设计
传输流程 :
- 配置阶段 :CPU通过AXI4-Lite写入DMA控制寄存器。
- 传输阶段 :
- 从外设(源)读取数据到内部FIFO。
- 从FIFO写入DDR(目标)。
- 完成阶段 :触发中断,更新状态寄存器。
关键代码 (突发读+突发写):
// AXI4读主设备逻辑
always @(posedge ACLK) begin
if (state == READ_BURST) begin
ARADDR <= src_addr;
ARLEN <= burst_len - 1;
ARVALID <= 1'b1;
if (ARREADY) begin
src_addr <= src_addr + (burst_len << 2); // 32位数据,地址递增
state <= WRITE_BURST;
end
end
end
// AXI4写主设备逻辑
always @(posedge ACLK) begin
if (state == WRITE_BURST) begin
AWADDR <= dst_addr;
AWLEN <= burst_len - 1;
AWVALID <= 1'b1;
WDATA <= fifo_data;
WVALID <= 1'b1;
if (WREADY && WLAST) begin
dst_addr <= dst_addr + (burst_len << 2);
state <= IDLE;
// 触发中断
end
end
end
3. 调试技巧
- FIFO深度优化 :根据突发长度设置FIFO深度,避免读/写速率不匹配导致溢出。
- 错误恢复 :检测
BRESP
是否为SLVERR
,若失败则重试或上报CPU。
总结与系列回顾
- 核心价值 :AXI4的灵活性使其适用于从简单外设到复杂SoC的全场景设计。
- 系列总结 :
理论 :通道分离、突发传输、原子操作。
实践 :性能优化、协议验证、子协议选型。 - 进阶方向 :
学习AXI5/CHI协议以支持一致性互联。
探索AI芯片中的定制AXI4拓扑结构。