计算机组成原理查漏补缺

三种指令类型 (R, I, J)

MIPS 指令集的设计非常整齐,所有的指令都是 32位(bits) 长。但是,这 32 个格子怎么分配,取决于指令的类型。

(1) R-type (Register type, 寄存器型)

  • 用途:纯粹的数学运算。
  • 特点:所有的操作数都在寄存器里。
  • 例子add $t0, $t1, $t2 (把 t1 和 t2 里的数拿出来相加,结果存到 t0)。
  • 格局:因为它需要 3 个寄存器(2个源,1个目标),所以它的空间被切得很细,最后剩下了 6 位给 func

(2) I-type (Immediate type, 立即数型)

  • 用途:涉及常数运算,或者读写内存。
  • 特点:操作数里包含一个具体的数字(立即数)。
  • 例子
    • ori $t0, $t1, 100 (把 t1 和数字 100 做或运算)。
    • lw $t0, 4($t1) (去内存取数,地址是 t1 + 4)。
  • 格局:为了放那个数字(比如 100),它牺牲了 rdfunc 的位置,腾出了 16位 的空间来存这个数。

(3) J-type (Jump type, 跳转型)

  • 用途:程序跳转(就像代码里的 goto)。
  • 特点:跳得很远。
  • 例子j 1000 (直接跳到地址 1000 去执行)。
  • 格局:除了开头的 op,剩下的 26位 全用来存目标地址,保证能跳得足够远。
指令类型 全称 (中文名) 包含的常见指令 (加粗为你课件中的) 核心特征 指令格式结构 (32位)
R-Type Register Type (寄存器型) add (加法) sub (减法) and, or, slt, nor 纯运算。 操作数全在寄存器里,不做数据传输,不涉及立即数。 op(6) rs(5) rt(5) rd(5) shamt(5) func(6) (特点:op全为0,靠 func 区分)
I-Type Immediate Type (立即数型) ori (或立即数) lw (加载字) sw (存储字) beq (相等分支) addi, andi, bne 带常数/地址偏移。 计算或访存时,需要用到一个具体的数字(16位)。 op(6) rs(5) rt(5) immediate(16) (特点:最后16位是常数/地址)
J-Type Jump Type (跳转型) jump (无条件跳转) jal (跳转并链接) 长距离跑路。 不需要计算,直接跳到程序代码的另一个位置。 op(6) address(26) (特点:后面26位全是目标地址)

opfunc 是什么?

这两个是指令的身份证

  • op (Opcode, 操作码):指令的高 6 位 (31-26 bit)。
    • 作用:它决定了这到底是一条什么指令(大类)。
    • 比喻:就像身份证上的“省份”。控制器一看 op,就知道你是 lw 还是 sw 还是 beq
    • 特殊情况:对于所有的 R-type 指令,它们的 op 都是 000000。这就尴尬了,控制器光看 op 分不清你是加法还是减法。
  • func (Function code, 功能码):指令的低 6 位 (5-0 bit)。
    • 作用:专门用来区分 R-type 指令的具体操作。
    • 比喻:就像身份证上的“名字”。
    • 逻辑:当 op000000 时,控制器就会去查 func
      • func = 100000 -> 做加法 (add)
      • func = 100010 -> 做减法 (sub)
    • 注意:只有 R-type 有 func。I-type 和 J-type 的这最后 6 位已经被那个常数或者地址占用了,所以它们没有 func 字段。

image-20251212164727970

为什么对于所有的 R-type 指令,它们的 op 都是 000000

设计者回头看了一眼 R-type 指令的格式。他们发现了一个惊喜:

R-type 指令只需要存 3 个寄存器编号(rs, rt, rd)和 1 个移位量(shamt)。

  • op: 6位
  • rs: 5位
  • rt: 5位
  • rd: 5位
  • shamt: 5位
  • 总共使用:$6 + 5 + 5 + 5 + 5 = 26$ 位。

32 - 26 = 6 位!

R-type 指令的末尾,正好空出了 6位 没地方用。

天才的设计思路来了:

既然 R-type 指令末尾空着 6 位,那为什么不把 Opcode 统一设为 000000(意思是:这是一条运算指令),然后利用末尾这空闲的 6 位(也就是 func 字段)来具体区分是加法还是减法呢?

  • 这样一来,add, sub, and, or, slt 等几十条运算指令,在 Opcode 表里只占用 1 个位置(就是 000000)。
  • 这就把剩下的 63 个 Opcode 宝贵名额,留给了那些没有空闲位置的 I-type 和 J-type 指令(因为它们后面被立即数填满了,没有 func 字段可用)。

