AXI4-Full突发传输掉数据——突发长度算错、WRAP边界、窄传输字节错位,调试一周才发现是协议理解错了 📅 2026/7/14 13:37:06 AXI4-Full是AXI协议族里最复杂的一种——支持突发传输、支持乱序、支持多机并行。很多人以为AXI4-Full就是“AXI4-Lite BURST”结果一写代码就踩坑数据丢了、顺序乱了、WRAP传输直接卡死。这篇把AXI4-Full最常见的4个致命坑全部拆开配上核心代码片段。完整工程代码DMA控制器、WRAP地址生成、窄传输处理、突发错误处理可“私信”获取。痛苦点一突发长度算错传输一半就断了问题描述你用AXI4-Full做DMA从DDR读4KB数据到FPGA内部BRAM结果只读了一半。C// 读4KB数据32bit接口1024次传输AXI_DMA_Read(src_addr0x10000000, length4096);仿真时发现只读了512个数据2KB剩下的一半不见了。根本原因AXI4-Full的突发长度AxLEN编码规则AxLEN[7:0]值实际突发长度说明0x001次AxLEN0表示1次传输0x012次0x0F16次0xFF256次AXI4最大值AxLEN 实际传输次数 - 1如果你要读1024次必须设置AxLEN 10230x3FF但AXI4单突发最大256次AxLEN255所以不能一次发完必须拆成多个突发。错误做法verilog// ❌ 错误AxLEN直接填传输次数assign arlen 16d1024; // ❌ 这表示1025次传输AXI4会截断assign arlen 16d256; // ❌ 这表示257次传输// ❌ 错误的突发拆分// 想读1024次拆成4个突发assign arlen_0 16d256; // 257次assign arlen_1 16d256; // 257次assign arlen_2 16d256; // 257次assign arlen_3 16d255; // 256次// 总计257257257256 1027次 ← 多了3次正确做法关键公式verilog// ✅ 核心公式AxLEN beats - 1// 4KB数据32bit接口 → 1024 beats// AXI4单突发最多256 beats → 拆成4个突发每个arlen255// 最后一次不足256 beat时arlen (剩余beats) - 1 完整DMA读控制器代码包含突发拆分、地址累加、状态机点击“阅读原文”获取。注意AxLEN最大取值为0xFF255硬件IP/Interconnect会直接截断超长突发不能一次下发1023。关键计算公式参数公式总传输次数ceil(字节数 / (数据位宽/8))突发次数ceil(总传输次数 / 最大突发长度)AxLEN实际传输次数 - 1痛苦点二WRAP突发传输出错地址跳回起点后数据乱了问题描述用WRAP模式读环形缓冲区地址回绕后数据顺序全乱。verilog// 从地址0x100开始突发长度16WRAP边界256字节assign araddr 32h00000100;assign arlen 8d15; // 16次传输assign arburst 2b10; // WRAP模式仿真时发现第12次传输后地址不是0x110而是跳回了0x100数据顺序全乱了。根本原因WRAP突发的地址计算规则和INCR完全不同突发模式地址变化适用场景FIXED (00)地址不变FIFO读写INCR (01)地址递增普通内存访问WRAP (10)到达边界后回绕Cache行填充WRAP边界 突发长度 × 传输字节数且边界必须是2的幂。错误做法verilog// ❌ 起始地址不在边界上assign araddr 32h00000110; // 0x110边界64字节预期会回绕到0x100正确做法核心计算verilog// ✅ WRAP边界 (arlen1) × (1 arsize)// 低位掩码 边界 - 1// 当前地址 高位(起始地址 ~掩码) 低位((起始偏移 累加步长) 掩码)工程建议实际项目中90%的场景用INCR即可WRAP主要用于Cache行填充。如果不需要WRAP直接用arburst 2b01INCR。WRAP使用场景总结场景是否用WRAP原因普通内存读写❌ 用INCR简单可靠FIFO读写❌ 用FIXED地址不变Cache行填充✅ 用WRAP提升Cache性能循环缓冲区可选INCR地址回绕更直观痛苦点三窄传输Narrow Transfer字节错位问题描述64bit AXI接口连接32bit外设写入数据后读回错位。verilog// 64bit AXI接口// 但外设寄存器是32bit// 地址0x00: reg0 (32bit)// 地址0x04: reg1 (32bit)// 地址0x08: reg2 (32bit)// 地址0x0C: reg3 (32bit)你写入64bit数据到地址0x00期望写到reg0和reg1但读回来发现数据全错了。根本原因AXI的WSTRB写选通信号决定了哪些字节有效。窄传输是指数据位宽大于实际传输大小需要用WSTRB选择有效字节。AXI读无RSTRB读窄传输靠地址区分数据位置地址bit[2]用来选择64bit接口中的高低32bit这是窄读错位最高发的坑点。错误做法verilog// ❌ 错误忽略WSTRB直接写整个64bitassign reg0 wdata[31:0]; // 忽略了WSTRBassign reg1 wdata[63:32];// 如果Master只想写reg0// wdata 64hXXXX_XXXX_1234_5678// wstrb 8h0F (只有低4字节有效)// 错误实现会把高32bit的垃圾数据也写入reg1正确做法核心逻辑verilog// ✅ 写根据WSTRB逐字节写入if (wstrb[0]) reg0[7:0] wdata[7:0];if (wstrb[1]) reg0[15:8] wdata[15:8];// ... 类似处理其他字节// ✅ 读用地址bit[2]区分64bit中的高低32bitassign rdata (araddr[2] 1b0) ? {regs[1], regs[0]} : {regs[3], regs[2]};关键点写操作WSTRB决定哪些字节有效无效字节不写入读操作没有RSTRB用地址选择返回数据地址对齐64bit接口地址必须是8字节对齐推荐做法32bit外设直接用32bit AXI接口避免窄传输痛苦点四突发传输中间出错数据残缺怎么办问题描述你用AXI4-Full读取256次突发数据读到一半RRESP返回了SLVERRverilog// 读突发过程中// Beat 0-127: RRESP OKAY// Beat 128: RRESP SLVERR ← 错误// Beat 129-255: 还要继续吗根本原因AXI4协议规定突发传输一旦开始必须完成所有Beats即使中间有错误。场景规则读突发出错Slave必须在剩余Beats返回RDATA值不确定RRESPSLVERR或DECERR写突发出错Slave可以立即返回BRESPSLVERR但必须接受完所有W数据Master处理检查RRESP/RESP如果出错丢弃整个突发数据错误做法verilog// ❌ 错误1读到错误后立即停止always (posedge aclk) beginif (rvalid rready) beginif (rresp ! 2b00) begin// ❌ 错误直接停止接收state S_ERROR;end.// 后果Slave还在发数据Master不接收协议违反// ❌ 错误2忽略RRESP假设数据正确assign data_valid rvalid rready;// ❌ 没有检查rresp错误数据被当成有效数据正确做法核心流程verilog// ✅ 继续接收所有beats但标记错误丢弃本次突发所有数据error_flag (rresp ! 2b00) ? 1b1 : error_flag;// 数据有效标志只在无错误时拉高data_valid rvalid rready !error_flag;// 突发结束后保持error_flag供上层重试突发错误处理规则规则说明必须完成突发即使中间出错也要接收完所有Beats检查RRESP每个Beat都要检查标记错误丢弃错误数据如果突发中有错误整个突发数据无效重试机制出错后可以重发AR请求需要上层协议支持⚠️ 重要注意事项注意事项一AXI4和AXI3的突发长度不同协议最大突发长度AXI316次AxLEN0~15AXI4256次AxLEN0~255如果你的代码要兼容AXI3必须把突发拆成多个16次的小突发。注意事项二突发传输的地址对齐要求突发模式地址对齐要求FIXED无要求INCR起始地址必须按AxSIZE字节对齐否则Master报DECERR很多DMA地址错位根源WRAP必须对齐到WRAP边界突发长度×传输大小INCR地址对齐AXI协议强制要求INCR/WRAP起始地址必须按AxSIZE对应字节对齐否则Master直接返回DECERR。注意事项三ARSIZE/AWSIZE的含义AxSIZE值每次传输字节数0001 byte0012 bytes0104 bytes0118 bytes10016 bytes10132 bytes11064 bytes111128 bytes重要AxSIZE ≠ 数据位宽AxSIZE表示每次传输的字节数实际数据位宽由WDATA/RDATA决定。同一AXI接口可通过AxSIZE配置单拍1/2/4/8Byte窄传输这是窄传输的核心来源。常见搭配32bit接口 → AxSIZE0104 bytes64bit接口 → AxSIZE0118 bytes128bit接口 → AxSIZE10016 bytes注意事项四Cache属性ARCACHE/AWCACHECache值含义典型场景0000Device Non-bufferable外设寄存器0011Normal Non-cacheable普通内存1011Write-Back, Read-AllocateDDR内存0111Write-Through需要一致性的内存建议访问DDR用1011或0011访问外设寄存器用0000。注意事项五调试突发传输用ILA抓完整序列verilog// ✅ ILA配置抓取完整突发序列ila_burst u_ila (.clk(aclk),.probe0(arvalid),.probe1(arready),.probe2(araddr),.probe3(arlen),.probe4(arburst),.probe5(rvalid),.probe6(rready),.probe7(rdata),.probe8(rresp),.probe9(rlast),.probe10(beat_cnt) // 内部计数器);// 触发条件arvalid上升沿抓取整个突发的完整波形常见问题 FAQQ1突发传输中途可以取消吗不能。AXI4协议规定突发一旦开始必须完成。如果必须取消Master只能设置超时忽略后续数据上层协议重发请求。Q2如何知道一次突发传输了多少数据用arlen1计算。突发长度 arlen 1。更可靠的方法是自己维护计数器每个rvalidrready时记录Beat数。Q3多个突发可以同时发出吗可以AXI4支持乱序。Master可以连续发出多个AR请求Slave可以按任意顺序返回R数据用RID标识。如果设计不支持乱序可以等上一个突发完成再发下一个或用AXI Interconnect的reorder_depth0禁用乱序。Q4FIXED突发模式什么场景用FIFO读写地址固定数据流式传输、外设寄存器轮询每次读同一地址、DMA到固定地址。FIXED模式下地址始终等于起始地址不递增。Q5突发传输的性能优势有多大对比项单次传输16次突发256次突发地址开销每次都有AR1次AR1次AR效率~50%~90%~98%适用场景零散访问小块数据大块DMA建议超过16次传输就用突发模式。Q6为什么我的突发传输实际速度远低于理论值原因检查方法突发长度太短检查arlen是否充分利用WSTRB导致窄传输检查wstrb是否全1Interconnect仲裁延迟检查是否有其他Master抢占Slave响应慢检查rready/wready延迟总结痛苦点根因解法突发长度算错AxLEN实际次数-1统一用arlen beats - 1WRAP传输出错边界计算错误/地址不对齐理解WRAP边界 突发长度 × 传输大小窄传输字节错位WSTRB没处理根据WSTRB逐字节写入突发中途出错数据残缺/协议违反继续完成突发丢弃错误数据AXI4-Full的精髓在于突发——算对长度、理解WRAP、处理窄传输、正确应对错误。关注我AXI协议实战专题持续更新。FPGA定制开发、项目调试、IP定制开发服务可私。