3. 高可靠性状态机:三模冗余(TMR)在状态机中的应用
做数字设计这么多年,我越来越觉得——状态机这东西,看着简单,出事往往最要命。尤其是在航天、医疗、汽车这些领域,一个状态跳错,可能就是灾难性的。
那怎么让状态机变得「摔不坏」?今天咱们聊聊三模冗余(TMR),还有状态机自检、恢复、非法状态处理这些硬核话题。
3.1 三模冗余(TMR)的基本原理
三模冗余,说白了就是「三个臭皮匠,顶个诸葛亮」。你把同一个状态机复制三份,让它们并行跑,最后用投票器取多数结果。
举个例子:
// 三个状态机实例
reg [STATE_WIDTH-1:0] state_fsm1, state_fsm2, state_fsm3;
wire [STATE_WIDTH-1:0] voted_state;
// 投票逻辑:取多数
assign voted_state = (state_fsm1 == state_fsm2) ? state_fsm1 :
(state_fsm1 == state_fsm3) ? state_fsm1 :
(state_fsm2 == state_fsm3) ? state_fsm2 :
state_fsm1; // 全不一致时默认选第一个
我在项目中遇到过一件事:一颗卫星控制芯片,单份状态机在辐射环境下偶尔会翻转。加了TMR之后,三份同时出错的概率几乎为零。嗯,代价就是面积大了三倍,但可靠性提升了一个数量级。
核心要点:TMR能容忍任意一个副本出错,但无法容忍两个副本同时出错。所以三个副本的物理布局要分开,避免单粒子效应同时打翻两个。
3.2 状态机自检与恢复机制
TMR不是万能的。你想想看,如果三个副本都因为同一个原因(比如时钟毛刺)同时出错,投票器也救不了你。这时候就需要自检和恢复机制。
我个人习惯的做法是:
- 周期性状态检查:每个状态机内部加一个「状态合法性检查器」,如果当前状态不在合法状态集合中,就触发复位。
- 看门狗定时器:每个状态机配一个看门狗,如果长时间没有状态跳转,就认为状态机「卡死」了,强制复位。
- 状态回滚:保存最近几个周期的状态快照,发现异常时回滚到上一个合法状态。
// 状态合法性检查示例
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
end else if (!is_valid_state(state)) begin
// 非法状态,强制回到IDLE
state <= IDLE;
error_flag <= 1'b1;
end else begin
state <= next_state;
end
end
function is_valid_state;
input [STATE_WIDTH-1:0] s;
case (s)
IDLE, S1, S2, S3, DONE: is_valid_state = 1'b1;
default: is_valid_state = 1'b0;
endcase
endfunction
我的经验:看门狗的超时时间要设得比最长的正常状态停留时间稍长一点。我曾经设得太短,结果状态机在等待外部数据时频繁被复位,查了两天才发现是看门狗在捣乱。
3.3 非法状态处理策略
非法状态,就是状态编码里那些没被使用的组合。比如你用了3位寄存器,定义了5个状态,那剩下的3个编码就是非法状态。
处理非法状态,常见策略有三种:
| 策略 | 做法 | 适用场景 |
|---|---|---|
| 复位到初始状态 | 检测到非法状态时,强制回到IDLE | 大多数通用场景 |
| 状态恢复 | 根据非法状态的值,尝试映射到最近的合法状态 | 对连续性要求高的场景 |
| 触发中断/报警 | 记录错误并通知上层系统 | 安全关键系统 |
我个人最推荐的是「复位+报警」的组合。为什么呢?因为非法状态的出现往往意味着硬件已经出了问题,强行恢复可能掩盖更大的隐患。
// 非法状态处理:复位+报警
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
fault_flag <= 1'b0;
end else begin
case (state)
IDLE, S1, S2, S3, DONE: begin
// 正常状态转移
state <= next_state;
fault_flag <= 1'b0;
end
default: begin
// 非法状态:复位并报警
state <= IDLE;
fault_flag <= 1'b1;
end
endcase
end
end
注意:非法状态处理一定要放在组合逻辑或时序逻辑的default分支里。我曾经见过有人只在case里写了合法状态,忘了default,结果综合工具把非法状态当成don't care,流片后状态机乱跳,查都查不出来。
3.4 知识体系总览
下面这张图,是我自己总结的高可靠性状态机设计框架。你可以把它当成一个检查清单:
这张图其实就说了三件事:顶层用TMR扛单点故障,中间层用自检和看门狗防系统性错误,底层用非法状态处理兜底。三层叠起来,状态机基本就「摔不坏」了。
一个小建议:如果你刚开始做高可靠性设计,别一上来就搞TMR。先把非法状态处理和看门狗做好,这两样成本低、见效快。等系统稳定了,再考虑加TMR提升冗余度。
好了,这一章的内容就到这里。记住一句话:状态机越简单越可靠,但有时候简单不够,还得「冗余」才行。