微程序控制器

硬布线把 操作码节拍标志 做成了电路。微程序控制器做的是另一件事:把这个函数的值全部预先算好,存进一个只读存储器,运行时查表。

一旦接受”控制信号是查出来的”,一整套新术语就顺着长出来:存表的地方叫控制存储器,表里的一行叫微指令,一行里的一位(或一个编码)叫微命令,完成一条机器指令要查的那一串行叫微程序。

本节的难点全部集中在”编码”上——表存得越紧凑,取出来后要做的译码就越多,速度就越慢。这是 4.1.4 那条”编码紧凑要用译码时间来换”的主线在本章的兑现,也是水平型与垂直型之争的全部内容。

机制

术语的四个层次

层次是什么类比
微命令 / 微操作一根控制信号 / 它引起的一次动作一个开关
微指令同一拍要发的一组微命令 + 下一条微指令的地址信息一行开关状态
微程序完成一条机器指令所需的全部微指令序列一段程序
控制存储器 CM存放所有微程序的只读存储器存这些程序的 ROM

两条容易混的对应关系:

一条机器指令一段微程序 一个机器周期(一拍)一条微指令

微命令与微操作是同一件事的两面:微命令是控制信号(因),微操作是它引起的动作(果)。题目问”微命令和微操作的关系”,答一一对应。

部件组成

flowchart TB
    IR["IR 的操作码"]
    MAF["微地址形成部件"]
    uMAR["微地址寄存器 μMAR"]
    CM[("控制存储器 CM<br/>只读,存全部微程序")]
    uIR["微指令寄存器 μIR"]
    OPF["操作控制字段<br/>→ 控制信号"]
    TESTF["判别测试字段"]
    NEXTF["下地址字段"]
    FLAG["状态标志"]

    IR --> MAF
    FLAG --> MAF
    MAF --> uMAR
    uMAR --> CM
    CM --> uIR
    uIR --> OPF
    uIR --> TESTF
    uIR --> NEXTF
    TESTF --> MAF
    NEXTF --> MAF

    classDef store fill:#dcfce7,stroke:#16a34a,stroke-width:2px
    classDef reg fill:#dbeafe,stroke:#2563eb,stroke-width:2px
    classDef fld fill:#fde68a,stroke:#d97706,stroke-width:2px
    class CM store
    class uMAR,uIR reg
    class OPF,TESTF,NEXTF,MAF fld

注意 CM 是只读的。 微程序在机器出厂时就固化了,运行中不会被改写——所以它是 ROM 而不是 RAM(3.2.2)。“用户可以通过编写微程序来扩充指令系统”这类说法在 408 里按错误处理,除非题目明说是可写控制存储器(WCS)。

微指令的三个字段

操作控制字段判别测试字段下地址字段
字段干什么位数由什么定
操作控制字段(微操作码字段)发出这一拍的全部微命令编码方式,见下
判别测试字段(P 字段)指出这一步要测试哪个条件测试类别的个数
下地址字段给出下一条微指令在 CM 中的地址微指令总条数

疑问点:判别测试字段是什么?目的地址和源地址又分别是什么?

两个问题都卡在同一个词上:微指令里的”地址”和机器指令里的”地址”不是一回事,而且微指令内部还有两种不同的”地址”。

先答判别测试字段。它管的是”下一条微指令去哪”,而且只在需要分支的时候起作用。

微程序也要有分支——否则所有机器指令都会走同一串微指令。分支发生在两个地方:

分支场合依据什么分常记作
取指微程序的最后一条操作码——按是哪条指令,散转到各自的微程序入口
条件转移指令的微程序中状态标志(ZF、CF…)——决定转不转

机制是”修改下地址”:

实际微地址下地址字段测试结果改写其中若干位分支后的微地址
  • 判别测试字段全 0 → 不测试,下一条微地址 就是下地址字段的值(顺序执行)
  • 有效 → 用操作码去改写微地址的低若干位,于是不同的操作码落到不同的微程序入口
  • 有效 → 用 ZF 改写微地址的最低一位,于是”转”和”不转”落到两条不同的微指令

所以判别测试字段回答的不是”测试的结果是什么”,而是”这一步要不要测、测哪一类”。 它是一个选择器的选择信号,不是条件本身。

那一步值得单独看一眼:它把机器指令的操作码变成了控制存储器的地址。5.4.1 说的”三个地址”里,这是唯一一处两个地址空间发生接触的地方——而它接触的方式是”用一个空间的编号去索引另一个空间”,正是一次地址翻译(4.2.1 那条链的思维动作)。


