跳转至

多周期 CPU(Multi-Cycle CPU)

参考:计算机系统Ⅰ - Lec08-2026 The Processor: Multi-cycle Design (Li Lu, Zhejiang University)


一、为什么需要多周期 CPU?

提升程序运行速度的三大方向

  1. 减少指令数量:CISC(一条指令做更多事)、更好的编译器
  2. 减少每条指令的周期数:RISC(更简单的指令)、多周期技术、并行
  3. 提高时钟频率:新制造工艺、重新设计关键路径、流水线

单周期 vs 多周期

单周期 (Single-Cycle) 多周期 (Multi-Cycle)
优点 设计简单 时钟周期更短;简单指令跑得更快;复用昂贵硬件
缺点 时钟周期受最长指令(lw)限制;需要两个 ALU 和两个存储器 有 sequencing overhead(多次付出)

关键区别: - 单周期:一个时钟周期完成一条指令 - 多周期:一个时钟周期完成一个阶段(stage) - 但设计步骤相同:datapath & controller


二、多周期 CPU 设计基本原则

  1. 将指令执行分为若干阶段,每个阶段周期尽量相同(实际很难完全相同,目标接近)
  2. 每个阶段占用一个时钟周期
  3. 每个时钟周期最多完成一次存储器访问、寄存器访问或 ALU 操作
  4. 前一个周期的执行结果需要存入特定的时序逻辑元件(临时寄存器)
  5. 时钟周期由最复杂的操作决定

三、多周期数据通路 (Datapath)

与单周期的硬件差异

  • 只有 1 个 Memory:指令和数据共用(冯·诺依曼架构可行)
  • 只有 1 个 ALU:不再需要额外的加法器
  • 增加了更多寄存器

新增临时寄存器==(关键!)==

instruction register 32位
register是64位的
寄存器 全称 作用
IR Instruction Register 保存从存储器取出的指令,供下一周期使用
MDR Memory Data Register 暂存从存储器读出的数据,直到下一周期
A 暂存 read register 1 的内容,直到下一周期
B 暂存 read register 2 的内容,直到下一周期
ALUout 暂存 ALU 的输出结果,直到下一周期

核心思想:这些临时寄存器在物理上将指令执行分隔为不同阶段!


四、指令执行的五个阶段

阶段 英文 操作
取指 IF (Instruction Fetch) 从存储器取指令;PC → 存储器地址;指令写入 IR;PC ← PC+4
译码/读寄存器 ID (Instruction Decode) 译码指令;乐观地读取寄存器;乐观地计算分支目标地址
执行 EX (Execute) 根据指令类型分叉:访存类 / R-type / 分支 / 跳转
访存 MEM (Memory Access) 仅 ld/sd 需要访问数据存储器
写回 WB (Write Back) R-type:ALU 结果写回 rd;I-type(lw):存储器数据写回 rd
修改 PC(分支) beq/j 等分支跳转指令修改 PC
  • 每条指令执行 3~5 个步骤:beq/j = 3 周期,R-type/sw = 4 周期,lw = 5 周期

五、各阶段详细数据通路

5.1 IF(取指)

  1. PC 内容作为地址送到存储器
  2. 从存储器读取指令
  3. 指令写入 IR(供下一周期使用)
  4. PC ← PC + 4

控制信号:IorD=0, ALUSrcA=0, ALUSrcB=01, ALUOp=00, PCSrc=00, IRWrite=1, PCWrite=1, MemRead=1

5.2 ID(译码 & 读寄存器)

  1. 译码指令
  2. 乐观读寄存器(不管是否需要,先读了再说)
  3. 乐观计算分支目标地址

为什么在 ID 阶段就算分支目标?—— "We have nothing better to do while we decode the instruction so we might as well."

控制信号:ALUSrcA=0, ALUSrcB=11, ALUOp=00(ALU 做 PC + 符号扩展偏移量 << 2)

5.3 EX(执行)—— 指令在此分叉

  • 访存类 (lw/sw):计算地址(base + offset)
  • R-type:ALU 执行运算(funct 字段决定具体操作)
  • 分支 (beq):ALU 做减法比较两寄存器
  • 跳转 (j):计算跳转目标地址

5.4 MEM(访存)

  • lw:从存储器读数据 → 存入 MDR
  • sw:将 B 寄存器的值写入存储器
  • R-type :Reg[IR[15-11]] = ALUout 让所有不需要时钟周期的指令更快的执行,所以放在mem而不是wb

5.5 WB(写回)

  • lw:MDR → 寄存器文件(rd),RegDst=0, MemtoReg=1 R-type:ALUout → 寄存器文件(rd),RegDst=1, MemtoReg=0

六、控制器设计 (Controller Design)

6.1 与单周期控制器的关键区别

单周期:每条指令的控制信号值==固定== 多周期:同一控制信号在==不同周期取值不同==

