---
title: 时序逻辑电路
url: https://doc.liz6.com/hardware/05-digital-circuits/03-sequential-logic-circuits
locale: zh
area: hardware
tags:
- hardware
- 数字电路
date: 2026-06-30
modified: 2026-07-11
description: 时序逻辑电路 什么是时序逻辑 时序逻辑 — 输出不仅取决于当前输入，还取决于历史状态。 时序逻辑核心结构:组合逻辑 + 反馈存储 = 有记忆的电路 输入 组合逻辑 输出 ↓ 状态更新 反馈(读状态) ↑ 存储元件 受时钟 CLK 控制采样 核心特征:时钟信号(Clock)+ 状态保持 —— 有反馈、有时钟,输出才不仅取…
---

# 时序逻辑电路

## 什么是时序逻辑

**时序逻辑** — 输出不仅取决于当前输入，还取决于**历史状态**。

<svg viewBox="0 0 720 300" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="时序逻辑核心结构:组合逻辑与反馈存储构成有记忆的电路">
  <defs>
    <marker id="seqfb1" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker>
  </defs>
  <rect width="720" height="300" fill="#ffffff"/>
  <text x="360" y="28" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">时序逻辑核心结构:组合逻辑 + 反馈存储 = 有记忆的电路</text>

  <text x="55" y="97" font-size="13" fill="#475569">输入</text>
  <line x1="85" y1="92" x2="138" y2="92" stroke="#475569" stroke-width="1.7" marker-end="url(#seqfb1)"/>
  <rect x="140" y="70" width="170" height="44" rx="8" fill="#4f46e5"/>
  <text x="225" y="97" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">组合逻辑</text>
  <line x1="310" y1="92" x2="358" y2="92" stroke="#475569" stroke-width="1.7" marker-end="url(#seqfb1)"/>
  <text x="366" y="97" font-size="13" fill="#475569">输出</text>

  <line x1="270" y1="114" x2="270" y2="160" stroke="#475569" stroke-width="1.6" marker-end="url(#seqfb1)"/>
  <text x="280" y="142" font-size="11" fill="#64748b">↓ 状态更新</text>
  <line x1="180" y1="162" x2="180" y2="116" stroke="#475569" stroke-width="1.6" marker-end="url(#seqfb1)"/>
  <text x="120" y="142" font-size="11" fill="#64748b" text-anchor="end">反馈(读状态) ↑</text>

  <rect x="140" y="162" width="170" height="44" rx="8" fill="#0d9488"/>
  <text x="225" y="189" text-anchor="middle" font-size="13" font-weight="700" fill="#ffffff">存储元件</text>
  <text x="225" y="222" text-anchor="middle" font-size="11" fill="#0f766e">受时钟 CLK 控制采样</text>

  <rect x="60" y="238" width="600" height="50" rx="7" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="76" y="260" font-size="12.5" fill="#3730a3">核心特征:时钟信号(Clock)+ 状态保持</text>
  <text x="76" y="280" font-size="12.5" fill="#3730a3">—— 有反馈、有时钟,输出才不仅取决于当前输入,还取决于历史状态。</text>
</svg>

核心特征: **时钟信号 (Clock)** + **状态保持**

---

## 锁存器与触发器

### SR 锁存器 (基本存储单元)
```
NOR 实现:
    ┌───┐
S ──┤   ├── Q
    │NOR│
    │   ├──┐
    └───┘  │
    ┌───┐  │
R ──┤   ├──┘── Q̄
    │NOR│
    └───┘

S=1,R=0 → Set   (Q=1)
R=1,S=0 → Reset (Q=0)
S=0,R=0 → Hold  (保持)
S=1,R=1 → 禁止! (Q=Q̄=0, 且解除后不确定)
```

### D 锁存器 (电平触发)
```
电平触发: CLK=1 期间跟随 D, CLK=0 锁存

D ────┬── Q
      │
CLK ──┘

问题: CLK=1 期间 D 变化 → Q 跟着变 (透明)
     在反馈回路中可能导致振荡
```

