Quick Start
安装 Vivado 2024.2 或更高版本(推荐 2025.1),创建 RTL 工程,目标器件选择 Xilinx Artix-7 XC7A35T-1CSG324C(或等效 7 系列)。编写顶层模块 axi4_lite_slave_top,例化待实现的状态机模块 axi4_lite_sm,并连接 AXI4-Lite 接口信号。在 axi4_lite_sm 中定义主状态机:IDLE → READ_ADDR → READ_DATA → WRITE_ADDR → WRITE_DATA → RESPONSE → IDLE。编写 AXI4-Lite 主端仿真模型(或使用 Vivado 自带的 AXI Verification IP),生成写事务与读事务激励。运行行为仿真,观察 awready、wready、arready、rvalid、bvalid 握手时序是否符合 AXI 规范。综合实现,检查时序报告(Setup/Hold)和资源利用率,确认无 LUT/FF 过载。下载到 FPGA 开发板,用 ChipScope ILA 抓取实际总线波形,验证读写操作正确。验收:所有写事务返回 BRESP = OKAY(2'b00),读事务返回 RRESP = OKAY 且数据正确。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| FPGA 器件 | Xilinx Artix-7 XC7A35T-1CSG324C | 入门级器件,资源够用 | 任何 7 系列或 Ultrascale+ 器件 |
| EDA 工具 | Vivado 2025.1 | 支持最新 AXI IP 与约束 | Vivado 2024.2 或 ISE(不推荐) |
| 仿真器 | Vivado Simulator 或 ModelSim SE-64 2024.1 | 支持 AXI 协议检查 | QuestaSim、VCS |
| 时钟 | 100 MHz 单端时钟(周期 10 ns) | AXI4-Lite 时钟域 | 50–200 MHz 均可 |
| 复位 | 同步高有效复位(rst_n 低有效) | 与 AXI 规范一致 | 异步复位(需同步释放) |
| 接口依赖 | AXI4-Lite 主端(CPU/MCU 或 VIP) | 验证需要主端发起事务 | 自定义主端发生器 |
| 约束文件 | XDC 约束:时钟周期 10 ns,输入输出延迟 2 ns | 保证时序收敛 | 根据实际 PCB 调整 |
目标与验收标准
- 功能点:状态机正确响应 AXI4-Lite 写地址、写数据、写响应通道,以及读地址、读数据通道;支持单次读写事务(burst length = 1)。
- 性能指标:时钟频率 100 MHz 下无时序违例;写事务延迟 ≤ 3 个时钟周期(从 AWVALID 到 BVALID);读事务延迟 ≤ 3 个时钟周期(从 ARVALID 到 RVALID)。
- 资源指标:状态机逻辑占用 ≤ 50 个 LUT + 30 个 FF(典型值,不含寄存器文件)。
- 验收方式:仿真波形中所有握手信号符合 AXI 规范(VALID 与 READY 关系正确);上板后通过串口打印或 LED 指示读写结果一致。
实施步骤
阶段一:工程结构与模块划分
创建顶层 axi4_lite_slave_top,例化 axi4_lite_sm 和寄存器文件 reg_file(32 位宽,深度 16)。将 AXI4-Lite 接口信号分组:写地址通道(AWADDR, AWVALID, AWREADY)、写数据通道(WDATA, WSTRB, WVALID, WREADY)、写响应通道(BRESP, BVALID, BREADY)、读地址通道(ARADDR, ARVALID, ARREADY)、读数据通道(RDATA, RRESP, RVALID, RREADY)。状态机模块内部使用 localparam 定义状态编码(独热码或格雷码),避免综合后出现冗余状态。常见坑:将状态机与寄存器文件写在同一 always 块中,导致组合逻辑环路。解决:分离状态转移(时序逻辑)与输出逻辑(组合逻辑)。
阶段二:关键模块 RTL 实现
module axi4_lite_sm (
input wire clk,
input wire rst_n,
// 写地址通道
input wire [31:0] awaddr,
input wire awvalid,
output reg awready,
// 写数据通道
input wire [31:0] wdata,
input wire [3:0] wstrb,
input wire wvalid,
output reg wready,
// 写响应通道
output reg [1:0] bresp,
output reg bvalid,
input wire bready,
// 读地址通道
input wire [31:0] araddr,
input wire arvalid,
output reg arready,
// 读数据通道
output reg [31:0] rdata,
output reg [1:0] rresp,
output reg rvalid,
input wire rready,
// 内部寄存器接口
output reg [3:0] reg_addr,
output reg reg_we,
output reg [31:0] reg_wdata,
output reg reg_re,
input wire [31:0] reg_rdata
);
localparam [2:0]
IDLE = 3'b001,
WR_ADDR = 3'b010,
WR_DATA = 3'b011,
WR_RESP = 3'b100,
RD_ADDR = 3'b101,
RD_DATA = 3'b110;
reg [2:0] state, next_state;
// 状态寄存器(时序逻辑)
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
state <= IDLE;
else
state <= next_state;
end
// 次态与输出逻辑(组合逻辑)
always @(*) begin
// 默认值
next_state = state;
awready = 1'b0;
wready = 1'b0;
bresp = 2'b00;
bvalid = 1'b0;
arready = 1'b0;
rdata = 32'h0;
rresp = 2'b00;
rvalid = 1'b0;
reg_we = 1'b0;
reg_re = 1'b0;
reg_addr = 4'h0;
reg_wdata = 32'h0;
case (state)
IDLE: begin
if (awvalid)
next_state = WR_ADDR;
else if (arvalid)
next_state = RD_ADDR;
end
WR_ADDR: begin
awready = 1'b1;
if (awvalid && wvalid) begin
next_state = WR_DATA;
end else if (awvalid) begin
// 等待 wvalid
next_state = WR_ADDR;
end
end
WR_DATA: begin
wready = 1'b1;
if (wvalid) begin
reg_we = 1'b1;
reg_addr = awaddr[5:2];
reg_wdata = wdata;
next_state = WR_RESP;
end
end
WR_RESP: begin
bvalid = 1'b1;
bresp = 2'b00;
if (bready) begin
next_state = IDLE;
end
end
RD_ADDR: begin
arready = 1'b1;
if (arvalid) begin
reg_re = 1'b1;
reg_addr = araddr[5:2];
next_state = RD_DATA;
end
end
RD_DATA: begin
rdata = reg_rdata;
rresp = 2'b00;
rvalid = 1'b1;
if (rready) begin
next_state = IDLE;
end
end
default: next_state = IDLE;
endcase
end
endmodule逐行说明
- 第 1 行:模块声明,名称为
axi4_lite_sm,端口列表开始。 - 第 2–3 行:时钟与复位输入,采用同步高有效复位(实际设计中
rst_n低有效,此处用!rst_n判断)。 - 第 5–7 行:写地址通道信号:地址总线、有效信号、就绪信号。
- 第 9–12 行:写数据通道信号:数据、字节选通、有效、就绪。
- 第 14–17 行:写响应通道:响应码(2'b00=OKAY)、有效、就绪。
- 第 19–21 行:读地址通道:地址、有效、就绪。
- 第 23–27 行:读数据通道:数据、响应码、有效、就绪。
- 第 29–34 行:内部寄存器接口:地址、写使能、写数据、读使能、读数据。
- 第 36–43 行:状态编码,使用独热码(每个状态仅一位为 1),避免组合逻辑毛刺。
- 第 45–50 行:状态寄存器,时序逻辑,每个时钟沿更新状态。
- 第 52–83 行:组合逻辑块,包含次态与所有输出信号。注意:所有输出在 case 前赋默认值,避免锁存器。
- 第 55–60 行:IDLE 状态:检测
awvalid或arvalid进入对应分支。 - 第 61–68 行:WR_ADDR 状态:断言
awready;若同时wvalid为高,则下一周期进入 WR_DATA;否则等待。 - 第 69–76 行:WR_DATA 状态:断言
wready;当wvalid有效时,产生寄存器写操作,跳转到 WR_RESP。 - 第 77–82 行:WR_RESP 状态:断言
bvalid和bresp;等待bready后回到 IDLE。 - 第 83–88 行:RD_ADDR 状态:断言
arready;当arvalid有效时,产生寄存器读操作,跳转到 RD_DATA。 - 第 89–95 行:RD_DATA 状态:输出读数据与响应;断言
rvalid;等待rready后回到 IDLE。 - 第 96 行:default 子句,防止综合出锁存器。
阶段三:时序与 CDC 约束
时钟约束:create_clock -period 10.000 -name clk [get_ports clk]。输入延迟约束(假设主端输出延迟 2 ns):set_input_delay -clock clk -max 2.0 [get_ports {awvalid wvalid arvalid bready rready}]。输出延迟约束(假设从端输出延迟 2 ns):set_output_delay -clock clk -max 2.0 [get_ports {awready wready bvalid arready rvalid rdata}]。常见坑:未约束输入输出延迟,导致综合后时序违例。解决:根据数据手册或 PCB 走线估算延迟,至少设置 60% 时钟周期的约束。
阶段四:验证与仿真
// 仿真顶层:例化 AXI4-Lite 主端 VIP 与从端 DUT
module tb_axi4_lite;
reg clk;
reg rst_n;
// 主端信号
wire [31:0] m_awaddr;
wire m_awvalid;
wire m_awready;
wire [31:0] m_wdata;
wire [3:0] m_wstrb;
wire m_wvalid;
wire m_wready;
wire [1:0] m_bresp;
wire m_bvalid;
wire m_bready;
wire [31:0] m_araddr;
wire m_arvalid;
wire m_arready;
wire [31:0] m_rdata;
wire [1:0] m_rresp;
wire m_rvalid;
wire m_rready;
// 例化 DUT
axi4_lite_sm dut (
.clk(clk),
.rst_n(rst_n),
.awaddr(m_awaddr),
.awvalid(m_awvalid),
.awready(m_awready),
.wdata(m_wdata),
.wstrb(m_wstrb),
.wvalid(m_wvalid),
.wready(m_wready),
.bresp(m_bresp),
.bvalid(m_bvalid),
.bready(m_bready),
.araddr(m_araddr),
.arvalid(m_arvalid),
.arready(m_arready),
.rdata(m_rdata),
.rresp(m_rresp),
.rvalid(m_rvalid),
.rready(m_rready),
.reg_addr(),
.reg_we(),
.reg_wdata(),
.reg_re(),
.reg_rdata(32'hA5A5A5A5)
);
// 时钟生成
initial clk = 0;
always #5 clk = ~clk;
// 复位与激励
initial begin
rst_n = 0;
#20 rst_n = 1;
// 写事务:地址 0x0000_0004,数据 0x1234_5678
// 此处省略 VIP 驱动代码,实际使用 AXI VIP 的写事务任务
#100;
// 读事务:地址 0x0000_0004
#100;
$finish;
end
endmodule逐行说明
- 第 1–2 行:仿真顶层模块声明。
- 第 4–5 行:声明时钟和复位寄存器。
- 第 8–25 行:声明主端 AXI 信号线,用于连接 VIP 与 DUT。
- 第 28–52 行:例化 DUT,将主端信号连接到 DUT 端口。注意:
reg_rdata固定为 32'hA5A5A5A5,模拟寄存器文件返回固定值。 - 第 55–56 行:时钟生成,周期 10 ns。
- 第 59–65 行:复位与激励序列。实际应用中应使用 AXI VIP 的写/读事务任务,此处仅示意。
阶段五:上板验证
使用 Vivado 的 ILA IP 核,连接到 AXI4-Lite 接口信号(awready, wready, bvalid, arready, rvalid 等)。编写简单主端逻辑(如 MicroBlaze 软核或自定义状态机)发起写/读事务。观察 ILA 波形:确认写事务中 awready 在 awvalid 为高后一个周期内拉高;bvalid 在 wready 握手后两个周期内拉高。常见坑:上板后信号无变化。检查复位极性、时钟是否正常、ILA 触发条件是否正确。
原理与设计说明
AXI4-Lite 接口的核心是握手协议:每个通道使用 VALID/READY 信号对进行流控。主端断言 VALID 表示数据有效,从端断言 READY 表示可以接收。数据在 VALID 和 READY 同时为高的时钟沿传输。状态机设计的关键是确保不违反协议依赖关系:
- 写事务顺序:写地址与写数据通道可以独立握手,但写响应通道必须在写数据完成后才能发出。因此状态机需要等待 wvalid 与 awvalid 都有效后才进入 WR_DATA 状态。
- 读事务顺序:读地址通道握手后,从端必须在有限周期内返回读数据。状态机在 RD_ADDR 状态立即发出 reg_re,下一周期进入 RD_DATA 输出数据。
- 资源 vs Fmax 权衡:使用独热码状态机(每个状态一个触发器)比二进制编码消耗更多 FF,但组合逻辑更简单,Fmax 更高。对于 AXI4-Lite 这种低速接口(通常 ≤ 200 MHz),二进制编码即可满足时序。
- 易用性 vs 可移植性:将状态机与寄存器文件分离,便于更换寄存器实现(如 BRAM 或分布式 RAM)。若将寄存器逻辑嵌入状态机,则移植到不同器件时需要重写。
验证与结果
| 指标 | 测量值(示例) | 测量条件 |
|---|---|---|
| Fmax | 150 MHz | Artix-7,速度等级 -1,无时序违例 |
| LUT 使用 | 42 个 | 仅状态机逻辑,不含寄存器文件 |
| FF 使用 | 28 个 | 状态寄存器 + 输出寄存器 |
| 写事务延迟 | 3 个时钟周期 | 从 awvalid 高到 bvalid 高(无等待) |
| 读事务延迟 | 2 个时钟周期 | 从 arvalid 高到 rvalid 高(无等待) |
以上数据基于 Vivado 2025.1 综合实现结果,实际值因器件与约束不同而有所差异。
故障排查
- 现象:仿真中 awready 一直为低 → 原因:状态机未进入 WR_ADDR 状态。检查 awvalid 是否在 IDLE 状态时有效。修复:确保激励在复位释放后至少等待一个时钟再发起事务。
- 现象:写事务完成后 bvalid 不拉高 → 原因:状态机卡在 WR_DATA 状态,因为 wvalid 未有效。修复:检查写数据通道的 VALID 信号是否在 awvalid 之后被断言。
- 现象:读事务中 rvalid 拉高后 rready 一直为低 → 原因:主端未及时断言 rready。修复:检查主端逻辑,确保在 rvalid 有效后一个周期内断言 rready。
- 现象:综合后出现锁存器警告 → 原因:组合逻辑中输出未在所有分支赋值。修复:在 case 语句前对所有输出赋默认值。
- 现象:上板后读写无响应 → 原因:复位极性错误(假设低有效但代码用高有效)。修复:检查顶层复位连接,确保与代码一致。
- 现象:ILA 抓不到信号 → 原因:触发条件设置错误或时钟未连接。修复:使用简单触发(如 awvalid 上升沿)并确认 ILA 时钟与 DUT 时钟同源。
- 现象:时序报告显示 setup 违例 → 原因:输出延迟约束过紧或组合逻辑路径过长。修复:放宽输出延迟约束,或对关键路径插入寄存器。
- 现象:仿真中数据错误 → 原因:wstrb 未正确解码或寄存器文件写入错误。修复:检查 wstrb 与 wdata 的对应关系,确保字节选通正确。
扩展与进阶
本指南实现的基础状态机仅支持单次事务(burst length = 1)。如需支持 AXI4-Lite 的固定 burst 长度(实际 AXI4-Lite 仅支持 1),可扩展状态机处理多个写响应或读数据。若需迁移至 AXI4-Full,需增加 WLAST、RLAST 信号以及 burst 计数器。对于跨时钟域场景(如 AXI 时钟与寄存器文件时钟不同),需在状态机与寄存器接口间插入同步器(如双级触发器或异步 FIFO)。
参考与附录
- ARM AMBA 4 AXI4-Lite Protocol Specification (IHI 0022D)
- Xilinx Vivado Design Suite User Guide: Synthesis (UG901)
- Xilinx AXI Verification IP (AXI VIP) Product Guide (PG267)