例:add x10, x12, x14(opcode=0110011, funct3=000, funct7=0000000, rd=01010, rs1=01100, rs2=01110)

信号 Cycle 1 (IF) Cycle 2 (ID) Cycle 3 (EX) Cycle 4 (WB)
PCWrite 1
IorD 0
MemRead 1
IRWrite 1
ALUSrcA 0 0 1
ALUSrcB 01 11 00
ALUOp 00 00 10
PCSrc 00
RegWrite 0 1
RegDst 1
MemtoReg 0

不能直接沿用单周期的控制器设计方法! 需要用 FSM

6.2 控制信号完整表

1-Bit 控制信号

信号 Deasserted (0) Asserted (1)
RegDst 目标寄存器号来自 rt 目标寄存器号来自 rd
RegWrite 无操作 写寄存器
ALUSrcA 第一操作数 = PC 第一操作数 = A 寄存器
MemRead 无操作 读存储器
MemWrite 无操作 写存储器
MemtoReg 寄存器输入来自 ALUout 寄存器输入来自 MDR
IorD PC 提供存储器地址 ALUout 提供存储器地址
IRWrite 无操作 存储器输出写入 IR
PCWrite 无操作 PC 被写入(源由 PCSource 控制)
PCWriteCond 无操作 若 ALU Zero=1,则 PC 被写入

2-Bit 控制信号

信号 效果
ALUOp 00 ALU 做加法
01 ALU 做减法
10 由 funct 字段决定 ALU 操作
ALUSrcB 00 第二操作数 = B 寄存器
01 第二操作数 = 4
10 第二操作数 = IR 低 16 位符号扩展 imm
11 第二操作数 = IR 低 16 位符号扩展后左移 2 位 imm
PCSrc 00 PC ← ALU 输出 (即 PC+4)
01 PC ← ALUout(分支目标地址)
10 PC ← {PC+4[31:28], IR[25:0]<<2}(跳转目标地址)

七、硬布线控制器 (Hardwired Controller)

  • 基于有限状态机 (FSM)
  • 通过 PLA 电路 + 状态寄存器实现
  • 通常用于 RISC

FSM 完整状态图

                              ┌─────────────────────────────┐
                              │  S0: IF (取指)               │
                              │  IorD=0, ALUSrcA=0,         │
                              │  ALUSrcB=01, ALUOp=00,      │
                              │  PCSrc=00, IRWrite, PCWrite │
                              └─────────────┬───────────────┘
                              ┌─────────────────────────────┐
                              │  S1: ID (译码)              │
                              │  ALUSrcA=0, ALUSrcB=11,     │
                              │  ALUOp=00                    │
                              └───┬───┬───┬───┬───┬────────┘
                                  │   │   │   │   │
              Op=lw/sw     Op=R-type  │  Op=beq  │  Op=j
                  │            │      │    │     │    │
                  ▼            ▼      ▼    ▼     ▼    ▼
    ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐
    │S2: MemAdr│  │S6: Execute│  │S9: AddiExe│  │S8: Branch│  │S11: Jump │
    │ALUSrcA=1 │  │ALUSrcA=1 │  │ALUSrcA=1 │  │ALUSrcA=1 │  │PCSrc=10  │
    │ALUSrcB=10│  │ALUSrcB=00│  │ALUSrcB=10│  │ALUSrcB=00│  │PCWrite   │
    │ALUOp=00  │  │ALUOp=10  │  │ALUOp=00  │  │ALUOp=01  │  └──────────┘
    └────┬─────┘  └────┬─────┘  └────┬─────┘  │PCSrc=01  │
         │             │             │         │Branch     │
    Op=lw│  Op=sw      │             │         └──────────┘
         ▼      ▼      ▼             ▼
    ┌──────────┐  ┌──────────┐  ┌──────────┐
    │S3:MemRead│  │S5:MemWr  │  │S7: ALUWb │  │S10:AddiWb│
    │IorD=1    │  │IorD=1    │  │RegDst=1  │  │RegDst=0  │
    └────┬─────┘  │MemWrite  │  │MemtoReg=0│  │MemtoReg=0│
         │        └──────────┘  │RegWrite  │  │RegWrite  │
         ▼                      └──────────┘  └──────────┘
    ┌──────────┐
    │S4:MemWb  │
    │RegDst=0  │
    │MemtoReg=1│
    │RegWrite  │
    └──────────┘

各指令类型经过的状态和周期数

指令 状态序列 周期数
lw S0 → S1 → S2 → S3 → S4 5
sw S0 → S1 → S2 → S5 4
R-type S0 → S1 → S6 → S7 4
beq S0 → S1 → S8 3
addi S0 → S1 → S9 → S10 4
j S0 → S1 → S11 3

实现方式

  • PLA (Programmable Logic Array) + 状态寄存器
  • 输入:Opcode + 当前状态
  • 输出:控制信号 + 下一状态
  • 时钟驱动状态转移

