手把手教你用Verilog实现AXI-FULL主从机通信(附完整仿真代码)

张开发
2026/4/22 9:37:43 15 分钟阅读
手把手教你用Verilog实现AXI-FULL主从机通信(附完整仿真代码)
从零构建AXI-FULL主从通信Verilog实战指南与仿真解析在FPGA和数字IC设计领域AXI协议已成为片上通信的事实标准。但对于初学者而言面对AXI-FULL协议复杂的信号交互和严格的时序要求往往感到无从下手。本文将从一个具体的DDR读写测试场景出发通过可运行的Verilog代码示例拆解AXI-FULL主从通信的实现细节。不同于单纯的理论讲解我们将聚焦三个核心目标理解握手信号机制、掌握突发传输控制、构建完整的验证环境。跟随本文的步骤您将获得一个可直接用于项目的AXI-FULL通信框架。1. AXI-FULL协议核心机制解析AXI-FULL协议的精髓在于其基于VALID/READY的握手机制。这种非阻塞式的通信方式允许主从设备以最高效率协调数据传输。在实际硬件设计中理解这种机制对避免死锁和保证吞吐量至关重要。关键信号交互原理VALID信号由发起方驱动表示地址、数据或控制信息有效READY信号由接收方驱动表示已准备好接收信息传输时机只有当VALID和READY同时为高时传输才会发生// 典型的写地址通道握手代码段 always_ff (posedge ACLK or negedge ARESETn) begin if (!ARESETn) begin AWVALID 1b0; end else if (state SEND_ADDR !AWVALID) begin AWVALID 1b1; // 主设备发出地址有效信号 end else if (AWVALID AWREADY) begin AWVALID 1b0; // 握手完成 end end突发传输是AXI-FULL的另一大特性它允许单个地址相位后跟随多个数据相位。我们的示例中使用的是INCR增量突发类型其地址计算规则为突发长度地址增量适用场景1-16数据宽度小批量连续数据17-256数据宽度大批量DMA传输状态机设计要点明确划分IDLE、ADDR、DATA、RESP等状态每个状态转换必须检查对应的握手信号突发计数器需要与LAST信号同步2. 主设备实现详解我们的主设备需要完成从指定地址读取数据、加工后写回的全过程。这个看似简单的任务实际上涵盖了AXI-FULL最常用的操作模式。2.1 读通道实现策略读操作涉及两个独立的通道读地址通道和读数据通道。这两个通道可以并行工作极大提高了总线利用率。关键实现代码// 读地址通道控制 always_comb begin if (state READ !ARVALID !rd_addr_sent) begin ARADDR start_addr; ARLEN burst_length - 1; // AXLEN实际值为传输次数减1 ARVALID 1b1; end else begin ARVALID 1b0; end end // 读数据通道处理 always_ff (posedge ACLK or negedge ARESETn) begin if (!ARESETn) begin data_buffer {default:0}; end else if (RVALID RREADY) begin data_buffer[rd_cnt] RDATA; if (RLAST) rd_done 1b1; end end2.2 写通道实现技巧写操作更为复杂涉及三个通道的协调写地址、写数据和写响应。其中最容易出错的是WLAST信号的生成时机。常见问题解决方案问题现象可能原因解决方法写响应超时WLAST未正确生成检查wr_cnt与AWLEN的匹配数据丢失WREADY未及时响应增加写数据FIFO缓冲地址错误突发类型配置错误确认AWBURST设置为2b01(INCR)// 写数据通道关键代码 always_ff (posedge ACLK or negedge ARESETn) begin if (!ARESETn) begin wr_cnt 0; WLAST 1b0; end else if (WVALID WREADY) begin if (wr_cnt AWLEN) begin WLAST 1b1; wr_cnt 0; end else begin wr_cnt wr_cnt 1; WLAST 1b0; end end end3. 从设备设计与仿真验证一个可靠的从设备模型对验证主设备行为至关重要。我们的测试从机需要模拟存储器的基本特性同时严格遵循AXI协议时序。3.1 存储器模型构建// 双端口存储器模型 logic [63:0] mem [0:31]; // 初始化存储器 initial begin foreach (mem[i]) begin mem[i] i; // 初始化测试数据 end end // 写操作处理 always_ff (posedge ACLK or negedge ARESETn) begin if (!ARESETn) begin foreach (mem[i]) mem[i] 64h0; end else if (WVALID WREADY) begin mem[wr_cnt] WDATA; // 写入数据 end end3.2 测试平台搭建要点完整的测试平台需要关注以下几个关键方面时钟与复位生成initial begin ACLK 0; forever #5 ACLK ~ACLK; // 100MHz时钟 end initial begin ARESETn 0; #20 ARESETn 1; // 复位脉冲 end自动检查机制// 写回数据验证 always (posedge ACLK) begin if (BVALID BREADY BRESP 2b00) begin foreach (mem[i]) begin if (mem[i] ! i 1) begin $error(Data mismatch at address %0d, i); end end $display(Test passed!); $finish; end end时序违规检测// 检查VALID-READY时序规则 always (posedge ACLK) begin if (ARVALID !ARREADY) begin #1 if (ARVALID !ARREADY) $warning(ARVALID held too long without ARREADY); end end4. 高级调试技巧与性能优化当基本功能验证通过后我们需要关注通信效率和资源利用率。以下是一些实战中总结的优化方法4.1 吞吐量提升策略通道并行化读操作中可以在第一个数据返回前就发起新的地址请求写操作中地址通道和数据通道可以完全并行OUTSTANDING传输通过增加ID信号支持多个未完成交易需要设计相应的ID管理逻辑// OUTSTANDING写示例 logic [3:0] awid_cnt; logic [3:0] outstanding_writes; always_ff (posedge ACLK or negedge ARESETn) begin if (!ARESETn) begin outstanding_writes 0; end else begin case ({AWVALID AWREADY, BVALID BREADY}) 2b10: outstanding_writes outstanding_writes 1; 2b01: outstanding_writes outstanding_writes - 1; default: ; endcase end end4.2 常见问题快速定位使用波形调试时重点关注以下信号组合死锁情况检查所有VALID信号是否都有对应的READY响应数据错误对比R/WDATA与预期值检查地址计算性能瓶颈统计VALID-READY握手延迟时间调试检查表问题类型关键信号正常表现读通道阻塞ARVALID/ARREADY每个突发传输只握手一次数据丢失RVALID/RREADY每个突发长度对应正确数据量写响应异常BVALID/BREADY每次突发写后有一个响应在Xilinx Vivado中可以设置AXI协议检查器自动检测违规行为set_property CONFIG.ENABLE_PROTOCOL_CHECKS true [get_bd_cells axi_verify]5. 工程扩展与实际应用基础框架验证通过后可以考虑以下扩展方向参数化设计module axi_master #( parameter DATA_WIDTH 64, parameter ADDR_WIDTH 32, parameter ID_WIDTH 4 ) ( // 端口定义 );DMA集成添加描述符管理逻辑实现数据流控制机制支持链式传输跨时钟域处理在AXI接口添加CDC逻辑使用异步FIFO缓冲数据// 异步FIFO实例化 axi_cdc_fifo #( .DATA_WIDTH(64), .DEPTH(8) ) u_write_fifo ( .s_axi_aclk(ACLK), .m_axi_aclk(other_clk), // 其他连接信号 );实际项目中AXI-FULL接口常用于以下场景高性能DMA引擎自定义加速器互联片外存储器控制器多核处理器通信在实现更复杂的AXI系统时建议采用逐步验证的方法先确保单个主从对工作正常再扩展为交叉开关互联的多主多从系统。同时合理使用AXI Interconnect IP可以显著减少开发时间。

更多文章