Xilinx FPGA AXI4 使用文档
1. 概述
AXI4(Advanced eXtensible Interface 4)是ARM公司AMBA协议中的高性能互连协议,广泛应用于Xilinx FPGA,用于处理器、IP核和自定义逻辑间的高带宽数据通信。本文档聚焦于AXI4(全AXI4)协议的使用,涵盖协议概述、信号描述、设计流程、Vivado相关IP核及示例代码,不涉及AXI4-Lite和AXI4-Stream。
2. AXI4 协议简介
AXI4是面向存储器映射的点对点通信协议,支持高带宽、低延迟的突发传输,适用于DMA、存储器接口等场景。
2.1 AXI4 关键特性
- 独立通道:读地址、读数据、写地址、写数据、写响应五个通道独立操作,提升并发性。
- 突发传输:支持固定(FIXED)、增量(INCR)和回绕(WRAP)突发,最大突发长度256次。
- 灵活数据宽度:支持32位、64位、128位等,需与硬件匹配。
- 对齐与非对齐传输:支持多种数据对齐方式。
- 响应机制:支持OKAY、EXOKAY、SLVERR、DECERR等多种响应状态。
3. AXI4 接口信号描述
以下为AXI4协议的主要信号描述:
信号名 | 方向 | 描述 |
---|---|---|
ACLK | 输入 | 全局时钟信号,所有信号同步于此。 |
ARESETN | 输入 | 全局复位信号,低电平有效。 |
写地址通道 | ||
AWADDR | 主->从 | 写地址,指定写操作的目标地址。 |
AWLEN | 主->从 | 突发长度,0表示1次传输,255表示256次传输。 |
AWSIZE | 主->从 | 每次传输的字节数(2^n,n=0到7,如2表示4字节)。 |
AWBURST | 主->从 | 突发类型:0(FIXED)、1(INCR)、2(WRAP)。 |
AWVALID | 主->从 | 写地址有效信号。 |
AWREADY | 从->主 | 写地址就绪信号。 |
写数据通道 | ||
WDATA | 主->从 | 写数据。 |
WSTRB | 主->从 | 写数据选通信号,指示哪些字节有效(每位对应一个字节)。 |
WLAST | 主->从 | 写数据最后一个传输的标志。 |
WVALID | 主->从 | 写数据有效信号。 |
WREADY | 从->主 | 写数据就绪信号。 |
写响应通道 | ||
BRESP | 从->主 | 写响应状态:0(OKAY)、1(EXOKAY)、2(SLVERR)、3(DECERR)。 |
BVALID | 从->主 | 写响应有效信号。 |
BREADY | 主->从 | 写响应就绪信号。 |
读地址通道 | ||
ARADDR | 主->从 | 读地址,指定读操作的目标地址。 |
ARLEN | 主->从 | 读突发长度,0表示1次传输,255表示256次传输。 |
ARSIZE | 主->从 | 每次传输的字节数(2^n,n=0到7)。 |
ARBURST | 主->从 | 读突发类型:0(FIXED)、1(INCR)、2(WRAP)。 |
ARVALID | 主->从 | 读地址有效信号。 |
ARREADY | 从->主 | 读地址就绪信号。 |
读数据通道 | ||
RDATA | 从->主 | 读数据。 |
RRESP | 从->主 | 读响应状态:0(OKAY)、1(EXOKAY)、2(SLVERR)、3(DECERR)。 |
RLAST | 从->主 | 读数据最后一个传输的标志。 |
RVALID | 从->主 | 读数据有效信号。 |
RREADY | 主->从 | 读数据就绪信号。 |
4. Xilinx FPGA 中的 AXI4 设计流程
在Xilinx FPGA中使用AXI4协议通常包括以下步骤:
4.1 需求分析
- 确定数据带宽需求(如32位、64位、128位)。
- 选择突发类型(INCR最常用,WRAP用于缓存,FIXED用于固定地址)。
- 确定主从设备角色(处理器为Master,存储器为Slave)。
4.2 使用 Vivado IP 核
Vivado提供多个AXI4相关IP核,简化设计流程。以下为常用IP核:
-
AXI Interconnect (PG059):
- 功能:连接多个AXI4主从设备,支持时钟域转换、数据宽度转换和协议转换。
- 配置:支持1到16个主/从接口,数据宽度32/64/128/256/512位。
- 用途:构建复杂的多主多从系统,如Zynq SoC中的PS到PL通信。
-
AXI DMA (PG021):
- 功能:实现高效的数据搬运,支持AXI4存储器映射接口。
- 配置:支持Scatter-Gather模式、数据宽度32/64/128位、突发长度最大256。
- 用途:处理器与PL间的高速数据传输,如图像处理或网络数据包处理。
-
AXI BRAM Controller (PG078):
- 功能:将AXI4接口连接到片上Block RAM。
- 配置:支持32/64位数据宽度,突发传输优化。
- 用途:实现高速片上存储器访问。
-
AXI Memory Mapped to Stream Mapper (PG102):
- 功能:将AXI4存储器映射接口转换为AXI4-Stream(本文不深入讨论,但常与AXI4配合)。
- 配置:支持多种数据宽度和突发长度。
- 用途:存储器数据到流式处理的桥接。
-
AXI Verification IP (PG267):
- 功能:提供AXI4协议仿真验证工具,支持主/从/监控模式。
- 配置:可模拟AXI4主从设备,检查协议合规性。
- 用途:验证自定义AXI4 IP的正确性。
在Vivado中:
- 打开IP Catalog,搜索“AXI”。
- 选择所需IP核,配置参数(如数据宽度、突发长度、时钟域)。
- 生成IP核并集成到Block Design中。
4.3 自定义 AXI4 IP 设计
若现有IP核无法满足需求,可通过以下方式开发自定义AXI4 IP:
-
Vivado IP Packager:
- 创建新IP,定义AXI4主或从接口。
- 配置接口参数(如地址宽度、数据宽度)。
- 打包为可复用IP核。
-
Verilog/VHDL 实现:
- 编写AXI4主或从设备逻辑,遵循VALID/READY握手协议。
- 实现突发传输逻辑,处理AWLEN、ARLEN、WLAST、RLAST等信号。
-
验证:
- 使用AXI Verification IP(AXI VIP)进行仿真。
- 检查协议时序、响应状态和数据完整性。
4.4 时序设计
- 所有信号需与ACLK同步。
- 使用ARESETN进行复位初始化,确保复位后信号处于已知状态。
- 遵循VALID/READY握手规则:VALID信号置位后需保持,直到READY置位完成握手。
4.5 调试
- 使用Vivado ILA(Integrated Logic Analyzer)捕获AXI4信号。
- 检查AWVALID/AWREADY、WVALID/WREADY等握手信号。
- 验证突发长度(AWLEN/ARLEN)、地址对齐和响应状态(BRESP/RRESP)。
5. 示例:AXI4 从设备设计
以下为一个简单的AXI4从设备Verilog代码,支持突发写和读操作。
module axi4_slave #(
parameter C_S_AXI_ADDR_WIDTH = 32,
parameter C_S_AXI_DATA_WIDTH = 32
) (
// AXI4 接口信号
input wire s_axi_aclk,
input wire s_axi_aresetn,
// 写地址通道
input wire [C_S_AXI_ADDR_WIDTH-1:0] s_axi_awaddr,
input wire [7:0] s_axi_awlen,
input wire [2:0] s_axi_awsize,
input wire [1:0] s_axi_awburst,
input wire s_axi_awvalid,
output wire s_axi_awready,
// 写数据通道
input wire [C_S_AXI_DATA_WIDTH-1:0] s_axi_wdata,
input wire [C_S_AXI_DATA_WIDTH/8-1:0] s_axi_wstrb,
input wire s_axi_wlast,
input wire s_axi_wvalid,
output wire s_axi_wready,
// 写响应通道
output wire [1:0] s_axi_bresp,
output wire s_axi_bvalid,
input wire s_axi_bready,
// 读地址通道
input wire [C_S_AXI_ADDR_WIDTH-1:0] s_axi_araddr,
input wire [7:0] s_axi_arlen,
input wire [2:0] s_axi_arsize,
input wire [1:0] s_axi_arburst,
input wire s_axi_arvalid,
output wire s_axi_arready,
// 读数据通道
output wire [C_S_AXI_DATA_WIDTH-1:0] s_axi_rdata,
output wire [1:0] s_axi_rresp,
output wire s_axi_rlast,
output wire s_axi_rvalid,
input wire s_axi_rready
);
// 内部存储器(模拟存储器)
reg [C_S_AXI_DATA_WIDTH-1:0] mem [0:1023];
reg awready;
reg wready;
reg [1:0] bresp;
reg bvalid;
reg arready;
reg [C_S_AXI_DATA_WIDTH-1:0] rdata;
reg [1:0] rresp;
reg rvalid;
reg rlast;
// 写地址通道
assign s_axi_awready = awready;
always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
if (!s_axi_aresetn) begin
awready <= 1'b0;
end else begin
if (s_axi_awvalid && !awready) begin
awready <= 1'b1;
end else begin
awready <= 1'b0;
end
end
end
// 写数据通道
assign s_axi_wready = wready;
always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
if (!s_axi_aresetn) begin
wready <= 1'b0;
end else begin
if (s_axi_wvalid && !wready) begin
wready <= 1'b1;
end else begin
wready <= 1'b0;
end
end
end
// 写操作
reg [C_S_AXI_ADDR_WIDTH-1:0] write_addr;
reg [7:0] burst_count;
always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
if (!s_axi_aresetn) begin
write_addr <= 0;
burst_count <= 0;
end else begin
if (awready && s_axi_awvalid) begin
write_addr <= s_axi_awaddr;
burst_count <= s_axi_awlen;
end
if (wready && s_axi_wvalid) begin
mem[write_addr[9:2]] <= s_axi_wdata;
if (s_axi_wlast) begin
write_addr <= 0;
burst_count <= 0;
end else begin
write_addr <= write_addr + (1 << s_axi_awsize);
burst_count <= burst_count - 1;
end
end
end
end
// 写响应通道
assign s_axi_bresp = bresp;
assign s_axi_bvalid = bvalid;
always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
if (!s_axi_aresetn) begin
bvalid <= 1'b0;
bresp <= 2'b00; // OKAY
end else begin
if (wready && s_axi_wvalid && s_axi_wlast && !bvalid) begin
bvalid <= 1'b1;
bresp <= 2'b00;
end else if (s_axi_bready && bvalid) begin
bvalid <= 1'b0;
end
end
end
// 读地址通道
assign s_axi_arready = arready;
always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
if (!s_axi_aresetn) begin
arready <= 1'b0;
end else begin
if (s_axi_arvalid && !arready) begin
arready <= 1'b1;
end else begin
arready <= 1'b0;
end
end
end
// 读数据通道
assign s_axi_rdata = rdata;
assign s_axi_rresp = rresp;
assign s_axi_rvalid = rvalid;
assign s_axi_rlast = rlast;
reg [C_S_AXI_ADDR_WIDTH-1:0] read_addr;
reg [7:0] read_burst_count;
always @(posedge s_axi_aclk or negedge s_axi_aresetn) begin
if (!s_axi_aresetn) begin
rvalid <= 1'b0;
rresp <= 2'b00; // OKAY
rdata <= 0;
rlast <= 1'b0;
read_addr <= 0;
read_burst_count <= 0;
end else begin
if (arready && s_axi_arvalid && !rvalid) begin
read_addr <= s_axi_araddr;
read_burst_count <= s_axi_arlen;
rvalid <= 1'b1;
rresp <= 2'b00;
rdata <= mem[s_axi_araddr[9:2]];
rlast <= (s_axi_arlen == 0);
end else if (rvalid && s_axi_rready) begin
if (read_burst_count == 0) begin
rvalid <= 1'b0;
rlast <= 1'b0;
end else begin
read_addr <= read_addr + (1 << s_axi_arsize);
read_burst_count <= read_burst_count - 1;
rdata <= mem[read_addr[9:2] + 1];
rlast <= (read_burst_count == 1);
end
end
end
end
endmodule
5.1 示例说明
- 该模块实现了一个AXI4从设备,支持突发读写操作。
- 地址宽度32位,数据宽度32位,支持INCR突发(未实现WRAP和FIXED)。
- 使用1024个32位存储单元模拟存储器。
- 支持VALID/READY握手,响应状态为OKAY。
- 可通过Vivado IP Packager打包为IP核。
6. 注意事项
-
时钟与复位:
- 确保所有信号与ACLK同步。
- 使用ARESETN初始化信号状态。
-
握手协议:
- VALID信号需在READY之前或同时置位,且保持直到握手完成。
- 避免死锁,确保READY信号及时响应。
-
突发传输:
- 正确处理AWLEN/ARLEN,确保突发长度不超过256。
- 使用WLAST/RLAST标记最后一个传输。
-
数据对齐:
- 确保WSTRB信号正确指示有效字节。
- 检查AWADDR/ARADDR对齐,防止越界访问。
-
性能优化:
- 优化突发长度,减少地址通道开销。
- 使用AXI Interconnect处理多主多从场景。
-
调试与验证:
- 使用AXI VIP验证协议合规性。
- 通过ILA检查握手时序、突发计数和响应状态。
7. 设计工具推荐
- SZ901:
SZ901 是一款基于XVC协议的FPGA网络下载器。- 最高支持53M
- 支持4路JTAG独立使用
- 支持端口合并
- 支持国产FLASH烧写
- 下载器无限扩展
- 配备专属程序固化软件,一键烧写,能大大减小程序固化时间!