优点:控制信号生成时间短 缺点:ISA 复杂时难以更新和维护 → 不适合 CISC


八、微程序控制器 (Micro-program Controller)

8.1 为什么需要微程序控制器?

  • 硬布线控制器在 ISA 复杂(CISC)时难以更新和维护
  • 微程序控制器应运而生

8.2 历史

  • 1951 年由 M. V. Wilkes 提出
  • 1964 年 IBM 360 系列首次部署
  • 1970 年代以来随 VLSI 发展广泛应用
  • 目前大多数 CISC 计算机采用

8.3 基本原理

  • 每条指令用一段微程序表示
  • 微程序由若干微指令组成,每条微指令对应 FSM 中的一个状态
  • 所有微程序存储在 ROM 中,称为控制存储器 (Control Storage, CS)

8.4 概念层次

微程序 (Micro-program)
  └── 一条 ISA 指令对应一段微程序
      └── 微指令 (Micro-instruction / Control Word)
          └── 由多个微命令组成的 0/1 序列,对应 FSM 中一个状态
              └── 微命令 (Micro-command)
                  └── 控制部件向执行部件发出的控制命令
                      └── 微操作 (Micro-operation)
                          └── 与微命令一一对应,执行部件的具体操作

微命令 ↔ 控制信号,微操作 ↔ 数据通路中的操作 —— 类似于数据通路中的控制信号与操作的关系

8.5 实现架构

存储器 → IR ──→ 启动 & 分支地址生成器
                  μPC (微程序计数器)
                  控制存储器 (CS/ROM) ← 条件码
                  μIR (微指令寄存器)
                   /          \
         译码 → 微命令      分支控制 → μPC

8.6 两个核心问题

  1. 微指令格式和微命令编码 → 长微指令字,格式参考指令格式
  2. 下一条微指令地址的确定 → 类似程序计数器,或微指令中显式含下址字段

8.7 优缺点

优点 缺点
大幅降低控制器设计难度 执行时间比硬布线长
提升 ISA 和 CPU 设计的灵活性 效率较低

九、性能分析 (Performance)

9.1 各指令周期数

  • 3 周期:beq, j
  • 4 周期:R-type, sw
  • 5 周期:lw

9.2 CPI 计算(加权平均)

指令类型 占比 周期数
Load (lw) 25% 5
Store (sw) 10% 4
Branch (beq) 11% 3
Jump (j) 2% 3
R-type 52% 4

平均 CPI = (0.11 + 0.02) × 3 + (0.52 + 0.10) × 4 + 0.25 × 5 = 4.12

9.3 关键路径分析

典型延迟参数:

参数 符号 延迟 (ps)
寄存器 clock-to-Q t_pc-q 30
寄存器 setup t_setup 20
多路选择器 t_mux 25
ALU t_alu 200
寄存器读 t_reg 150
存储器读 t_mem 250

多周期的两条关键路径

  1. ALU 路径:Tc = t_pc-q + t_mux + t_alu + t_mux + t_setup = 30 + 25 + 200 + 25 + 20 = 300ps
  2. 存储器路径(主导!):Tc = t_pc-q + t_mux + t_mem + t_setup = 30 + 25 + 250 + 20 = 325ps

存储器读取主导了关键路径 → 时钟周期取 325ps

单周期关键路径(lw 指令): Tc_single = t_pc-q + t_mem + t_reg + t_mux + t_alu + t_mem + t_setup = 30 + 250 + 150 + 25 + 200 + 250 + 20 = 925ps

9.4 实际性能对比

对于 1000 亿条指令的程序:

单周期 多周期
CPI 1 4.12
时钟周期 925ps 325ps
执行时间 100×10⁹ × 1 × 925×10⁻¹² = 92.5s 100×10⁹ × 4.12 × 325×10⁻¹² = 133.9s

⚠️ 多周期反而更慢!CPI 增加倍数 (4.12×) > 时钟周期缩短倍数 (925/325 ≈ 2.85×)

9.5 为什么还要学多周期?

虽然绝对性能可能不如单周期,但多周期提供了全新的设计视角: - 更细粒度的时钟周期内执行 - 为流水线 (Pipelining) 奠定基础——这才是真正大幅提升性能的关键技术(System II 将详细讲解)


十、关键总结

  1. 核心思想:一条指令 → 多个阶段 → 每个阶段一个时钟周期
  2. 硬件复用:1 个 ALU、1 个 Memory(冯·诺依曼架构)
  3. 临时寄存器(IR / MDR / A / B / ALUout)在物理上分隔各阶段,是设计的精髓
  4. 控制器必须用 FSM:同一信号在不同周期取值不同,不能像单周期那样固定
  5. 硬布线控制器(FSM + PLA)→ RISC;微程序控制器(控制存储器 ROM)→ CISC
  6. 性能不一定更好:CPI 增幅超过时钟周期缩短 → 真正提升靠流水线