同步时序电路的分析与设计
更新时间:2026-09-10。本文是「芯片设计 · 进阶层」数字逻辑基础第十篇。上承入门 有限状态机入门,下接工程写法 状态机设计。
本文要回答的问题
- 给一张电路图,如何由时钟触发器和门推出驱动方程→状态方程→输出方程→状态表?
- 怎么判断两个状态等价并合并(状态化简/最小化)?蕴含表怎么用?
- 状态分配(编码)为什么影响组合逻辑面积?相邻分配的启发式是什么?
- 怎么保证自启动:所有未使用编码都有回到主循环的转移?
- 这套手工法和直接写 Verilog 三段式是什么关系,哪些思想必须保留?
一、同步时序机模型(Maley/Moore 的形式化)
任何时钟驱动的同步时序电路都能抽象成同一模型(即入门篇 FSM 三要素的方程化):一组共用时钟的状态寄存器保存现态 Q,两块纯组合逻辑分别根据"现态 + 输入 X"算出次态 Q⁺和输出 Z:
X ──────────────┐
│ ┌──────────────┐
Q ──→ [次态组合逻辑] →│ 状态寄存器 D │─→ Q ──→ [输出组合逻辑] → Z
↑ └──────────────┘ ↑
└──────────────── Q(反馈) ────────────────┘
所有寄存器共用同一个 clk三类方程完整刻画它:
- 驱动方程(激励方程):触发器输入端关于现态/输入的表达式,如
D₁ = …、D₀ = …; - 状态方程(次态方程):把驱动代入 D 触发器特性
Q⁺ = D,得每个状态位的次态Qᵢ⁺ = fᵢ(Q, X); - 输出方程:Moore 型
Z = g(Q);Mealy 型Z = g(Q, X)。
同步是关键前提:所有状态变化只发生在时钟沿,因此两次沿之间可以把电路当纯组合逻辑分析,无需考虑门内部时序(竞争冒险只影响过渡瞬间)。
二、分析流程:从电路读出它在做什么
给一张已搭好的电路图,按五步反推功能:
- 写驱动方程:由连到各触发器 D/T/JK 端的门,写出各输入关于现态 Q、外部输入 X 的表达式。
- 写状态方程:代入触发器特性方程(D 触发器就是
Q⁺=D),得到每个状态位的次态。 - 写输出方程:写出 Z 关于 Q(和 X)的组合表达式。
- 列状态转移表:对"每个现态 × 每种输入",由状态方程算次态、由输出方程算输出,逐格填全。
- 画状态图并判定功能:按转移表画出状态图,给状态起有意义的名字(IDLE/RUN…),用一句自然语言总结它实现了什么(如"模 6 可逆计数器""1101 序列检测器")。
这套"驱动→状态→输出→表→图"的流程,是调试陌生 RTL/网表、读懂别人控制器的基本方法——在工程上对应"从 RTL 反推出状态转移表/状态图来做 code review 和功能核对"。
三、设计流程:从功能描述到电路
正向设计是分析的逆过程,教科书给出七步:
- 建立原始状态图/状态表:从自然语言需求出发,先宁多勿漏地列出状态与转移(这一步最考验理解需求,见 FSM 入门 的建模四步)。
- 状态化简(最小化):合并"行为完全相同"的多余状态。
- 状态分配(状态编码):给每个状态分配二进制码。
- 选触发器类型(现代设计恒为 D 触发器)。
- 求驱动方程与输出方程:由编码后的状态表,用卡诺图分别对每个状态位的次态和每个输出求最简式。
- 自启动检查:检查未用编码的去向。
- 画电路图(今天这一步由综合器完成)。
前三步是智力含量最高、也是写 RTL 前真正该做的设计工作。
四、状态化简:等价状态与蕴含表
两个状态等价(可合并)的判据:对每一种输入组合,它们的①输出完全相同,且②次态相同或彼此等价(第二条是递归条件)。判据满足时,外部世界无法区分这两个状态,合并后状态机行为不变但状态更少、所需触发器和逻辑更少。
系统化的工具是蕴含表(implication table,三角表):
- 画一张只含下三角的表格,每对状态占一格;
- 先把"输出不同"的状态对直接打 × 排除(显然不等价);
- 其余格子里填入"要让它俩等价,还必须成立的次态等价条件"(如
需 S1≡S3 且 S2≡S0); - 自顶向下迭代:一旦某格依赖的条件被证明不成立(被打 ×),该格也打 ×;
- 反复传递直到不再变化,所有未被打 × 的状态对即等价,据此合并,得到最简状态集。
不完全指定状态机(存在无关/不可能出现的输入输出,即 don't care)用更宽松的"相容状态"概念处理。工程映射:原始需求里常有人为细分、实则处境相同的状态,review 时用"输出与次态是否可区分"一问就能合并冗余状态,简化后续所有逻辑与验证。
五、状态分配:编码如何影响面积
化简后要给状态编码。同一个状态机,不同编码导致次态/输出组合逻辑的繁简差异明显。经典相邻分配启发式:把"经常作为同一状态的次态、或在同一输入下并列出现、或输出相同"的状态分配成相邻码(只差 1 位),使卡诺图上 1 格相邻、圈更大,从而减少逻辑。但这只是启发式,最优状态分配是 NP 难问题。
工程现实与入门篇一致:
- 二进制/格雷编码:状态多、ASIC 上省触发器(格雷还利于低翻转和跨域计数,见 异步 FIFO 与 Gray 码);
- 独热 one-hot:每个状态一位,次态逻辑近乎"置位/复位条件的直连",组合最简、最快,FPGA 上因触发器富余几乎总是更优;
- 今天通常把编码选择交给综合器参数(
enum_encoding/fsm_encoding:one-hot/gray/binary/auto),但先做状态化简仍是人的职责——工具一般不自动合并你语义上重复的状态。
六、自启动检查:别让芯片跑飞到野状态
若状态数不是 2 的整数次幂,二进制编码后必然存在没用到的"无效/未用状态"(独热码也有多位同效的非法态)。设计完成后必须逐个检查每个未用状态在每种输入下的次态:它们应能在有限拍内进入有效状态环(能自启动 / self-starting),而不是互相转移形成独立死环——否则上电随机态、单粒子翻转或干扰一旦把机器带进野状态,就永久卡死。
RTL 对应做法非常直接,也是强制规范:
always @(*) begin
next = state; // 默认保持,避免意外
case (state)
IDLE: if (start) next = RUN;
RUN : if (done) next = IDLE;
default: next = IDLE; // 所有未用/非法编码 → 回安全态
endcase
enddefault 把所有未列编码导向 IDLE(见 组合与时序逻辑 的防 latch 规则),一举同时保证①不综合出锁存器、②可自启动。复位态也应明确设为某个有效状态(通常 IDLE)。
七、从手工方程到 RTL 三段式
手工法的第 5、7 步(卡诺图求方程、画门电路)今天由逻辑综合完成,但第 1–4、6 步的思想原样保留,并对应到推荐的 RTL 三段式(详见 状态机设计):
| 教科书步骤 | RTL 三段式对应 |
|---|---|
| 状态化简、状态分配(建模) | 写 localparam 状态定义前先合并等价状态 |
| 状态方程(次态组合逻辑) | 第一段:现态寄存器 state<=next(时序,<=);第二段:纯组合算 next(always @(*),=,带 default) |
| 输出方程 | 第三段:输出逻辑(关键输出用 Moore/寄存输出防毛刺) |
| 自启动检查 | default 指向 IDLE + 明确复位态 |
配合 可综合 RTL 编码规范,这套"建模 → 化简 → 编码 → 方程 → 自启动"的纪律,就是从课本时序机设计无缝过渡到工业 FSM 的桥梁。
与现有篇目的衔接
- 前置:有限状态机入门、锁存器与触发器、布尔代数与卡诺图
- 毛刺与输出:组合逻辑竞争与冒险
- 工程写法:状态机设计(一段/两段/三段式)、可综合 RTL 编码规范、valid/ready 握手
- 编码与跨域:异步 FIFO 与 Gray 码
总结
一句话总结:同步时序电路可统一抽象为"状态寄存器 + 次态组合逻辑 + 输出组合逻辑",由驱动方程、状态方程(D 触发器即 Q⁺=D)和输出方程完全刻画;分析已有电路按"驱动→状态→输出→状态转移表→状态图→功能"五步反推,正向设计则按"原始状态图→状态化简→状态分配→求方程→自启动检查→(综合)画电路"推进;状态化简用"输出相同且次态相同或等价"的递归判据、借助蕴含表迭代打叉找出所有等价状态对并合并,状态分配用相邻编码启发式减小次态逻辑(最优分配 NP 难,工程上二进制/格雷适合 ASIC 多状态、独热适合 FPGA,也可交给综合器,但语义上重复状态的合并是设计者的职责);必须逐个检查未用编码能在有限拍回到主环以保证自启动,RTL 里用组合次态逻辑的 default 把所有非法状态导向 IDLE,同时杜绝锁存器;手工求方程和画门虽已由综合器承担,但建模、化简、编码与自启动这些思想完整对应到工业界的 Verilog 三段式 FSM——这正是数电课本时序机设计法在今天 RTL 工程中的留存形态。