再答源地址和目的地址。它们根本不是内存地址,是寄存器编号。

垂直型微指令的格式 μ 长得像一条机器指令,但三个字段的含义都在 CPU 内部:

字段是什么位数例子
μOP(微操作码)这次做哪一类微操作:传送、加、移位……微操作类别数”传送”
源地址数据从哪个部件出来——寄存器编号可作源的部件数R1
目的地址数据送进哪个部件——寄存器编号可作目的的部件数R2

整条微指令的意思就是 ,也就是发出 R1out 和 R2in 两个微命令。

“地址”在这里 = “编号”。 它索引的是寄存器堆,既不是主存也不是控制存储器。而这个编号在硬件上的去向,正是 5.3.2 那对零件:源编号送 MUX 的选择端(读),目的编号送译码器(写)。


把三个”地址”并排放一次,混淆就不会再回来:

名字索引哪个存储体出现在
机器指令的地址码主存程序里,可见
微指令的下地址字段控制存储器 CM微指令里,不可见
微指令的源/目的地址寄存器堆垂直型微指令里,不可见

微命令的编码方式

这是本节的计算核心,也是”互斥字段”那类题的出处。

(一)直接编码(直接控制)

操作控制字段的每一位对应一个微命令,该位为 1 就发出这个微命令。

  • 不需要译码,从 CM 读出来直接就是控制信号 → 最快
  • 字段最长:有多少个微命令就要多少位 → CM 容量最大

(二)字段直接编码

把微命令分组,每组内部用编码表示。 个微命令编在一个字段里,只需 位。

分组的规则只有两条,但两条都要用上:

  1. 互斥的微命令编在同一字段——它们不可能同时有效,所以可以共用编码
  2. 相容的微命令必须分在不同字段——它们可能同时有效,共用编码就发不出来了

“互斥”的判据是物理上的:同一拍内不可能同时成立。典型互斥组:

  • 所有 Xout 信号(5.3.2:单总线一拍只能一个源驱动)
  • ALUop 的各种功能(ALU 一拍只能做一种运算)
  • 主存的 Read 和 Write

典型相容组:各个 Xin 信号(多个寄存器可以同时接收),所以它们不能编在同一字段。

那个 “+1” 是本节最高频的陷阱:每个字段必须留出一个编码表示”本段不发出任何微命令”。所以:

字段位数该组互斥微命令的个数

例:某组有 7 个互斥微命令 → 需要 位(7 个命令 + 1 个”不操作”= 8 种状态)。若忘了 +1,会算成 位——这次恰好相同;但 8 个互斥微命令时,正确答案是 位,漏掉 +1 就会错答 3 位。

(三)字段间接编码

一个字段的含义由另一个字段来解释。进一步压缩长度,但译码更复杂、速度更慢,通常只作为字段直接编码的辅助。

(四)混合编码

直接编码与字段编码并用,在速度和长度之间折中——实际机器采用的就是这种。

水平型与垂直型

疑问点:垂直型微指令是个什么东西

一句话:垂直型微指令就是把微指令写成一条”迷你机器指令”。

两种格式并排看,差别一眼可见:

水平型垂直型
格式操作控制字段 | 判别测试 | 下地址μOP | |
像什么一排开关面板,一位一个开关一条机器指令,有操作码有操作数
有没有微操作码没有——每位直接就是控制信号有——需要译码才知道发什么信号
一条能做几个微操作多个,并行通常一个
微指令字长长短
微程序长度短(并行度高,条数少)长(一次只做一件事)
执行速度快慢
编写难度难——要自己安排并行易——像写汇编
与机器指令的关系差别大相似

判据只有一句:微指令里有没有微操作码字段。 有 → 垂直型(要译码);没有、每位直接是控制信号 → 水平型(不要译码)。

为什么垂直型慢,理由不止”一次只做一件事”:它还多了一层译码——μOP 要经译码器才变成控制信号,而水平型从 CM 读出来就已经是控制信号了。

这就是 4.1.4 那条主线在本章的兑现:编码越紧凑,越需要译码,越慢。 同一个取舍到这里已经是第三次出现:

层次紧凑的一方宽松的一方代价
指令编码(4.1.4)变长指令 / 扩展操作码定长指令取指与译码串行化
微命令编码(本节)字段编码、垂直型直接编码、水平型多一级译码延迟
指令集风格(4.4.3)CISCRISC译码复杂、难流水

三层的方向完全一致:省空间 ⇄ 花时间。 而水平型微指令之所以能”省时间”,代价就写在 CM 的容量里。

