AXI 4K 边界:突发为什么不能跨 4KB、谁来拆、谁来罚
更新时间:2026-09-28。本文是「集成电路大类 · 芯片设计」接口主题簇里的一篇长尾文。AXI4 完整协议 和 AXI4 事务全生命周期 讲了 burst 的五通道握手与拍序推进,但把一条协议红线留了下来:任何一笔 burst 的地址范围不允许跨过 4KB 边界。这条写在 AMBA AXI 规约(ARM IHI 0022)A3.4.1 节里的规则,看着像一句轻描淡写的限制,实则是 master 侧 DMA 配置、互连侧地址译码、验证侧用例设计三方都必须吃透的硬约束。
本文要回答的问题
- 4KB 这个数字从哪来,为什么不是 2KB、不是 64KB?
- 一笔 burst 跨了 4KB 边界,硬件层面到底会发生什么?
- 跨 4KB 的访问该由谁负责拆开:master 自己,还是互连代劳?
- 怎么从
AxADDR、AxLEN、AxSIZE反推出一笔 burst 会不会越界? - 验证环境里怎么构造 4K 边界的定向用例与断言?
一、规则的来源:页表粒度和译码窗口
AXI 规定一笔突发传输(burst transaction)不能跨越 4KB 地址边界,直接原因是地址译码窗口的对齐粒度。典型的 AXI slave 在互连地址映射表里拿到的窗口是 4KB 的整数倍,译码器通常只比较高 20 位地址(ADDR[31:12])来决定选中哪个 slave。如果一笔 burst 从 0x0000_0FF0 开始、INCR16、每拍 4 字节,那么第 16 拍的地址就落在 0x0000_1000——跨进了下一个 4KB 页,可能属于另一个 slave,甚至是一片未映射的空洞。slave 端只接收首地址和控制信号,后续拍的地址是它自己按 AxLEN/AxSIZE 递增算出来的;一旦算进别人的窗口,数据就会写错地方,或者干脆没人应。
更深层的原因是虚拟内存:操作系统页表的最小粒度就是 4KB,相邻两个 4KB 物理页在虚拟地址上未必连续,在物理地址上也未必属于同一个设备。如果允许 burst 跨页,那么 IOMMU/SMMU 就必须在 burst 中途插入一次页表翻译,这对纯握手的 AXI 通道来说是不可接受的。所以规约干脆把 4KB 定为所有实现的共同天花板——即使你的系统页大小是 16KB 或 64KB,AXI 侧仍按 4KB 守规矩。
二、判定公式:一笔 burst 会不会越界
给定首地址 AxADDR、拍数 AxLEN+1、每拍字节数 2^AxSIZE,越界判定一句话:
burst 末地址 = AxADDR + (AxLEN+1) × 2^AxSIZE - 1
是否越界 = (AxADDR[31:12] != 末地址[31:12])等价写法是先算「本页剩余字节数」:page_remaining = 4096 - AxADDR[11:0],再比较 burst_bytes = (AxLEN+1) × 2^AxSIZE,只要 burst_bytes > page_remaining 就越界。注意 AxADDR[11:0] 只取低 12 位——页内偏移,这是 4KB 规则在 RTL 里只比较 12 位的原因。
举三个具体例子,都是验证记分板里要逐拍核对的场景。例一:AxADDR=0xFF0、AxLEN=3、AxSIZE=2(4 拍 × 4 字节 = 16 字节),末地址 0xFFF,同页,合法。例二:AxADDR=0xFF0、AxLEN=15、AxSIZE=2(64 字节),末地址 0x102F,跨页,非法。例三:AxADDR=0xF80、AxLEN=15、AxSIZE=3(128 字节),末地址 0xFFF,刚好压线到页尾,合法——「贴边」是定向用例的常客。
上面这张图里,合法 burst 把最后一拍顶到页尾 0x1FFF,一拍不多一拍不少;非法 burst 在第 5 拍就越过了 0x2000 这条线。正文里说「跨进下一个 4KB 页」指的就是后者——末地址的高 20 位变了。
三、违反之后会发生什么
规约把跨 4KB 定义为协议违规(protocol violation),但 AXI 通道上没有「违规中断」这种东西,后果完全取决于下游实现,工程上常见的有三种。
第一种是 slave 直接回 SLVERR 或 DECERR。做得严谨的互连或 slave 会在首拍采样时算一遍末地址,发现跨页就用错误响应终止事务。这是最好的结局——错误显式、可定位,配合 AXI RRESP/BRESP 解码 能迅速收敛。
第二种是数据被静默写到错误地址。很多手写 slave 不做边界检查,地址递增逻辑就是简单的 addr + beat_size,越过 4KB 后继续往内部 RAM 的下一个偏移写。如果这个 slave 的窗口只有 4KB,高地址位被截断,数据就回卷到了窗口开头的寄存器或存储区——典型症状是设备配置被莫名改写、驱动读到乱码,定位极其痛苦,因为波形上看一切握手都正常。
第三种是互连译码错乱甚至挂死。burst 越过 4KB 后,若高 20 位落进另一个 slave 的窗口,而互连的译码只在首拍做一次,那么后续数据拍会被送往错误的下游,或者因为目标 slave 的 outstanding 配额不匹配造成握手死锁。这类问题在 AXI 错误响应与总线超时 里有配套的排查手段。
四、谁来拆:master 的主责,互连的有限补位
责任划分上,规约把 4K 合规明确放在 master 一侧:master 发出 burst 之前必须自己保证不越界。DMA 控制器的 RTL 通常这样实现——在描述符取到「起始地址 + 总长」后,先算到下一个 4K 边界的剩余字节数,把传输切成若干段,每段一个独立 burst,段长不超过 min(剩余传输, 页内剩余, 最大 burst 字节数)。CPU 侧的访存则天然安全:单拍访问不会跨 4KB,cache 行填充用的 WRAP burst 长度 16/32/64 字节且按行对齐,也碰不到边界。
互连(interconnect)是否代劳拆包,实现定义,不能假设。ARM 的 NIC/CMN 系列里,带数据宽度转换或 AXI3 降级逻辑的部件可能顺手做 burst 拆分,但大多数直通型 crossbar 不做。把「互连会帮我拆」当设计前提,是芯片回片后 DMA 越界写坏寄存器的经典来源。唯一可靠的口径是查互连的数据手册:支持拆分的会明确写出「splits bursts crossing 4KB」,不写的默认不拆。互连体系的一般架构见 AXI Crossbar 互连。
还有一个容易漏的角落:窄传输和非对齐传输会改变「每拍字节数」的直觉。AxSIZE 小于总线位宽时,burst 总字节数按 AxSIZE 算而不是按总线位宽算;非对齐首地址下首拍实际有效字节更少,但越界判定用的是地址范围而不是有效字节数——两条规则各算各的,详见 AXI4 窄传输与非对齐。WRAP burst 的回卷边界是 burst 自身块长,与 4K 边界是两件事,见 AXI4 WRAP 与 Cache。
这张图就是 master 侧 DMA 拆包的状态机骨架:每发出一段就回到「算页内剩余」重新判定,直到描述符发完。RTL 实现里它通常就是一个比较器加一组地址累加器,成本极低,但漏掉它的代价是整个 burst 越界。
五、验证侧怎么覆盖 4K 边界
定向用例至少覆盖四类:贴边合法(末地址恰为 0xFFF)、跨 1 字节越界(最小非法)、跨整页越界(多页穿越,检验 master 拆包循环)、以及非对齐首地址下的边界组合。随机用例里把 AxADDR[11:0] 的高位段(0xF00 以上)加大权重,让边界场景自然高频出现。
断言(SVA)侧有两条性价比最高。一条放在 master 接口上:AxVALID && AxREADY 采样时检查 AxADDR[31:12] == (AxADDR + burst_bytes - 1)[31:12],违例直接 $error——这是单向的 master 守规矩检查。另一条放在 slave/互连侧:监测 burst 进行中内部递增地址的高 20 位是否变化,变了就报协议违规,这条能在没有错误响应的「静默写错」场景下兜底。配合 AXI4 burst 长度计算 里的拍数公式,这两条断言加起来不过十几行,却能在回归里挡住绝大多数 4K 类 bug。
这一篇在知识体系里的位置
协议全貌见 AXI4 完整协议 与 AXI4 事务全生命周期;burst 拍数与字节数的换算见 AXI4 LEN/SIZE 计算;越界后错误响应的语义见 AXI RRESP/BRESP 解码 与 AXI 错误响应与总线超时;相邻但不同的地址规则见 AXI4 窄传输与非对齐 和 AXI4 WRAP 与 Cache。
总结
AXI 4K 边界规则源于地址译码窗口和 4KB 页表粒度:一笔 burst 的地址范围(AxADDR 到 AxADDR + (AxLEN+1)×2^AxSIZE - 1)高 20 位必须相同,越界后果轻则 SLVERR、重则静默写错地址或互连挂死;合规责任在 master,DMA 要按「页内剩余」切段循环发 burst,互连是否代拆必须查手册不能假设;验证侧用贴边/越界/非对齐定向用例加两条高 20 位不变性断言即可低成本守住这条红线。