控制信号的含义都有哪些

这些信号就是控制器发出的“命令”,控制数据通路里的多路选择器 (Mux)使能开关 (Enable)

我们把它们分为三类来记:

第一类:选路信号(Mux Selectors)

这些信号决定数据走哪条路。你可以理解为火车轨道的道岔。如果是 0 走左边,1 走右边。

  1. RegDst (Register Destination)
    • 含义运算结果存到哪个寄存器编号里?
    • 背景
      • R-type 的目标寄存器编号在指令的第 15-11 位 (rd 字段)。
      • I-type (如 lw) 的目标寄存器编号在指令的第 20-16 位 (rt 字段)。
      • 1: 选 rd (R-type)。
      • 0: 选 rt (I-type)。
  2. ALUSrc (ALU Source)
    • 含义ALU 的第二个操作数来自哪里?
      • 0: 来自寄存器堆的读出数据(两个寄存器做运算,如 R-type)。
      • 1: 来自指令里的立即数(寄存器和数字做运算,如 ori, lw, sw)。
  3. MemtoReg (Memory to Register)
    • 含义写回寄存器的数据来源是谁?
      • 1: 来自内存的数据(只有 lw 指令是这样,把数据从仓库搬回寄存器)。
      • 0: 来自 ALU 的计算结果(绝大多数指令,如 add, ori)。

第二类:开关信号(Enables)

这些信号是安全锁。只有设为 1,才允许动作。

  1. RegWr (Register Write)
    • 含义允不允许修改寄存器的值?
      • 1: 允许写。像 add, lw, ori 这种需要保存结果的指令。
      • 0: 禁止写。像 sw (只是往内存存数),beq (只是比较),j (只是跳转),绝对不能改写寄存器里的数据。
  2. MemWr (Memory Write)
    • 含义允不允许修改内存的值?
      • 1: 允许写。只有 sw (Store Word) 指令是 1
      • 0: 禁止写。其他所有指令。

第三类:功能控制信号

  1. ExtOp (Extension Operation)
    • 含义16位的立即数怎么变成32位?
    • 背景:指令里的数字只有16位,但计算器是32位的。
      • 1 (Signed): 符号扩展。保持正负号不变(比如 -2 扩展后还是 -2)。用于 lw, sw, beq(算地址偏移量)。
      • 0 (Unsigned): 零扩展。高位直接补0。用于逻辑运算如 ori
  2. Branch
    • 含义这是一个条件分支指令吗?
    • :如果是 beq 指令,这个信号是 1。它会结合 ALU 的“零标志位”来决定要不要跳。
  3. Jump
    • 含义这是一个无条件跳转指令吗?
    • :如果是 j 指令,这个信号是 1。直接强行修改 PC 指针。
  4. ALUctr (ALU Control)
    • 含义ALU 到底做什么数学题?
    • :这是个多位信号(通常3位或4位)。
      • Add: 加法 (用于 add, lw, sw)
      • Sub: 减法 (用于 sub, beq 比较是否相等)
      • Or: 逻辑或 (用于 ori)

什么是控制器 (Controller)?

在 CPU 这个“大工厂”里,主要分两部分:

  1. 数据通路 (Datapath):这是干活的工人机器。包括寄存器(用来记账的小本子)、ALU(算盘/计算器)、内存(大仓库)。它们负责搬运数据、做加减法。
  2. 控制器 (Controller):这是工厂的指挥官

控制器的作用: 它不直接干活(不存数、不算数),它的任务是看懂指令,然后对着数据通路里的各种开关“发号施令”。

  • 输入:它看的是指令(Instruction)。比如指令说“把 A 和 B 加起来”,这串 0101 的机器码传给控制器。
  • 输出:控制器根据指令,把相应的控制信号线拉高(置1)或拉低(置0)。

一句话总结:控制器就是 CPU 的大脑,它通过查表(真值表)来告诉身体的各个部位(ALU、寄存器、内存)在当前这一刻该干什么。

什么是数据通路 (Datapath)?

它的任务:根据指挥官(控制器)的命令,把数据从仓库(寄存器/内存)里搬出来,送到加工车间(ALU)算一下,再搬回去。

核心组成

  1. 仓库:寄存器堆 (Registers)、数据存储器 (Data Memory)。
  2. 车间:算术逻辑单元 (ALU)、加法器 (Adder)。
  3. 交通枢纽:多路选择器 (Mux)、扩展器 (Ext)。

什么是单周期处理器 (Single-Cycle Processor)?

