9 Communicating State Machines
当一个问题太复杂,无法用单个有限状态机 (FSM) 表达时,我们可以将其拆分为多个更小、更简单的 FSM,这些 FSM 之间通过信号通信协同工作。这种方法称为 FSM 分解 (factoring FSMs)。
通信 FSM 的关键要点:
- 分解复杂问题:将一个复杂的状态机分解为多个简单的 FSM。
- 信号交互:一个 FSM 的输出作为另一个 FSM 的输入,两者通过信号进行通信。
- 模块化设计:提高设计的可读性、可维护性和可扩展性。
9.1 A Light Flasher Example
本例展示了如何使用两个 FSM 来实现一个 闪光灯控制器 的设计。
功能描述
闪光灯控制器的功能规格如下:
输入信号:
start
:触发闪光序列的信号(高电平持续一个时钟周期)。
输出信号:
light
:灯的状态(开/关)。
闪光序列逻辑:
当
start
信号为高时,开始闪光序列。闪烁 3 次
:
- 灯开 (on):保持 6 个时钟周期。
- 灯关 (off):保持 4 个时钟周期。
闪光序列完成后,
light
保持关闭状态,等待下一个start
信号。
直接实现的缺点
若直接使用单个 FSM 来实现该功能,可能需要多达 27 个状态:
- 1 个初始状态:等待输入
start
。 - 3 × 6 = 18 个状态:分别对应 3 次“灯开 (on)”阶段,每次 6 个时钟周期。
- 2 × 4 = 8 个状态:分别对应 3 次“灯关 (off)”阶段,每次 4 个时钟周期。
这种实现虽然可以满足功能要求,但状态数量过多,设计复杂,难以维护。
分解 FSM 的解决方案
为简化设计,我们将复杂的闪光灯 FSM 拆分为两个更小的 FSM:
- 主 FSM (Master FSM)
- 负责管理闪光灯的逻辑:启动序列、控制灯的开/关、计数闪烁次数等。
- 向 定时器 FSM 发送控制信号,如
timerLoad
和timerSelect
。 - 接收定时器 FSM 的状态信号
timerDone
。
- 定时器 FSM (Timer FSM)
- 负责实现定时功能:根据主 FSM 提供的计时值,生成定时完成信号
timerDone
。 - 计时完成后,将信号反馈给主 FSM,通知定时阶段结束。
- 负责实现定时功能:根据主 FSM 提供的计时值,生成定时完成信号
FSM 之间的信号通信
信号交互关系:
- 主 FSM → 定时器 FSM:
timerLoad
:触发定时器加载新计时值。timerSelect
:选择定时时间(6 或 4 个时钟周期)。
- 定时器 FSM → 主 FSM:
timerDone
:通知定时完成。
分解 FSM 的结构图
图 9.1 展示了主 FSM 和定时器 FSM 之间的交互:
- 主 FSM (Master FSM):
- 接收输入信号
start
。 - 控制输出信号
light
。 - 控制定时器 FSM 的加载和计时。
- 接收输入信号
- 定时器 FSM (Timer FSM):
- 接收主 FSM 的控制信号
timerLoad
和timerSelect
。 - 输出定时完成信号
timerDone
。
- 接收主 FSM 的控制信号
分解 FSM 的优势
- 模块化设计:
- 将复杂的 FSM 拆分为多个功能单一的子 FSM,每个 FSM 的功能明确且易于理解。
- 减少状态数量:
- 每个子 FSM 的状态数量大大减少,逻辑更简单,设计更清晰。
- 提高复用性:
- 定时器 FSM 可以复用于其他模块,实现定时功能。
- 易于调试和维护:
- 各子 FSM 独立实现,便于调试。
- 如果设计需要修改,只需调整某个子 FSM,而不影响整体结构。
总结
通过将一个复杂的闪光灯控制器 FSM 拆分为 主 FSM 和 定时器 FSM,我们实现了更简洁、模块化的设计:
- 主 FSM:负责控制灯的开关逻辑和闪烁次数。
- 定时器 FSM:负责定时,通知主 FSM 计时完成。
这种方法不仅减少了状态数量,还提高了设计的可维护性和复用性。在实际设计中,分解复杂 FSM 是一种常用的设计策略,尤其适用于大型系统和复杂时序逻辑。