### D 触发器 (边沿触发) — 数字电路主力
```
符号:
    ┌───┐
D ──┤D  Q├── Q
CLK─┤>   │
    └───┘

仅在时钟上升沿 (↑) 采样 D, 其余时间 Q 不变

关键时序参数:
  tsu (setup): D 在 CLK 沿之前必须稳定的最短时间
  th  (hold):  D 在 CLK 沿之后必须保持的最短时间
  tcq (clk→q): CLK 沿到 Q 更新的延迟

违反 tsu/th → 亚稳态 (metastability) → Q 振荡或不确定!
```

### 其他触发器
```
JK 触发器:
  J=1,K=0 → Q=1  (Set)
  J=0,K=1 → Q=0  (Reset)
  J=1,K=1 → Q翻转 (Toggle)
  J=0,K=0 → Hold

T 触发器 (Toggle):
  T=1 → 每个时钟沿翻转一次
  T=0 → 保持

级联 T 触发器 = 计数器
```

---

## 寄存器 (Register)

```
n 个 D 触发器共用同一时钟 = n 位寄存器

    ┌───┐
D0 ─┤D  Q├── Q0
    │>  │
    └───┘
    ┌───┐
D1 ─┤D  Q├── Q1
    │>  │
    └───┘
    ...   ← 共 n 个
    ↑
   CLK

每个时钟上升沿，所有 D 被采样 → Q 更新
这是 CPU 中寄存器、流水线寄存器的基本原理
```

---

## 计数器 (Counter)

### 异步 (行波) 计数器
```
Q0 → CLK1 → Q1 → CLK2 → Q2 ...
前级 Q 输出直接驱动后级 CLK

简单但慢 (级联延迟累加) + 中间态有毛刺
```

### 同步计数器
```
所有触发器共用同一时钟

任意计数序列 (上/下/可逆)
典型: 74HC161 (4位同步), 74HC193 (可逆)
```

### 常用计数
```
二进制: 0→1→2→...→2ⁿ-1→0
十进制: 0→1→...→9→0  (BCD码)
格雷码: 每次只变1位 (防竞争)
  BCD:     000→001→010→011→100...
  Gray:    000→001→011→010→110...
  每次只翻转1位 → 适合跨时钟域传输
```

---

## 状态机 (FSM)

### Moore 型
<svg viewBox="0 0 720 330" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="Moore 型状态机:输出仅取决于当前状态,状态切换在时钟沿发生">
  <defs>
    <marker id="moorefsm1" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker>
  </defs>
  <rect width="720" height="330" fill="#ffffff"/>
  <text x="360" y="28" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">Moore 型状态机:输出仅取决于当前状态</text>

  <rect x="280" y="62" width="160" height="66" rx="10" fill="#e0e7ff" stroke="#4f46e5"/>
  <text x="360" y="90" text-anchor="middle" font-size="13" font-weight="700" fill="#3730a3">S0</text>
  <text x="360" y="112" text-anchor="middle" font-size="11" fill="#4f46e5">out = A</text>

  <line x1="360" y1="128" x2="360" y2="182" stroke="#475569" stroke-width="1.7" marker-end="url(#moorefsm1)"/>
  <text x="372" y="158" font-size="11" fill="#64748b">条件满足(时钟沿切换)</text>

  <rect x="280" y="184" width="160" height="66" rx="10" fill="#ccfbf1" stroke="#0d9488"/>
  <text x="360" y="212" text-anchor="middle" font-size="13" font-weight="700" fill="#115e59">S1</text>
  <text x="360" y="234" text-anchor="middle" font-size="11" fill="#0f766e">out = B</text>

  <rect x="60" y="270" width="600" height="50" rx="7" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="76" y="292" font-size="12.5" fill="#3730a3">输出仅取决于当前状态,状态切换只发生在时钟沿</text>
  <text x="76" y="312" font-size="12.5" fill="#3730a3">—— 输出变化只跟着时钟走,没有 glitch(毛刺)。</text>
