FPGA 中的 AXI 总线介绍
1. AXI 家族一张图
AXI4 ------ 存储器映射,高带宽突发读写(DDR/HP端口)
AXI4-Lite ------ 存储器映射,低带宽寄存器读写(控制/状态寄存器)
AXI4-Stream------ 纯数据流,无地址,适合高速流水线(DMA/视频/ADC数据)
分层理念:
-
控制面:AXI4-Lite(寄存器、启动/停止、阈值等)
-
数据面:AXI4(到内存)或 AXI4-Stream(流→DMA→内存/外设)
-
中间衔接:DMA / Interconnect / SmartConnect / Clock Converter / Protocol Converter
2. AXI 通道与握手:VALID/READY 的"一进一出"
AXI4/AXI4-Lite 有 5 条通道(读写各自独立):
-
写地址
AW*
、写数据W*
、写响应B*
-
读地址
AR*
、读数据R*
AXI4-Stream 只有数据通道 :TVALID
/TREADY
/TDATA
/TLAST
/TKEEP
/TUSER
黄金法则 :只有当 VALID=1
且 READY=1
的那个周期,数据/地址才被"传送" 。
背压(Backpressure)由 从属端 通过拉低 READY
产生,上游必须_保持_当前拍数据与控制信号稳定直至握手达成。
3. 关键信号速查(常见子集)
3.1 AXI4/AXI4-Lite
-
地址:
AWADDR
/ARADDR
(字节地址),AWLEN
/ARLEN
(突发长度,AXI4) -
大小:
AWSIZE
/ARSIZE
(一次 beat 的字节数编码) -
类型:
AWBURST
/ARBURST
(固定/递增/环回) -
写数据:
WDATA
、WSTRB
(字节写使能)、WLAST
-
读数据:
RDATA
、RRESP
、RLAST
-
ID/排序:
AWID
/ARID
+BID
/RID
(并发与乱序完成) -
属性:
PROT
/CACHE
/QOS
(缓存、仲裁提示,SoC 上常用)
3.2 AXI4-Stream
-
TDATA[N-1:0]
、TKEEP
、TLAST
(分帧)、TUSER
(带外/副通道) -
TID
/TDEST
(路由/多路)
4. 吞吐/时延估算(常用公式,便于选型)
-
单口有效吞吐(以 beat 为单位):
Throughput≈DataWidth(bits)×Utilization×fclk \text{Throughput} \approx \text{DataWidth(bits)} \times \text{Utilization} \times f_{\text{clk}} Throughput≈DataWidth(bits)×Utilization×fclk -
含
WSTRB
的有效字节率(写):
ByteRate≈(∑WSTRB_onesBeats)fclk \text{ByteRate} \approx \left(\frac{\sum \text{WSTRB\ones}}{\text{Beats}}\right) f{\text{clk}} ByteRate≈(Beats∑WSTRB_ones)fclk -
突发的平均利用率(读/写):
Utilization≈BeatsBeats+WaitCycles \text{Utilization} \approx \frac{\text{Beats}}{\text{Beats}+\text{WaitCycles}} Utilization≈Beats+WaitCyclesBeats -
环形缓冲抗抖动容量:
Buffer≥(Rin‾−Rout‾)+×Tburst \text{Buffer} \ge (\overline{R_{\text{in}}}-\overline{R_{\text{out}}})^{+}\times T_{\text{burst}} Buffer≥(Rin−Rout)+×Tburst
5. 设计套路:三大典型拓扑
5.1 "寄存器 + 流"的双面架构
-
AXI4-Lite:配置/状态(门槛、模式、计数器)
-
AXI4-Stream:数据面(ADC→DSP→FIFO→DMA)
5.2 "流→内存"的 DMA 架构
-
流侧 AXIS:
TVALID/TREADY/TLAST
分帧 -
DMA(如 Xilinx AXI DMA/Datamover、XDMA)把 AXIS 写入 DDR(AXI4),再由 CPU/PCIe 读
5.3 "内存→流"的回放架构
- 读 DDR(AXI4)→ Datamover → AXIS → 下游 IP / DAC
建议 :控制面与数据面分时钟域 、分层清晰;跨域用 AXI Clock Converter 或 AXIS FIFO(CDC)。
6. 时序与约束:稳定系统的底线
-
保持规则 :当
VALID=1
且对端READY=0
,所有负载信号必须保持不变(地址、数据、ID、LAST、KEEP...)。 -
Skid Buffer(单拍弹簧):在 READY 可能抖动的边界(如跨层/跨时钟)加一拍寄存器或小 FIFO,避免毛刺/违约。
-
跨时钟域:优先用官方 CDC IP;手写 AXIS CDC 需用灰码计数 + 双口 RAM。
-
AXI4-Lite :地址与数据通道可乱序到达,但一次写的 AW/W 必须成对,常用"打拍对齐"以简化。
7. 常见突发(AXI4)与对齐
-
INCR
递增突发最常用,AWLEN/ARLEN
指定 beat 数(len+1)。 -
AWSIZE/ARSIZE
应与数据宽度匹配(如 64bit→SIZE=3'b011
),否则注意字节对齐与掩码。 -
WLAST/RLAST
宣告突发最后一个 beat。
最佳实践 :对齐到缓存线/DDR 突发边界 ,LEN
选择让控制器最省开销(例如 16 或 32 beats)。
8. AXI4-Lite:寄存器地图与最小从机骨架
8.1 典型寄存器地图(可直接套用)
0x000 VERSION R 固件版本
0x004 BUILD_TIME R 构建时间戳
0x010 CTRL RW [0]start [1]stop [8]soft_rst
0x014 STATUS R [0]running [1]err [2]fifo_af
0x020 CFG0 RW 用户参数0
0x024 CFG1 RW 用户参数1
0x030 STAT_PKTS R 包计数
0x034 STAT_DROP R 丢包计数
8.2 Verilog:AXI-Lite 从机框架(片段,可直接改)
verilog
// reply 2
module axil_regs #(
parameter ADDR_W = 12
)(
input wire ACLK,
input wire ARESETN,
// AXI-Lite Slave interface (简化命名)
input wire [ADDR_W-1:0] S_AWADDR, input wire S_AWVALID, output wire S_AWREADY,
input wire [31:0] S_WDATA, input wire [3:0] S_WSTRB,
input wire S_WVALID, output wire S_WREADY,
output reg [1:0] S_BRESP, output reg S_BVALID, input wire S_BREADY,
input wire [ADDR_W-1:0] S_ARADDR, input wire S_ARVALID, output wire S_ARREADY,
output reg [31:0] S_RDATA, output reg [1:0] S_RRESP,
output reg S_RVALID, input wire S_RREADY,
output reg [31:0] reg_ctrl,
input wire [31:0] reg_status,
output reg [31:0] reg_cfg0,
output reg [31:0] reg_cfg1,
input wire [31:0] stat_pkts,
input wire [31:0] stat_drop
);
// 省略握手状态机:建议用"一拍写、一拍应答"模板 + skid buffer
// 写通道
// ...(AW/W 对齐、WSTRB 应用、BRESP=OKAY)
// 读通道
always @(*) begin
case (S_ARADDR[ADDR_W-1:0])
12'h010: S_RDATA = reg_ctrl;
12'h014: S_RDATA = reg_status;
12'h020: S_RDATA = reg_cfg0;
12'h024: S_RDATA = reg_cfg1;
12'h030: S_RDATA = stat_pkts;
12'h034: S_RDATA = stat_drop;
default: S_RDATA = 32'hDEAD_BEEF;
endcase
end
// TODO: 完整握手与复位逻辑
endmodule
9. AXI4-Stream:分帧、背压与 TKEEP
-
分帧用
TLAST
;字节有效用TKEEP
;副通道/标记用TUSER
。 -
背压 :当下游
TREADY=0
时,上游必须保持当前T*
。 -
合规 FIFO:用官方 AXIS FIFO/RegSlice/SkidBuffer,既做 CDC 也做打拍。
Verilog:极简 AXIS 直连(带背压)
verilog
// reply 2
assign m_tdata = s_tdata;
assign m_tkeep = s_tkeep;
assign m_tlast = s_tlast;
assign m_tvalid = s_tvalid;
assign s_tready = m_tready; // 背压直通
10. AXI 到 DDR:Datamover/DMA 的"正确打开方式"
-
写 DDR(S2MM):AXIS→Datamover 写通道→AXI4(AW/W/B)
-
读 DDR(MM2S):AXI4(AR/R)→Datamover 读通道→AXIS
-
描述符环 :主机/PS 侧准备物理地址+长度;FPGA 侧按
TLAST
/帧界定填充 -
性能关键 :突发对齐、
LEN
合理、足够 outstanding、避免小包抖动
11. Interconnect/SmartConnect 仲裁与并发
-
仲裁:固定优先级/轮询/加权;避免低优先级长期饥饿
-
并发 :利用
ID
拆分/聚合事务;保证必要的顺序一致性(同 ID 保序) -
带宽规划 :上游峰值之和 > DDR 可承载 → 必须引入节流/缓存 与背压传播
12. 常见问题清单(踩坑速救)
-
VALID 稳定性违规:READY 拉低时仍改变负载 → 随机丢/错
-
WSTRB 误用:半字/字节写未掩码 → 覆盖邻近寄存器/数据
-
WLAST/RLAST 漏/多:突发粘包或过早终止 → 下游状态机异常
-
突发未对齐:穿越 DDR 突发边界 → 带宽骤降
-
CDC 漏做:跨时钟域直接连 → 间歇性死锁/毛刺
-
Outstanding 太少:高延迟 DDR 下吞吐拉胯
-
Interconnect 饥饿:固定优先级压死低优口,统计计数器飙升
-
AXIS 无缓冲:READY 抖动导致上游气泡,速率不达标
13. 约束与验证建议
-
时序约束:为 AXI/AXIS 时钟域分别建时钟、设置 IO 延时、跨域 false path 交给 CDC IP
-
仿真:使用 AXI VIP/Bus Functional Model,覆盖:单拍、长突发、背压、乱序、错误响应
-
硬件观测:ILA 插到关键握手与 FIFO 水位;统计寄存器记录丢包/背压时间
-
压测:PRBS/计数器源,长时间跑(1h/24h),记录 Utilization/Drop
14. 可复用模块清单(建议直接用 IP/骨架)
-
Clock/Protocol Converter:AXI Clock Converter、Protocol Converter
-
流水稳态:AXI/AXIS RegSlice、Skid Buffer、AXIS FIFO(CDC)
-
存储搬运:AXI DMA / Datamover / CDMA / XDMA(PCIe)
-
互连:AXI Interconnect / SmartConnect(多主多从)
-
验证:AXI VIP、AXIS VIP、Scoreboard + Coverage
15. 迷你模板:AXIS 到 AXI4 的"打包写"控制器(思路)
-
累计
BeatCnt
与字节数,遇到TLAST
或计数达阈值 → 触发一次写突发 -
生成
AW*
(地址、LEN、SIZE、BURST),随后打出W*
序列并在最后一拍置WLAST
-
等待
B*
应答;统计BRESP
错误 -
地址按固定步长递增,跨页换描述符
结合 Datamover 可显著简化,实现上尽量复用官方 IP,自己写控制层逻辑即可。
16. 收尾:一条"黄金路径"
-
确定数据面/控制面分工(AXI-Stream + AXI4-Lite)
-
规划带宽与突发参数(对齐缓存线/DDR 突发)
-
插足够的 RegSlice/FIFO/CDC 保证稳定与时序
-
利用 DMA/Datamover 落地"流↔内存"
-
用统计计数器 + ILA 做长期压测与定位
-
把寄存器地图/协议写成文档,与上位机脚手架一并版本化