AHB HSIZE 与拍地址:8/16/32 位传输的每拍 HADDR 计算、对齐与字节车道
更新时间:2026-09-25。本文是「集成电路大类 · 芯片设计」接口主题簇里的一篇长尾文。AHB-Lite 流水线、HREADY 与错误响应 建立了地址相位/数据相位错一拍的模型,但没有展开一个写 RTL 和验证用例时绕不开的细节:每个数据拍(beat)的
HADDR到底由什么决定。答案就是HSIZE——它同时编码了拍宽度、地址步进和对齐边界。
本文要回答的问题
HSIZE[2:0]各个编码代表多宽的传输,一拍搬几个字节?- burst 的后续 SEQ 拍,
HADDR按什么规则递增,WRAP 何时回卷? - 地址为什么要对齐,半字/字传输的低位地址有什么硬约束?
- 32 位总线上做 8 位传输,数据落在哪个字节车道,谁来选?
- slave 拉低
HREADY插等待时,拍地址和拍序号怎么变?
一、HSIZE:一拍传几个字节
AHB 把一次数据相位称为一个 beat(拍),HSIZE[2:0] 就是拍宽度编码,取值为传输字节数的对数,即拍宽 = 2^HSIZE 字节:
| HSIZE | 拍宽 | 字节数 | HADDR 步进 | 对齐要求 |
|---|---|---|---|---|
| 000 | 8 位 | 1 | +1 | 无 |
| 001 | 16 位 | 2 | +2 | HADDR[0]=0 |
| 010 | 32 位 | 4 | +4 | HADDR[1:0]=00 |
| 011 | 64 位 | 8 | +8 | HADDR[2:0]=000 |
| 100 | 128 位 | 16 | +16 | HADDR[3:0]=0000 |
| 101 | 256 位 | 32 | +32 | HADDR[4:0]=00000 |
| 110 | 512 位 | 64 | +64 | 低 6 位为 0 |
| 111 | 1024 位 | 128 | +128 | 低 7 位为 0 |
三条推论要先记住:第一,HSIZE 是逐拍有效的控制信号,随地址相位发出,但对同一笔 burst 规约要求各拍保持一致,不能第一拍 32 位、第二拍变 8 位;第二,HSIZE 不得超过接口数据位宽,32 位总线上发 HSIZE=011(64 位)属于非法组合;第三,HSIZE 描述的是拍宽,不是 burst 总长度——后者由 HBURST(SINGLE/INCR/WRAP4/8/16)决定,整笔突发搬的字节数等于拍数乘以拍宽,比如 INCR8 配 16 位拍一共 16 字节。
还有一个实现细节决定了 slave 的 RTL 写法:控制信号全部在地址相位采样,slave 必须先把 HSIZE、HADDR、HWRITE 寄存一拍,等数据相位到来时再用寄存值选车道、读写存储。32 位总线上做字节写时,slave 内部 RAM 的写使能通常拆成四个独立的字节使能,由寄存后的地址低位组合产生。如果组合逻辑误用数据相位当拍的地址,遇到流水线连续访问就会拿 B 的地址去配 A 的数据,这类错位在单拍 SINGLE 测试里看不出来,只有连续 burst 才暴露。
二、每拍 HADDR 怎么算:NONSEQ、SEQ 与回卷
主机发一笔 burst 时,第一拍 HTRANS=NONSEQ,HADDR 是起始地址;后续拍 HTRANS=SEQ,地址按 HSIZE 线性步进:
HADDR(n+1) = HADDR(n) + 2^HSIZE以最常见的 32 位 INCR4 为例,起始地址 0x1000:四拍地址依次是 0x1000 → 0x1004 → 0x1008 → 0x100C。同样四拍换成 8 位传输则是 0x1000、0x1001、0x1002、0x1003——步进量完全由 HSIZE 决定,这就是「拍地址」最核心的算法。
WRAP 突发多一条回卷规则:地址在跨越「拍数 × 拍宽」的块边界时回到块首。块首地址由起始地址按块大小向下取整。例如 WRAP4、32 位拍(块长 16 字节),起始 0x1004:四拍为 0x1004 → 0x1008 → 0x100C → 0x1000,最后一拍回卷。cache 行填充用 WRAP 可以先取关键字、再补齐整行,因此拍地址序列在验证时必须逐拍比对,不能只查首末地址。
HTRANS=BUSY 是唯一不改拍地址的「插入拍」:主机在 burst 中途需要停顿时插入 BUSY,该拍地址总线上驱动的其实是下一 SEQ 拍的地址,但 slave 不把它当作一次有效传输,数据搬移和拍序号都不前进。也就是说 BUSY 之后第一个 SEQ 拍的地址与 BUSY 拍总线上的地址相同。INCR 不定长突发没有固定拍数,靠主机用 IDLE 或下一笔 NONSEQ 结束,因此拍地址序列只能边收边算,这也是记分板对 INCR 要按收到的 SEQ 逐个入队的原因。
三、对齐要求与非对齐的边界
经典 AHB/AHB-Lite 要求传输地址与拍宽对齐:16 位传输 HADDR[0] 必须为 0,32 位传输 HADDR[1:0] 必须为 00,规律是「低于拍宽的地址位全部为 0」。这一要求和步进规则互为表里——只要首拍对齐、后续按 2^HSIZE 步进,整个序列自然对齐。
规约不要求 slave 检查对齐错误:主机若发出错位地址,译码和字节车道逻辑仍会照地址动作,结果通常是数据落到错误车道或被拆成奇怪的访问,而且没有任何 HRESP=ERROR 提示。因此对齐约束主要靠主机设计和验证用例保证,定向用例应显式覆盖错位地址的行为约定。
一个需要知道的版本差异:AHB5 为 INCR 类突发定义了非对齐传输语义,允许主机发出非对齐首地址、由下游完成等价的对齐访问与车道拼装,思路类似 AXI 的非对齐支持;但大量存量 AHB-Lite slave 和 AHB/APB 桥只认对齐访问,是否支持必须逐组件查手册,不能假设。
四、窄传输与字节车道:拍宽小于总线位宽
HSIZE 小于数据总线位宽时就是窄传输:32 位总线上发 8 位或 16 位拍。AHB 没有 AXI 那样的显式 WSTRB 字节使能,字节车道由地址低位和 HSIZE 隐式决定,slave 自行译码。32 位总线上的映射为:
| HSIZE | HADDR[1:0] | 使用的字节车道(HWDATA/HRDATA) |
|---|---|---|
| 8 位 | 00 / 01 / 10 / 11 | lane0 [7:0] / lane1 [15:8] / lane2 [23:16] / lane3 [31:24] |
| 16 位 | HADDR[1]=0 / =1 | lane0-1 [15:0] / lane2-3 [31:24] |
| 32 位 | 任意(须 00) | 全部 4 个车道 [31:0] |
64 位总线同理,用 HADDR[2:0] 在 8 个车道里选起始车道,连续占用 2^HSIZE 个。读窄传输时主机只取对应车道、忽略其余;写窄传输时未选中的车道必须被 slave 忽略,对应字节保持原值。这一区别在 RTL 上经常表现为 bug:写使能直接按整拍放行,结果字节写误伤了相邻字节。验证窄传输要逐个车道、逐类宽度做「写后读回」检查。车道编号与大小端无关:车道 0 永远是数据总线最低 8 位、对应地址最低字节,大端模式只改变「逻辑字节序」的解释,不改变物理车道与地址的对应关系,跨大小端系统对接时不要在这里找原因。
工程上还常见一条隐性约定:很多 32 位 slave(尤其是手写的 SRAM/寄存器接口)只实现 8/16/32 三种 HSIZE,对更宽编码直接按 ERROR 响应或忽略。把第三方 slave 挂到 64 位矩阵上时,要在集成清单里确认其支持的拍宽集合,以及当主机发出更宽拍时互连是否负责拆分——AHB 互连不像 AXI 那样有标准化的数据宽度转换器,拆分行为完全实现定义。
五、HREADY 插等待时,拍地址保持不变
slave 跟不上时序时拉低 HREADY,当前数据相位插入等待态。由于 AHB 地址相位与上一笔数据相位共享同一拍,HREADY=0 同时把地址相位延长:主机必须保持 HADDR、HSIZE、HTRANS、HWRITE 和 HWDATA 不变,整个拍序列被「冻结」,不产生新的拍序号,也不允许在等待期间把地址改成下一 SEQ 拍的值。
对验证的含义是:等待态不改变拍地址序列,只改变每个拍出现的时刻。记分板建模拍序列时应按「地址 + 宽度」排队、以 HREADY=1 作为拍完成的弹出条件,而不是按周期数计数。总线矩阵和多层互连场景里还要注意,HREADY 是各 slave 响应经译码回 MUX 后的结果,未选中的 slave 不应参与,详见 AHB-Lite 总线矩阵。错误响应的两拍时序与 HREADY 的配合见 HREADY 流水线。
这一篇在知识体系里的位置
协议全貌见 AMBA 入门 与 AHB-Lite 流水线、HREADY 与错误响应;地址如何被译码到各 slave 见 地址译码与地址重映射;多拍原子访问见 AHB Locked 锁定传输;跨桥到 APB 的拍宽与时序转换见 AHB/APB 与桥接;对比显式字节使能与非对齐模型可参考 AXI4 完整协议。
总结
HSIZE[2:0] 以 2^HSIZE 编码每个 beat 的字节数,同时决定 SEQ 拍 HADDR 的步进量与地址对齐边界,WRAP 突发在块边界回卷;拍宽小于总线位宽即窄传输,AHB 无 WSTRB,字节车道由地址低位隐式选择,slave 必须忽略未选中车道;slave 拉低 HREADY 只冻结拍的时刻、不改变拍地址序列,经典 AHB 要求地址对齐、AHB5 才为 INCR 定义非对齐语义,是否支持必须逐组件确认。