</svg>

### Mealy 型
<svg viewBox="0 0 720 240" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="Mealy 型状态机:输出取决于当前状态与输入,输入一变输出立刻响应">
  <defs>
    <marker id="mealyfsm1" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker>
  </defs>
  <rect width="720" height="240" fill="#ffffff"/>
  <text x="360" y="28" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">Mealy 型状态机:输出取决于当前状态 + 输入</text>

  <rect x="250" y="70" width="170" height="64" rx="10" fill="#e0e7ff" stroke="#4f46e5"/>
  <text x="335" y="98" text-anchor="middle" font-size="13" font-weight="700" fill="#3730a3">S0</text>
  <text x="335" y="118" text-anchor="middle" font-size="11" fill="#4f46e5">当前状态</text>

  <line x1="420" y1="102" x2="470" y2="102" stroke="#475569" stroke-width="1.7" marker-end="url(#mealyfsm1)"/>
  <text x="478" y="98" font-size="12" font-weight="700" fill="#9a3412">输入 = 1 时输出 = 1</text>
  <text x="478" y="116" font-size="11" fill="#c2410c">(即刻响应,不等时钟沿)</text>

  <rect x="60" y="160" width="600" height="50" rx="7" fill="#eef2ff" stroke="#c7d2fe"/>
  <text x="76" y="182" font-size="12.5" fill="#3730a3">输出 = 当前状态 + 当前输入,输入一变输出立刻跟着变</text>
  <text x="76" y="202" font-size="12.5" fill="#3730a3">—— 可能发生在任意时刻,有 glitch 风险;但状态数通常比 Moore 少。</text>
</svg>

### FSM 实现
```
1. 状态编码 (二进制/独热码/Gray)
2. 当前状态 → 寄存器
3. 下一状态 → 组合逻辑 (状态 + 输入 → 下一状态)
4. 输出逻辑 → Moore/Mealy

独热码: N个状态=N位, 仅1位为1
  优点: 输出/下一状态逻辑简单
  缺点: 触发器多
```

---

## 时序分析

### 建立/保持时间
```
     tsu  th
     ├──┤├┤
D ───┘    └────────────
         ↑
CLK ─────┘    ─────────

tsu: 时钟沿前 D 必须稳定的时间
th:  时钟沿后 D 必须保持的时间

违规 → 亚稳态!
```

### 最大频率
```
fmax = 1 / (tcq + tcomb(max) + tsu)

tcq:    触发器 CLK→Q 延迟
tcomb:  组合逻辑最大延迟 (关键路径)
tsu:    下一级触发器建立时间

提高 fmax:
- 减少组合逻辑级数
- 插入流水线寄存器 (把长路径切成多段)
```

### 亚稳态 (Metastability)
```
当 D 在 tsu/th 窗口内变化时:
  Q 可能进入中间电平 → 振荡 → 最终稳定在 0 或 1

平均无故障时间 (MTBF):
  MTBF ∝ e^(t_wait/τ) / (f_clk × f_data)

解决: 两级同步器 (打两拍)
  async_in → [DFF] → [DFF] → sync_out
             ↑CLK      ↑CLK
  
  第一级可能亚稳态，第二级几乎总是稳定了
```

---

## 时钟域交叉 (CDC)

```
跨时钟域传输信号的黄金法则:

1. 单 bit 信号: 两级同步器 (双触发器)
2. 多 bit 总线: 用异步 FIFO 或握手协议
   不要直接同步多 bit! (各 bit 可能在不同周期捕获)
3. 慢→快: 信号保持至少 2 个快时钟周期
4. 快→慢: 信号必须保持足够长时间被慢时钟采样
```

---
*关键词: 触发器, DFF, 建立时间, 保持时间, 亚稳态, 状态机, Moore, Mealy, CDC, 同步器*