核心定义:CPI (Cycles Per Instruction) = 1。

通俗解释

  • 时钟信号“哒”(上升沿)一下,CPU 开始取指令。
  • 在时钟“哒”下一响之前,CPU 必须把这条指令的所有工作(取指、翻译、运算、读写内存、写回结果)全部做完。

单周期处理器包含哪些功能?

为了让程序能跑起来,处理器通常需要支持三大类功能(指令):

A. 算术逻辑运算 (R-Type)

  • 功能:做数学题。
  • 指令例子add (加), sub (减), and (与), or (或), slt (比较大小)。
  • 流程:读寄存器 -> ALU 算 -> 写回寄存器。

B. 数据传输/访存 (I-Type)

  • 功能:搬运数据。CPU 的寄存器太小,数据多了要放内存里。
  • 指令例子
    • lw (Load Word):从内存搬到寄存器。
    • sw (Store Word):从寄存器搬到内存。
  • 流程:算地址 -> 读/写内存 -> (如果是读)写回寄存器。

C. 条件分支与跳转 (Branch & Jump)

  • 功能:改变程序执行顺序(也就是改变 PC 的值)。
  • 指令例子
    • beq (Branch if Equal):如果两个数相等,就跳到某处去。
    • j (Jump):无条件直接飞到某处。
  • 流程:比较 -> 计算新地址 -> 修改 PC。

单周期处理器包含哪些组成部分?

我们可以把它分为“肉体”(数据通路)和“灵魂”(控制单元)两大部分。

第一部分:数据通路 (Datapath) —— “干活的”

这部分你之前的实验已经做了一大半了,现在需要补全:

  1. 取指单元 (Instruction Fetch) —— 这是新面孔
    • PC (Program Counter):一个 32 位的寄存器,存着“现在执行到哪一行代码了”。
    • 指令存储器 (Instruction Memory):存放你写的机器码的大仓库。
    • 加法器 (+4):让 PC 自动加 4,指向下一条指令。
  2. 寄存器堆 (Register File)
    • CPU 的“口袋”,这里有 32 个格子 ($0 - $31),用来存放临时数据。
  3. 算术逻辑单元 (ALU)
    • CPU 的“计算器”,负责算加减法、逻辑运算。
  4. 数据存储器 (Data Memory)
    • CPU 的“大仓库”,用来做 lwsw
  5. 扩展单元 (Extender)
    • 把 16 位的立即数变成 32 位。
  6. 多路选择器 (Mux) —— 交通警察
    • 关键组件!比如 ALUSrc 这个 Mux,决定了 ALU 的输入是来自寄存器还是立即数。

第二部分:控制单元 (Control Unit) —— “发号施令的”

在你上一个实验里,“你”就是控制器(手动在波形里设 0 或 1)。现在要写一个模块来替代你。

  1. 主控制器 (Main Control)
    • 输入:指令的高 6 位 (Opcode)。
    • 输出:所有的控制信号 (RegDst, ALUSrc, MemWr 等)。
    • 作用:看到 lw 指令,它就自动把 MemtoReg 拉高,把 RegWr 拉高。
  2. ALU 控制器 (ALU Control)
    • 输入:主控制器的信号 + 指令的低 6 位 (Funct)。
    • 输出:给 ALU 的 ALUctr (3位或4位)。
    • 作用:专门告诉 ALU 该做加法还是减法。

MIPS是什么

1. 一种经典的 CPU 架构 (MIPS Architecture)

全称是 Microprocessor without Interlocked Pipeline Stages(无互锁流水线阶段微处理器)。

  • 这是什么: 它是一种基于 RISC(精简指令集计算机)原则设计的 CPU 架构。
  • 地位与影响: MIPS 是计算机体系结构教科书中的“标准模版”(著名的《计算机组成与设计》一书就主要使用 MIPS 教学)。它的设计非常简洁、优雅,对后来的 CPU 设计(包括 ARM 和 RISC-V)产生了深远影响。
  • 应用场景:
    • 曾经的辉煌: 索尼 PlayStation (PS1, PS2)、任天堂 N64 等游戏机都使用 MIPS 处理器。
    • 现在的应用: 依然广泛用于路由器(如部分 TP-Link, Ubiquiti 设备)、嵌入式设备和部分龙芯处理器(早期的龙芯基于 MIPS 指令集)。
  • 现状: 虽然曾经辉煌,但在移动端被 ARM 击败,在开源领域受到 RISC-V 的强烈冲击。MIPS 公司后来宣布将架构开源,随后又经历了多次收购和转型,目前已不再开发新的 MIPS 架构,转投 RISC-V 阵营。