后继微地址的形成

两种方式:

方式怎么形成特点
断定方式(下地址字段)微指令里直接给出下一条的地址灵活,可任意跳转;微指令要多一个字段
计数器方式(μPC)类似 PC,顺序执行时自动加 1,遇分支才另给地址微指令短;顺序性强,分支不便

408 的题目绝大多数按断定方式出——因为微指令格式里明写着”下地址字段”。

控制存储器的容量计算

容量微指令总条数微指令字长 微指令字长操作控制字段位数判别测试字段位数下地址字段位数 下地址字段位数微指令总条数

微指令总条数怎么数(王道口径):

总条数每条机器指令该指令微程序的微指令条数取指微程序公共间址、中断微程序若题目提及

“取指微程序只有一段、被所有机器指令共用”是必考点——它对应 5.2.1 说的”取指周期的动作与是哪条指令无关”。

一道完整例题的算法:

某机有 32 条指令,每条指令的微程序平均 4 条微指令,另有一段公共取指微程序占 2 条。微命令共 40 个,其中可分成 6 个互斥组,各组分别有 8、7、6、5、4、3 个微命令,另有 7 个微命令必须用直接编码。判别测试字段 3 位。求 CM 容量。

  1. 微指令总条数
  2. 下地址字段 位
  3. 操作控制字段:六个互斥组分别需 、、、、、 位,合计 18 位;再加直接编码的 7 位 → 25 位
  4. 微指令字长 位
  5. CM 容量 位 位

第 3 步每组都要 ——这是全题唯一的陷阱。

与硬布线的对比

硬布线微程序
CU 的实现组合逻辑(与-或阵列)控制存储器 + 取微指令逻辑
控制信号来源算出来读出来
速度快慢(每拍要读一次 CM)
规整性差,阵列杂乱好,微程序整齐易读
修改扩充难,要改电路易,改 CM 内容
适合RISCCISC

边界

边界辨析:互斥 / 相容

  • 互斥:同一拍不可能同时有效 → 编在同一字段
  • 相容:同一拍可能同时有效 → 必须分在不同字段

典型互斥:所有 Xout(单总线一拍一个源)、ALUop 各功能、Read/Write。 典型相容:各个 Xin(多个寄存器可同时接收)。

判据来自 5.3.2 那条 Xout 与 Xin 的不对称。

边界辨析:字段位数要不要 +1

要。 每个字段必须留一个编码表示”本段不发命令”:

位数

时是 4 位不是 3 位。这是微程序计算题最高频的失分点。

层次辨析:微指令 / 机器指令

  • 一条机器指令 = 一段微程序(多条微指令)
  • 一条微指令 = 一拍要发的全部微命令
  • 微指令存在 CM(CPU 内、只读),机器指令存在主存
  • 微指令程序员不可见,机器指令可见

垂直型微指令”像机器指令”,但只是格式像,层次完全不同。

边界辨析:微命令 / 微操作

一一对应,是同一件事的因与果:微命令是发出的控制信号,微操作是它引起的动作。题目问关系,答”一一对应”。

对照速查

要算什么公式
某互斥组的字段位数, = 组内微命令数
下地址字段位数微指令总条数
微指令字长操作控制 + 判别测试 + 下地址
微指令总条数 各指令微程序条数 + 公共取指微程序
CM 容量总条数 × 字长
直接编码的字段位数等于微命令个数(一位一个)
说法判断
一条机器指令对应一段微程序✅
一条微指令对应一个机器周期✅
控制存储器在 CPU 内部✅ 且是 ROM
微程序控制器比硬布线快❌ 要访问 CM
水平型微指令的微程序比垂直型短✅ 并行度高
垂直型微指令字长比水平型短✅
相容的微命令应编在同一字段❌ 互斥的才编在同一字段
用户可以改写控制存储器扩充指令❌ CM 是只读的

考点

  • CM 容量计算:五步流程如上。每个字段 、取指微程序只算一段是两大陷阱。
  • 互斥字段分组:给一批微命令,判断哪些能编在同一字段。判据是”同一拍会不会同时有效”。
  • 水平型 / 垂直型辨析:六项对比,判据是”有没有微操作码”。
  • 判别测试字段的作用:答指出本步要测试哪一类条件,测试结果去修改下地址字段形成分支微地址。
  • 三个”地址”的分辨:下地址字段索引 CM,源/目的地址索引寄存器堆,机器指令地址码索引主存。
  • 微程序 vs 硬布线六项对比:速度、规整性、修改难度、适用机型等。

链接