鲁棒状态机:掉进不存在的状态怎么自己爬出来
更新时间:2026-09-12。本文是「集成电路大类 · 芯片设计」**进阶层(intermediate)**数字逻辑第四十五篇。FSM 三段式教的是正常转移,但 N 个状态的编码空间总有空缺。这一篇专讲「如果状态机掉进未定义状态怎么办」——这在车规、功能安全和长稳运行里不是小概率。
本文要回答的问题
- 为什么二进制/one-hot 编码总有「不存在的状态」?什么会把 FSM 打进去?
- 我明明写了 default,为什么综合后可能还是回不来?
- 独热码怎么用「有效位计数」检测非法态?奇偶保护又怎么做?
- 除了未用状态,等待态死锁、输出未定义还能怎么防?
- 「安全实现(safe implementation)」综合属性到底加了什么硬件?
一、空缺从哪来,怎么掉进去
n 个触发器有 2ⁿ 个编码,而状态数通常远少于它:4 状态用二进制 2 位恰好占满,5 状态 3 位就空 3 个;one-hot 的 16 状态用 16 位,合法的只有「恰一个 1」那 16 种,其余 6 万多种全是非法态。掉进去的途径:
- 上电未复位或复位不完整:触发器初值是随机/X;
- 单粒子翻转(SEU):粒子打中状态寄存器,某一位翻转(ECC 保护的是存储,FSM 状态位常裸奔);
- 组合毛刺/时序违例在跨异步输入时把状态机打偏;
- 复位释放不一致(见 RDC)。
一旦进入无转移定义的状态,若硬件「保持」,FSM 就永久死机。
二、为什么写了 default 还可能没用
两个常见坑:①综合器为了面积/时序,可能假设未用状态不可达而把 default 逻辑优化掉(don't-care 处理);②default: 里只写了 next_state 没给所有输出赋值,或状态机不是规范两段/三段式,导致回到 IDLE 的同时输出残留。要让恢复逻辑真实存在,需要:
- default 显式指回安全态,且在 default 里给全所有输出,不依赖「未列出就保持」;
- 用综合属性明确要求保留恢复逻辑(不同工具叫法不同,如
syn_encoding="safe"/safe implementation state machine/fsm_safe_state),工具会插入「未用状态 → 复位态」的硬件而不是当 don't-care 删掉; - 规范的两段/三段式 FSM:状态寄存器、次态组合、输出分开,避免输出在异常态残留。
always_comb begin
next = S_IDLE; // 默认安全态(不写 next=state!)
out_valid = 1'b0; // 默认输出先给安全值
unique case (state)
S_IDLE: if (start) next = S_WORK;
S_WORK: begin out_valid=1; if (done) next = S_DONE; else next=S_WORK; end
S_DONE: next = S_IDLE;
default: next = S_IDLE; // 任何非法态都回家
endcase
end注意默认次态写成 S_IDLE 而不是 state:这样即使在未定义编码,下一周期也被拉回,而不是原地卡死(正常态因 case 全覆盖仍正确转移)。
三、独热非法态检测与状态位保护
one-hot 下合法态要求「恰一个位为 1」,可以显式算 ones = |(state & (state-1)) ... 即统计 1 的个数,若 ones != 1 则判定非法、强制回家或报错。代价是多一点组合逻辑,高速时可周期检查而不是每拍检查。
更强的防护针对 SEU:
- 状态奇偶位:给状态寄存器配一个奇偶位,每次状态跳转时按新状态更新;每拍检查「状态+奇偶」是否合法,不合法即检测到单 bit 翻转(只能检,配合复位回家);
- 复制/三模冗余(TMR):高可靠设计用三份状态寄存器多数表决,单份翻转被多数掩盖(航天/车规);
- 把状态位放进带 ECC 的存储,或用 LEC/形式验证证明「任意状态在有限步内可达安全态」(可达性/活性质检)。
四、不止未用状态:死锁、完备性与确定性
鲁棒性还包括正常逻辑层面:
- 等待态加超时:在
S_WAIT等外部握手时配看门狗计数器,超时强制回 IDLE/错误态,避免从机不响应永久死锁(valid/ready 尤其要防); - 输出在每个状态都有定义,包括 default,避免异常态输出 X 传播;
- 跨异步输入先稳定化:FSM 输入若来自别的时钟域,先同步/握手,防止一次跳变被不同状态位看到不同值;
- 确定性:同一状态+同一输入必须唯一决定次态,避免竞争;复位后所有 FSM 都在已知态(配合 RDC 的同步释放)。
与现有篇目的衔接
总结
一句话总结:任何编码都有未用状态(二进制有空码、one-hot 有大量非独热编码),上电 X、SEU、毛刺或复位释放不一致都可能把 FSM 打进去并永久卡死;只写 default 不一定够,因为综合器可能把不可达状态当 don't-care 删掉恢复逻辑,正确做法是默认次态指向安全态(而非保持 state)、default 给全所有输出、用 safe implementation 属性强制保留恢复硬件,并采用状态寄存器/次态/输出分离的规范结构;one-hot 可统计有效位个数检测非法态,更高可靠用状态奇偶位、TMR 多数表决或 ECC 纠正单 bit 翻转,形式验证可证明任意状态有限步内可回到安全态;鲁棒性还要给等待态配超时看门狗、保证所有状态输出有定义、跨异步输入先同步、转移确定唯一并在复位后处于已知态——这套要求在车规/功能安全与长稳设备里是签核项而非加分项。