2. 一种性能指标 (Million Instructions Per Second)

全称是 Million Instructions Per Second(每秒百万条指令)。

  • 这是什么: 它是衡量计算机 CPU 运算速度的一个老式指标。

  • 计算公式:

  • 缺点: 这个指标在现代对比中往往被认为不准确,因此有时候被戏称为 “Meaningless Indication of Processor Speed“(处理器速度的无意义指标)。

    • 原因: 不同的 CPU 执行一条指令所做的事情不同。例如,CISC(如 Intel x86)的一条复杂指令可能相当于 RISC(如 ARM)的 5 条简单指令。仅仅比较“每秒执行多少条指令”并不能真实反映两台不同架构电脑的快慢。

ISA是什么

ISAInstruction Set Architecture(指令集架构)的缩写。

它是计算机体系结构中最重要的抽象层,可以理解为软件(程序员/编译器)和硬件(CPU)之间的“合同”或“接口”

1. 核心概念:它是什么?

想象一下驾驶汽车:

  • ISA 就像是驾驶舱的设计标准: 它规定了“方向盘是用来转弯的”、“右边的踏板是油门”、“仪表盘显示速度”。只要懂这个标准,你就能开福特,也能开丰田。
  • 硬件(微架构)就像是引擎的设计: 它是 V6 还是 V8 引擎,是燃油还是电动,这属于内部实现。

在计算机中:

  • 软件(操作系统、编译器)只看 ISA,它只需知道“发送 ADD 指令能做加法”,不需要知道 CPU 内部是有几亿个晶体管怎么连线的。
  • 硬件(CPU 设计师)必须实现 ISA 规定的所有功能,至于怎么实现(用多少级流水线、多大的缓存),那是硬件的事。

2. ISA 规定了什么? (CPU 的“词汇表”)

ISA 定义了程序员在汇编层面能看到的所有东西:

  1. 指令集 (Instructions): CPU 能干什么?(如:加法、减法、从内存读取数据、跳转)。
  2. 数据类型 (Data Types): 它是怎么理解 0 和 1 的?(如:这是个 32 位整数,还是个 64 位浮点数?)。
  3. 寄存器 (Registers): 程序员能直接控制哪些“临时存储格”?(比如 MIPS 里的 $t0 - $t9,x86 里的 RAX, RBX)。
  4. 寻址模式 (Addressing Modes): 怎么找到内存里的数据?(是直接给地址,还是通过寄存器加偏移量?)。
  5. 内存管理与异常处理: 程序崩溃了怎么办?如何和操作系统配合?

MIPS 指令集架构 (ISA)

MIPS 指令集架构 (ISA) 是计算机体系结构中最经典的“教科书级”设计。它基于 RISC(精简指令集计算机)理念,主打简洁、高效和规整。

以下是 MIPS 指令集的核心要素拆解:

核心设计理念

  • 固定长度: 所有的指令都是 32位(4字节)长。这使得 CPU 解码非常容易。
  • Load/Store 架构: 只有 load(读取)和 store(写入)指令可以访问内存。其他的算术逻辑运算(如加法、减法)必须在寄存器之间进行。
  • 三操作数格式: 大多数运算指令需要三个操作数(例如:add a, b, c 意思是 a = b + c),非常直观。

Register Transfer Language(寄存器传输语言)

Register Transfer Language (RTL),有时在教科书中也称为 RTN (Register Transfer Notation),是一种用于描述计算机内部微操作 (Micro-operations) 的符号系统。

如果说汇编语言是给程序员看的,那么 RTL 就是给计算机架构师用来推导和设计电路逻辑的“数学公式”。它比汇编更底层,因为它描述的是数据在硬件连线上的具体流动。

以下是关于它的详细介绍:

核心符号 (The Vocabulary)

RTL 使用一套简洁的数学符号来表示硬件动作。掌握这些符号就能读懂各种架构图:

符号 含义 例子 解释
$\leftarrow$ 传输 / 赋值 $R1 \leftarrow R2$ 把寄存器 R2 的内容复制给 R1
[ ] 寻址 / 内容 $M[100]$ 内存地址为 100 的存储单元里的数据
M 内存 (Memory) $M[PC]$ PC 指向的内存地址里的内容
, 并行执行 $R1 \leftarrow R2, R2 \leftarrow R1$ 这两个操作在同一个时钟周期内同时发生
() 部分位 $R1(0-7)$ 仅操作 R1 寄存器的低 8 位