Skip to content

一条指令在CPU里的一生——模拟器使用指南

大纲定位

五(二)指令执行过程 · 五(三)数据通路的功能和基本结构

要求:能把一条指令在数据通路上的完整流转讲清楚——每一步用到哪个部件、数据从哪来到哪去。

这个模拟器解决什么问题

指令执行的五个阶段(IF→ID→EX→MEM→WB)和控制信号是这一章的骨架。数据通路图能看懂、控制信号表能列出,但两者合在一起时常常对不上——"这条指令到底走了哪些部件?哪一拍是哪个信号在起作用?"

这个模拟器让你跟着一条指令"走一遍" CPU,每一步都能看到哪些部件被点亮、哪些信号被激活。按顺序走完三个场景大约 15 分钟。

界面速览

位置控件作用
顶部认识 CPU / 跟着指令走 / 换条指令试试三个场景,建议按此顺序
场景三指令下拉框lw $t0,0($t1) 取数 / sw $t0,0($t1) 存数 / beq $t1,$t2,+4 分支
中部数据通路图场景一里灰色等你点;场景二三里随阶段逐个点亮
右侧信息面板当前部件/阶段的说明与激活的控制信号
底部◀ | ▶/⏸ | ▶上一步 | 播放暂停 | 下一步
底部速度下拉 |「重新播放」0.5x / 1x / 2x | 跑到末尾才出现

建议一律用单步 ▶,别连播。 这个模拟器的价值在于"停下来看当前这一拍激活了哪些信号",连播会把它变成一段看不清的动画。

教学模型说明

模拟器采用 MIPS 风格信号命名(ALUSrc/RegWrite/MemToReg)。另一种常见写法是单总线结构 + 微操作传送语句,信号名各不相同,见 单总线数据通路。模拟器负责建立"指令流经部件"的画面感,这个直觉在两套体系里是通用的。

加载可视化中...

场景一:认识 CPU

打开模拟器后默认进入这个场景。你看到的是一个简化的单周期数据通路图——所有部件灰色,等你点击。

你应该点击的七个部件

1. PC(程序计数器)

点击后弹出说明:"我记住下一条指令的地址。每执行一条,自动 +4。" PC 自增是硬件自动完成的,不需要控制信号。

2. 指令存储器(IM)

存放所有指令。PC 给地址,IM 返回对应的 32 位指令编码。

哈佛结构

指令存储器和数据存储器分开——这就是"哈佛结构"的思想。分开的好处是取指和访存可以同时进行(流水线需要这一点)。

3. 控制器

指挥官。根据 opcode(和 funct)生成所有控制信号。控制信号在译码阶段就全部确定,但各信号在不同阶段才起作用。

4. 寄存器堆

32 个寄存器($0$31),可同时读两个(rs、rt 端口)、写一个。$0 永远为 0。

5. ALU

做加减与或比较等运算。输出运算结果 + Zero 标志(结果为 0 时 Zero=1)。

6. 数据存储器(DM)

主存。lw 从这里读数据,sw 往这里写数据。R 型指令不用它。

7. MUX(多路选择器)

数据通路上有两个关键 MUX:

  • ALU 输入 MUX:ALUSrc 控制,=0 选寄存器,=1 选立即数
  • 写回 MUX:MemToReg 控制,=0 选 ALU 结果,=1 选内存值

右侧信息面板

始终显示当前指令的:

  • 汇编格式和二进制编码
  • 指令字段分解(op/rs/rt/rd/shamt/funct 或 op/rs/rt/imm)
  • 关键寄存器的当前值

场景二:跟着一条指令走

点击"跟着指令走"标签,进入核心场景。默认指令是 add $t0, $t1, $t2$t1=5, $t2=3)。

动画的五个阶段

每一步都可以暂停(⏸)、单步推进(▶)、回退(◀):

阶段 ① 取指(IF)

你能看到什么对应知识点
PC 高亮 → 地址流向指令存储器 → 指令编码取出取指过程
+4 加法器高亮 → PC 更新为 PC+4PC 自增

取指阶段的两件事

取指阶段做两件事:①取指令 ②PC+4。这两件事是硬件自动完成的,所有指令都一样,不需要控制信号参与。

