Wishbone STALL 突发:反压时序、CTI/BTE 编码与突发结束速查
更新时间:2026-09-25。本文是「集成电路大类 · 芯片设计」序列里的一篇长尾协议实操文。Wishbone 总线 B4 给出了 STB/CYC/ACK/STALL 的信号定义,但读突发波形时最常被问的三件事——「STALL 拉高这拍到底算不算数」「CTI/BTE 两组编码各管什么」「突发在哪一拍算结束」——答案分别落在 STALL 的保持规则、CTI 与 BTE 的字段组合上。本文把反压时序和编码速查一次讲透,并给出可直接照查的两张表。握手的基本思想对照 valid/ready 握手。
本文要回答的问题
- STALL 拉高时主机哪些信号必须保持,这一拍请求算不算被从机接收?
- CTI 三个 bit 的四种有效编码是什么,end-of-burst 怎么标?
- BTE 的线性/4 拍/8 拍/16 拍回卷怎么编码,回卷边界怎么一眼看出?
- CTI/BTE 哪些组合非法,记分板做突发检查时最容易踩哪些坑?
一、STALL:流水线反压的保持规则
先明确适用范围:STALL 是 Pipelined 周期的反压信号。Classic 周期里请求与 ACK 强绑定,从机没准备好就延后 ACK、插入等待态,主机把 STB/ADR/WE/DAT_W 原样保持即可,不依赖 STALL;只有在流水线突发中,主机连续发地址流、多笔在途时,才需要 STALL 来踩刹车。
Pipelined 周期下的规则只有一条核心句:STALL=1 且 STB=1 的拍,从机不接收该请求,主机必须把全部请求信号保持不动;直到 STALL=0 的那个上升沿,请求才被接收。 需要保持的信号包括 ADR、DAT_W、SEL、WE、CTI、BTE 和 STB 本身,少保持任何一个都可能让从机采到「半个新请求」。这与 valid/ready 中 ready 拉低时 valid 及其载荷必须稳定的纪律完全一致。
一个关键时序点:STALL 管的是「不要发新请求」,ACK 管的是「早先在途的某笔完成了」,两者可以同拍出现。从机在 STALL=1 期间仍然可以对之前已经接收的请求返回 ACK 和读数据,主机必须照常接收——不能因为自己被反压就忽略 ACK。因此 monitor 要维护两个独立计数:已接收未完成的在途笔数,以及当前被 STALL 挡住的请求位置,混在一个计数器里必然在「STALL 与 ACK 重叠拍」上算错。
二、CTI:周期类型标识
CTI(Cycle Type Identifier)是 3 bit 信号,每个请求拍随 STB 一起给出,标识当前总线周期的形态。B4 定义了四种有效编码,其余组合保留:
CTI 编码速查表
| CTI | 名称 | 含义 | BTE 是否有效 |
|---|---|---|---|
| 000 | Classic | 经典周期:单笔传输,或 Classic 等待态 | 否 |
| 001 | Constant Address | 常量地址突发:每拍访问同一地址(FIFO 读写典型) | 否 |
| 010 | Incrementing Burst | 递增突发:地址按 BTE 规则推进或回卷 | 是 |
| 011–110 | Reserved | 保留编码,遇到视为非法 | — |
| 111 | End-of-Burst | 突发最后一拍 | 与上一拍相同 |
几个看波形时的细节。第一,CTI=000 不是「突发第一拍」,它就是 Classic 周期本身;单笔传输从头到尾 CTI=000,不需要再发一次 111。第二,CTI=111 是最后一拍的属性,不是突发结束后单独补的一拍:主机在突发最后一个传输拍把 CTI 从 001/010 切成 111,该拍 ACK 后突发即完成,下一拍主机可以撤掉 STB/CYC,也可以保持 CYC、重新置 CTI 开一笔新突发。第三,111 拍的地址必须符合突发自身的推进规律——它是突发的一员,不是额外节拍。
三、BTE:线性与回卷突发
BTE(Burst Type Extension)是 2 bit 信号,只在 CTI=010(递增突发)时决定地址如何推进;CTI=000/001 时 BTE 应置 00 且其值被从机忽略。
BTE 编码速查表
| BTE | 突发类型 | 地址行为 | 回卷对齐粒度 |
|---|---|---|---|
| 00 | Linear | 地址持续递增,不回卷 | 无 |
| 01 | 4-beat wrap | 每 4 拍回卷一次 | 4 × 传输粒度 |
| 10 | 8-beat wrap | 每 8 拍回卷一次 | 8 × 传输粒度 |
| 11 | 16-beat wrap | 每 16 拍回卷一次 | 16 × 传输粒度 |
传输粒度(granule)由接口的 SEL 宽度约定:32 位总线满带宽传输时每拍推进 4 字节,因此 BTE=01 的回卷窗口是 4×4=16 字节,地址低 4 位在窗内编号;BTE=10 窗口 32 字节看低 5 位;BTE=11 窗口 64 字节看低 6 位。看波形速判的方法与 AXI WRAP 一致:推进时只有窗口低位做加法、到窗顶归零,高位不变。例如 32 位总线、BTE=01、起始地址 0x0C,四拍地址为 0x0C、0x00、0x04、0x08,第一拍后立刻回卷到窗口起点,但四拍覆盖的仍是同一个 16 字节窗口。AXI 侧的同类边界推演见 AXI4 burst 类型与边界。
一个容易忽略的点:B4 不强制突发长度恰好等于回卷拍数。BTE=01 表示「按 4 拍窗口的规则推进」,但突发实际长度仍由主机用 CTI=111 收尾决定——主机可以发一笔 6 拍的 4-beat-wrap 递增突发,地址在中途回卷一次、第 6 拍以 111 结束。从机的地址生成必须纯粹按 BTE 规则逐拍算,不能假设「回卷突发必然 4/8/16 拍整」。
四、非法组合与验证检查清单
字段层面有四类必查的非法或可疑组合。第一,CTI 出现 011–110 的保留编码。第二,CTI=000/001 时 BTE 非 00,或设计文档声明从机只支持线性突发却收到回卷编码。第三,把 CTI=111 当成独立的一拍计入突发长度——末拍本身是最后一个数据拍,数拍数时不要为 111 额外加一。第四,STALL 期间主机的任何请求信号发生跳变,或主机在 STALL=1 时自行撤掉 STB,这两种行为都会让从机的地址采样错位。
记分板侧建议这样组织:monitor 在 STB=1 且 STALL=0 的拍(且仅有这些拍)把请求压入在途队列,记录地址、CTI、BTE、WE、SEL;地址期望按拍推进函数生成,对 constant(地址不变)、linear(持续加)、wrap(窗内回卷)分别实现,每收到一个非 STALL 的新请求就推进一步,与 ACK 返回完全解耦。断言至少覆盖:STALL 拉高期间请求信号稳定;CTI=111 之后 STB 要么撤下要么开启新周期;回卷突发的地址在窗顶后正确归零;STALL 与 ACK 同拍时在途计数不乱。握手稳定性的通用断言写法见 valid/ready 握手。覆盖率上建议覆盖三种回卷窗口、回卷拍数不等于突发长度、起始地址在窗口中部、STALL 连续多拍且 ACK 穿插返回、以及 111 后紧接新突发。跨时钟域的突发反压必须经过异步 FIFO,不能直连,见 异步 FIFO CDC。
这一篇在知识体系里的位置
信号与时序总览见 Wishbone 总线 B4:Classic 与 Pipelined 周期;握手纪律对照 valid/ready 握手;流水线与默认从机思想对照 AHB-Lite 流水线;AXI 侧回卷边界见 AXI4 burst 类型与边界;跨时钟域见 异步 FIFO CDC;总线选型见 AMBA 总线选型。
总结
Wishbone STALL 突发只看三个信号:STALL=1 时主机保持 STB 与全部请求信号不动、请求不被接收,且 STALL 不妨碍 ACK 对在途传输的返回;CTI 三 bit 中 000 是 Classic、001 是常量地址、010 是递增突发、111 标最后一拍(011–110 保留);BTE 两 bit 只在 CTI=010 时生效,00 线性、01/10/11 分别为 4/8/16 拍回卷,窗口为 N 乘传输粒度、看地址低位即可速判;突发长度由 111 收尾决定、不必等于回卷拍数,STALL 期信号跳变、保留 CTI、为 111 多数一拍是三类必查错误。