微程序控制器
硬布线把
一旦接受”控制信号是查出来的”,一整套新术语就顺着长出来:存表的地方叫控制存储器,表里的一行叫微指令,一行里的一位(或一个编码)叫微命令,完成一条机器指令要查的那一串行叫微程序。
本节的难点全部集中在”编码”上——表存得越紧凑,取出来后要做的译码就越多,速度就越慢。这是 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 容量最大
(二)字段直接编码
把微命令分组,每组内部用编码表示。
分组的规则只有两条,但两条都要用上:
- 互斥的微命令编在同一字段——它们不可能同时有效,所以可以共用编码
- 相容的微命令必须分在不同字段——它们可能同时有效,共用编码就发不出来了
“互斥”的判据是物理上的:同一拍内不可能同时成立。典型互斥组:
- 所有
Xout信号(5.3.2:单总线一拍只能一个源驱动) ALUop的各种功能(ALU 一拍只能做一种运算)- 主存的
Read和Write
典型相容组:各个 Xin 信号(多个寄存器可以同时接收),所以它们不能编在同一字段。
那个 “+1” 是本节最高频的陷阱:每个字段必须留出一个编码表示”本段不发出任何微命令”。所以:
例:某组有 7 个互斥微命令 → 需要
(三)字段间接编码
一个字段的含义由另一个字段来解释。进一步压缩长度,但译码更复杂、速度更慢,通常只作为字段直接编码的辅助。
(四)混合编码
直接编码与字段编码并用,在速度和长度之间折中——实际机器采用的就是这种。
水平型与垂直型
疑问点:垂直型微指令是个什么东西
一句话:垂直型微指令就是把微指令写成一条”迷你机器指令”。
两种格式并排看,差别一眼可见:
水平型 垂直型 格式 操作控制字段 | 判别测试 | 下地址 μOP | | 像什么 一排开关面板,一位一个开关 一条机器指令,有操作码有操作数 有没有微操作码 没有——每位直接就是控制信号 有——需要译码才知道发什么信号 一条能做几个微操作 多个,并行 通常一个 微指令字长 长 短 微程序长度 短(并行度高,条数少) 长(一次只做一件事) 执行速度 快 慢 编写难度 难——要自己安排并行 易——像写汇编 与机器指令的关系 差别大 相似 判据只有一句:微指令里有没有微操作码字段。 有 → 垂直型(要译码);没有、每位直接是控制信号 → 水平型(不要译码)。
为什么垂直型慢,理由不止”一次只做一件事”:它还多了一层译码——μOP 要经译码器才变成控制信号,而水平型从 CM 读出来就已经是控制信号了。
这就是 4.1.4 那条主线在本章的兑现:编码越紧凑,越需要译码,越慢。 同一个取舍到这里已经是第三次出现:
层次 紧凑的一方 宽松的一方 代价 指令编码(4.1.4) 变长指令 / 扩展操作码 定长指令 取指与译码串行化 微命令编码(本节) 字段编码、垂直型 直接编码、水平型 多一级译码延迟 指令集风格(4.4.3) CISC RISC 译码复杂、难流水 三层的方向完全一致:省空间 ⇄ 花时间。 而水平型微指令之所以能”省时间”,代价就写在 CM 的容量里。
后继微地址的形成
两种方式:
| 方式 | 怎么形成 | 特点 |
|---|---|---|
| 断定方式(下地址字段) | 微指令里直接给出下一条的地址 | 灵活,可任意跳转;微指令要多一个字段 |
| 计数器方式(μPC) | 类似 PC,顺序执行时自动加 1,遇分支才另给地址 | 微指令短;顺序性强,分支不便 |
408 的题目绝大多数按断定方式出——因为微指令格式里明写着”下地址字段”。
控制存储器的容量计算
微指令总条数怎么数(王道口径):
“取指微程序只有一段、被所有机器指令共用”是必考点——它对应 5.2.1 说的”取指周期的动作与是哪条指令无关”。
一道完整例题的算法:
某机有 32 条指令,每条指令的微程序平均 4 条微指令,另有一段公共取指微程序占 2 条。微命令共 40 个,其中可分成 6 个互斥组,各组分别有 8、7、6、5、4、3 个微命令,另有 7 个微命令必须用直接编码。判别测试字段 3 位。求 CM 容量。
- 微指令总条数
- 下地址字段
位 - 操作控制字段:六个互斥组分别需
、 、 、 、 、 位,合计 18 位;再加直接编码的 7 位 → 25 位 - 微指令字长
位 - CM 容量
位 位 第 3 步每组都要
——这是全题唯一的陷阱。
与硬布线的对比
| 硬布线 | 微程序 | |
|---|---|---|
| CU 的实现 | 组合逻辑(与-或阵列) | 控制存储器 + 取微指令逻辑 |
| 控制信号来源 | 算出来 | 读出来 |
| 速度 | 快 | 慢(每拍要读一次 CM) |
| 规整性 | 差,阵列杂乱 | 好,微程序整齐易读 |
| 修改扩充 | 难,要改电路 | 易,改 CM 内容 |
| 适合 | RISC | CISC |
边界
边界辨析:互斥 / 相容
- 互斥:同一拍不可能同时有效 → 编在同一字段
- 相容:同一拍可能同时有效 → 必须分在不同字段
典型互斥:所有
Xout(单总线一拍一个源)、ALUop各功能、Read/Write。 典型相容:各个Xin(多个寄存器可同时接收)。判据来自 5.3.2 那条
Xout与Xin的不对称。
边界辨析:字段位数要不要 +1
要。 每个字段必须留一个编码表示”本段不发命令”:
位 数
时是 4 位不是 3 位。这是微程序计算题最高频的失分点。
层次辨析:微指令 / 机器指令
- 一条机器指令 = 一段微程序(多条微指令)
- 一条微指令 = 一拍要发的全部微命令
- 微指令存在 CM(CPU 内、只读),机器指令存在主存
- 微指令程序员不可见,机器指令可见
垂直型微指令”像机器指令”,但只是格式像,层次完全不同。
边界辨析:微命令 / 微操作
一一对应,是同一件事的因与果:微命令是发出的控制信号,微操作是它引起的动作。题目问关系,答”一一对应”。
对照速查
| 要算什么 | 公式 |
|---|---|
| 某互斥组的字段位数 | |
| 下地址字段位数 | |
| 微指令字长 | 操作控制 + 判别测试 + 下地址 |
| 微指令总条数 | |
| CM 容量 | 总条数 × 字长 |
| 直接编码的字段位数 | 等于微命令个数(一位一个) |
| 说法 | 判断 |
|---|---|
| 一条机器指令对应一段微程序 | ✅ |
| 一条微指令对应一个机器周期 | ✅ |
| 控制存储器在 CPU 内部 | ✅ 且是 ROM |
| 微程序控制器比硬布线快 | ❌ 要访问 CM |
| 水平型微指令的微程序比垂直型短 | ✅ 并行度高 |
| 垂直型微指令字长比水平型短 | ✅ |
| 相容的微命令应编在同一字段 | ❌ 互斥的才编在同一字段 |
| 用户可以改写控制存储器扩充指令 | ❌ CM 是只读的 |
考点
- CM 容量计算:五步流程如上。每个字段
、取指微程序只算一段是两大陷阱。 - 互斥字段分组:给一批微命令,判断哪些能编在同一字段。判据是”同一拍会不会同时有效”。
- 水平型 / 垂直型辨析:六项对比,判据是”有没有微操作码”。
- 判别测试字段的作用:答指出本步要测试哪一类条件,测试结果去修改下地址字段形成分支微地址。
- 三个”地址”的分辨:下地址字段索引 CM,源/目的地址索引寄存器堆,机器指令地址码索引主存。
- 微程序 vs 硬布线六项对比:速度、规整性、修改难度、适用机型等。
链接
- 🏠 返回总览:计算机组成原理第 5 章:中央处理器总览
- ⬅️ 上一节:5.4.2 硬布线控制器
- ➡️ 下一节:5.5.1 异常和中断的基本概念
- 🔗 互斥的物理来源:5.3.2 数据通路的组成
- 🔗 “编码紧凑要用译码时间换”:4.1.4 扩展操作码指令格式
- 🔗 CM 是 ROM:3.2.2 只读存储器
- 🖼️ 配图:微程序控制器取微指令与后继地址图
- 📖 名词库:第 5 章名词库