阶段 ② 译码(ID)

你能看到什么对应知识点
指令编码拆成 6 个字段,每个字段不同颜色指令格式
opcode 送入控制器 → 控制信号逐个亮起(绿=1,红=0)控制信号生成
rs/rt 字段送入寄存器堆 → 读出 $t1=5, $t2=3寄存器读取

记忆要点

控制器在译码阶段就一次性生成所有控制信号。比如 RegWrite=1 虽然在 ID 就确定了,但它在 WB 阶段才真正控制寄存器堆写入。

阶段 ③ 执行(EX)

你能看到什么对应知识点
ALUSrc MUX 高亮 → ALUSrc=0 → 选寄存器值ALU 输入选择
两个操作数(5, 3)进入 ALU → 输出 ALU Result=8ALU 运算
Zero 信号输出(8≠0 → Zero=0)Zero 标志

易混

R 型指令 ALUSrc=0(两个输入都来自寄存器)。lw/sw 的 ALUSrc=1(第二个输入是立即数)。但 beq 虽然是 I 型,ALUSrc=0(做寄存器比较,不用立即数做 ALU 运算)。

阶段 ④ 访存(MEM)

你能看到什么对应知识点
数据存储器保持灰色 → MemRead=0, MemWrite=0add 不访存
ALU 结果直接穿过只有 lw/sw 用数据存储器

WARNING

add 不需要数据存储器,但阶段不能跳过——硬件是固定连线的,只是控制信号让数据存储器"什么都不做"。这个理解对后面学流水线非常重要。

阶段 ⑤ 写回(WB)

你能看到什么对应知识点
MemToReg MUX 高亮 → MemToReg=0 → 选 ALU 结果写回数据来源
结果 8 写回寄存器堆 → $t0 从 0 变为 8RegWrite=1

完成后出现绿色汇总面板,列出五个阶段的关键动作和信号。

场景三:换条指令试试

这是最有价值的场景。从下拉菜单选择不同指令,看它走的路径和 add 有什么不同。

三条可选指令

指令和 add 的关键差异
lw $t0, 0($t1)ALUSrc=1(用立即数算地址),MemRead=1(要访存),MemToReg=1(写回内存值)
sw $t0, 0($t1)MemWrite=1(写内存),RegWrite=0(没有写回阶段
beq $t1, $t2, +4ALU 做减法比较,Branch=1,Zero=1 时 PC 跳转,RegWrite=0(没有写回

对比表(核心差异)

右侧面板会自动展示和 add 的控制信号对比表。差异项高亮显示:

信号addlwswbeq
ALUSrc0110
MemRead0100
MemWrite0010
RegWrite1100
MemToReg01××
Branch0001
RegDst10××

记忆技巧

只需要记住 add 的控制信号(全部都是"默认值"),然后记住每种指令和 add 哪里不一样

  • lw:ALUSrc、MemRead、MemToReg 变 1,RegDst 变 0(写 rt 不是 rd)
  • sw:ALUSrc 变 1,MemWrite 变 1,RegWrite 变 0(不写回)
  • beq:Branch 变 1,RegWrite 变 0,ALU 做减法

推荐使用流程

第一轮:建立直觉(5 分钟)

  1. 认识 CPU:点击每个部件,搞清楚它的功能
  2. 跟着 add 指令走:0.5x 慢速看完五个阶段
  3. 展开每个阶段的说明,画面 + 文字对照理解

第二轮:对比差异(10 分钟)

  1. 切到"换条指令试试"
  2. 依次选 lw → sw → beq,看每条指令的数据通路
  3. 重点看右侧对比表:哪些信号不同?为什么不同?
  4. 自己试着默写四种指令的控制信号表,然后用模拟器验证

第三轮:自己复现(按需)

  1. 合上模拟器,凭记忆手画一遍数据通路,标出某条指令激活的部件
  2. 再打开模拟器逐阶段对照,看漏了哪一段
  3. 重点检查两处:控制信号是不是在 ID 段一次性生成的,以及不用的部件是"跳过"还是"空过"

概念去哪里学

本文只讲怎么用这个模拟器。它演示到的知识点都有专文:

真题练习