10. 控制单元的设计
文章目录
- 10. 控制单元的设计
- 10.1 组合逻辑设计
- 10.1.1 CU外特性
- 10.1.2 微操作的节拍安排
- 10.1.3 组合逻辑设计步骤
- 10.2 微程序设计
- 10.2.1 微程序设计思想
- 10.2.2 微指令格式
- 10.2.3 毫微程序设计
- 10.2.4 微程序设计举例
- 完结撒花
- 本笔记参考哈工大刘宏伟老师的MOOC《计算机组成原理(上)_哈尔滨工业大学》、《计算机组成原理(下)_哈尔滨工业大学》。
- 或者是B站《计算机组成原理(哈工大刘宏伟)135讲(全)高清》,大家一起听比较热闹。
- 中文教材:《计算机组成原理(第二版)-唐朔飞.pdf》、《学习指导与习题解答(第2版)-唐朔飞.pdf》
- 本篇笔记对应课程第十章(下图加粗)。
第九章将指令周期分为四个机器周期:取指周期、间址周期、执行周期、中断周期,并分析了每个机器周期当中 CU 要发出的各种控制信号/命令。本章在第九章的基础上,进一步介绍 如何设计控制单元 CU,主要有以下两种方法:
- 组合逻辑设计:完全由硬件来实现,缺点是难以修改。
- 微程序设计:采用“存储逻辑”的方式设计控制单元,非常适合指令集扩展。
10.1 组合逻辑设计
10.1.1 CU外特性
上一章已经介绍过 CU 的外特性,下面具体来看一下CU输入输出信号的设置及位宽:
- 节拍发生器:m+1位,产生 CU 所需的节拍信号,m 表示单个机器周期所能包含的最大周期数。如上右图,假设每个机器周期都包含4个节拍,那么就只会用到 T0~T3,由 T0~T3 控制每一个微操作命令或者是控制命令发出的时间。
- 操作码译码:根据译码结果通知 CU 要做什么操作。假设操作码为 n 位,那么经过“操作码译码”后会有 2n 根译码线输入到 CU,其中只有一根译码线是高电平。
- 标志:同样影响 CU 输出控制信号。比如“条件跳转指令”需要进行跳转条件的判断,就会用到这些标志信号。
- 控制信号:共有 k+1 位,每根控制信号都连接一个控制电路(9.2.2节-不采用CPU内部总线的方式)。在每个节拍中,一个或几个控制信号为高电平,控制CPU内各部件的运行。
实际上,上述给出了 通用的CU外特性,下面就来介绍如何使用“组合逻辑设计”实现CU内部结构。下一大节介绍如何使用“存储逻辑”实现CU内部结构。
10.1.2 微操作的节拍安排
- 控制信号Ci:共13个,蓝色标出。所有的控制信号都是在时钟、操作码译码、标志作为输入的情况下,由CU在给定的节拍下产生。并且 CU 的控制信号也会影响 ALU 的控制信号、CU 的标志。
上一章我们讲解了非总线方式的CPU内部结构(如上图),并介绍了机器指令执行过程中需要发出的所有控制命令,以及“多级时序系统”。于是我们需要将各个控制命令安排到不同机器周期的各个节拍上,也就是确定“微操作时序”。原则如下:
- 原则一:微操作的先后顺序不得随意更改。
- 原则二:可以并行执行的微操作,尽量安排在一个节拍内完成。
- 原则三:占用时间较短但有先后顺序的微操作,也尽量安排在一个节拍内完成,比如分别在上升沿、下降沿执行。
下面根据所给出的“前提假设”,来介绍“取指周期”、“间址周期”、“执行周期”、“中断周期”的微操作的节拍安排:
前提假设
- CPU结构采用非总线方式(9.2.2节-控制信号举例)。
- 采用同步控制方式,且一个机器周期内有3个节拍(时钟周期)。实际上节拍数和控制信号的数量、复杂程度、能否并行执行有关,所以不同机器的节拍数不同。
取指周期 微操作的节拍安排:注意CPU内部寄存器→寄存器之间的操作耗时很短,如 MDR → IR。
间址周期 微操作的节拍安排
执行周期 微操作的节拍安排:【CLA】清零ACC;【COM】将ACC按位取反;【SHR】将ACC算术右移一位;【CSL】将ACC循环左移一位;【STP】停机指令;【ADD X】加法指令,将X所保存内容于ACC相加;【STA X】存数指令,将ACC内容保存到内存的X地址中;【LDA X】取数指令,将X地址中的数据存储到ACC;【JMP X】跳转指令,将PC跳转到给定的地址X;【BAN X】分支指令/条件转移指令,若上一条指令计算结果(假设为ACC)小于零,则将PC跳转到X,注意当前的PC已经是下一条指令,并且实际上应该用标志信号作为判断条件。
中断周期 微操作的节拍安排:主要完成中断隐指令——“保存断点”、“形成中断服务程序的入口地址”、“关中断”。
注:PC指令计数器、MAR主存地址寄存器、MDR主存数据寄存器、OP(IR)指令操作码、Ad(IR)指令地址码、ID指令译码器。1→R表示CU发出读控制信号给存储器,1→W表示CU发出写信号。AC寄存器(ACC)、L(AC)左边的位、R(AC)右边的位、AC0符号位。
10.1.3 组合逻辑设计步骤
1. 列出操作时间表
根据上述节拍安排,我们便可以确定组合逻辑电路的设计。可以发现上述每个机器周期中的微操作数量有限,于是可以列表统计起来。下面给出6种指令的“取指周期”、“间址周期”、“执行周期”的操作时间表:
- 取指周期FE:间址特征 I 的决定了下一周期是 间址周期IND 还是 执行周期EX。
- 间址周期IND:间址周期标志 IND 决定了后续是否还要间址, IND ‾ \overline{\text{IND}} IND 表示不需要。
- 执行周期EX:将每个指令对应节拍、对应微操作的位置标记“1”。
- 中断周期:本小节未给出。
2. 写出微操作命令的最简表达式
于是根据上表,将用到的指令和对应的节拍写进来,就可以得到每个微操作的组合逻辑控制表达式,比如【M(MAR)→MDR】来说:
M(MAR)→MDR
= FE·T1 + IND·T1(ADD+STA+LDA+JMP+BAN) + EX·T1(ADD+LDA)
= T1{FE + IND(ADD+STA+LDA+JMP+BAN) + EX(ADD+LDA)}
3.画出逻辑图
根据上述表达式,就可以画出逻辑图:
最后总结以下“组合逻辑设计”的特点:
- 思路清晰,设计简单,速度非常快,RISC就使用该方法。现代处理器将处理单元分为“整型处理单元”、“浮点处理单元FPU”,其中“整型处理单元”就是使用本方法。
- 电路庞杂,调试和修改都很困难,难以进行指令集的扩展。因为上述例子只是一个控制信号,而要完成所有的机器指令需要还需要几十个控制信号的设计。
10.2 微程序设计
“微程序设计”采用“存储逻辑”的方式设计控制单元,设计和修改都比较容易,非常适合指令集的扩展。
10.2.1 微程序设计思想
1951年,英国剑桥大学教授Wilkes首次提出“微程序设计思想”。如下图所示,一条“机器指令”可以拆分成若干“微操作命令”,将单个节拍中的所有“微操作命令”组合在一起就是“微指令”。我们不妨将将“微指令”进行二进制编码,每一位都表示一种微操作,于是一个“微指令”就能发出本节拍的控制信号,将这些“微指令”按照节拍的顺序组合起来就是“微程序”。
最终如下右图所示,一条机器指令对应一个微程序,存入ROM,执行时依次读出,并执行相应的控制信号,即可完成机器指令。这就是“存储逻辑”。图中假设每个机器周期都是三个节拍,所以微程序长度都是3:
- “取指周期微程序”结束后,需要根据机器指令的操作码才能确定下一微指令的地址,所以标记为“XXX”。
- “间址周期微程序”结束时根据机器指令的操作码才能确定下一微指令的地址,所以也是“XXX”。
- “中断周期微程序”结束时会直接转回到“取指周期微程序”。
- 【LDA指令】、【STA指令】执行完毕后,会返回到“取指周期微程序”的首地址。
下图给出了微程序控制单元的基本框图,注意“微指令格式”也是分为“操作控制字段”、“下地址字段(顺序控制)”两部分,“操作控制字段”的每一位都表示一个微操作控制信号,“下地址字段”则给出下一条微指令的地址。如下:
- 微地址形成部件:根据机器指令的操作码形成微程序地址。
- 顺序逻辑:实际上是一个多路选择器,其控制信号为“标志、CLK”。由于 CMAR 有多个数据来源,所以“顺序逻辑”负责选择正确的数据来源并将其传递给 CMAR。比如刚开始执行机器指令需从“微地址形成部件”找到第一条微指令,后续则可以直接根据“下地址”找到下一条微指令地址。
- 地址译码:微指令的地址保存在 CMAR 中,经过“地址译码”可以将读出的数据送入到 CMDR 中。
- 控制存储器【核心】:是一个ROM,所有的微程序都保存在其中。
注:CMAR控制存储器地址寄存器、CMDR控制存储器数据寄存器。
下面给出“微程序设计”中的两个小概念:
- 静态微程序设计和动态微程序设计:根据“控制存储器”的不同,分为两种。
- 静态微程序:采用ROM,无须修改微程序。
- 动态微程序:采用EPROM,可以修改微程序。常用于指令集的开发,一般很少修改指令集,而是增加指令集。
- 串行微程序控制和并行微程序控制:微指令也可以使用“流水技术”提升微程序执行速度。
最后使用一个小例子,进一步说明微程序的执行过程。如下图,用户程序在“主存”中给出,“控存”则保存了所有机器指令所对应的微程序。于是执行用户程序的过程,就是根据机器指令不断执行其对应的微程序:
- 【LDA X】取指周期:执行“取指周期微程序”。根据机器指令的操作码,得出是【LDA指令】,于是下一个机器周期就跳转到【LDA指令】对应的微程序。
- 【LDA X】执行阶段:按照顺序执行“LDA微程序”,执行结束后返回“取指周期微程序”,加载下一条指令。
- 【ADD Y】取指阶段:执行“取指周期微程序”。根据机器指令的操作码,得出是【ADD指令】,于是下一个机器周期就跳转到【ADD指令】对应的微程序。
- 【ADD Y】执行阶段:按照顺序执行“ADD微程序”,执行结束后返回“取指周期微程序”,加载下一条指令。
- …不断的循环往复,即可执行完所有的用户程序。
下一节将继续介绍两个关键问题:
- 微指令的“操作控制字段”如何形成微操作命令?
- 微指令的后续地址如何形成?
10.2.2 微指令格式
上一小节已经介绍了微指令的格式,主要由“操作控制字段”、“下地址字段”两部分构成,“操作控制字段”给出当前微操作的控制信号。下面给出几种“操作控制字段”的编码方式:
- 直接编码:也被称为“直接控制”。操作控制字段中的每一位都代表一个微操作命令,为“1”表示该控制信号有效,速度最快。实际上就是上一小节最后的例子,比如第一位就表示【PC→MAR】、第二位表示【M(MAR)→MDR】、…、最后一位表示【1→R】等不同的微操作。
- 显式编码:也被称为“字段直接编码”。将微指令的控制字段分成若干“段”,每“段”经译码后发出控制信号。每个字段中的命令是互斥的,不同字段的命令可以并行执行,可以缩短微指令字长,但译码速度较慢。
- 隐式编码:也被称为“字段间接编码”。每一段的译码结果和其他段有关。
- 混合编码:混合使用上述编码方式,比如常用的微指令使用“直接编码”,不常用的微指令使用“显式编码”/“隐式编码”,相比于只使用“直接编码”可以压缩微指令字长。
- 其他:留待大家思考。
另外,根据“操作控制字段”的不同,微指令格式还可以分为:
水平型微指令:“操作控制字段”可以直接被译码并发出控制信号,特点是宽而扁,对存储需求较高。上述介绍的所有编码方式都是“水平型微指令”。
垂直型微指令:“操作控制字段”不能直接被转换成控制信号,而是类似于机器指令的操作码,采用更高级别的编码,需要专门的译码电路。特点是窄而深,可以减少对存储的需求,但会提升微程序译码复杂度。优点是可以控制硬件完成非常复杂的操作。具体见下一小节“10.2.3节-毫微程序设计”。
两种微指令格式的比较
- 水平型微指令并行操作能力更强,灵活性更强。
- 水平型微指令执行一条机器指令所要的微指令数目少,速度快。
- 水平型微指令较长,但设计的微程序较短;垂直性微指令较短,但设计的微程序结构较长。
- 水平型微指令与机器指令的差别大;垂直型微指令则非常类似。
“下地址字段”主要提供下一条微指令的地址,比较简单,所以我们来介绍“多路选择/顺序逻辑”。微程序控制单元的“顺序逻辑”用于从所有输入中选择一个有效的微指令地址,其输入来源主要有以下几种:
微指令的“下地址字段”。
根据机器指令的“操作码”形成。
增量计数器:在取指阶段、执行阶段的下地址都是直接+1,也就是【(CMAR)+1 → CMAR】。
分支转移微指令:分支转移微指令的格式如下,其中“转移方式”指明判别条件,“转移地址”指明转移成功后的去向。
通过测试网络:将下地址分成两段,低位经过测试源进行变换,再和高位组合在一起形成新的微指令地址。可用于微程序在小范围内的跳转,也就是一种“条件转移操作”。
由硬件产生微程序入口地址:也就是一些固定地址的指令可以由硬件直接产生,比如刚开机要执行的第一条微指令的地址、中断周期的微程序首地址、间址周期的微程序首地址。
10.2.3 毫微程序设计
前面介绍过“微程序设计”就是用微程序解释机器指令,而“毫微程序设计”就是用毫微程序解释微指令,毫微指令与微指令的关系好比微指令与机器指令的关系,如上图所示。之所以会多出“毫微指令”这个概念,是因为上一小节提到的“垂直型微指令”被极度压缩,需要使用专门的译码电路来将其转换成控制信号。如下图所示,左侧的“控制存储器(微程序)”使用“垂直型微指令”编写,取出该微指令后,就可以将其地址码送入“控制存储器(毫微程序)”。“毫微指令”使用水平型编码,可以直接发出控制信号。于是通过这样的方式,就将“垂直型微指令”转换成一系列“水平型微指令”:
10.2.4 微程序设计举例
前提假设
- CPU结构采用非总线方式(9.2.2节-控制信号举例)。
- 微指令采用“水平型编码方式”。
- 后续微指令的地址,要么由机器指令的操作码通过“微地址形成部件”形成,要么由微指令的“下地址字段”直接给出。
1. 写出机器指令的微操作及节拍安排
最后一节,通过一个例子来理解整个“微程序设计”的过程。我们首先写出所有机器指令的微操作及节拍安排,“微操作”决定了微指令的“操作控制字段”,“节拍安排”则决定了微指令的先后顺序。注意和 “10.1节-组合逻辑设计”不同,我们不仅要考虑 CPU 内(微程序控制单元之外)各结构之间的操作,还需要考虑新增加的“微程序控制单元”内部的操作:
取指阶段的微操作及节拍安排:总体还是分为“发送指令地址”、“取指令”、“操作码译码”三大阶段,但增加了“微程序控制单元”的操作,注意最后将操作码的译码结果送给CMAR。
执行阶段的微操作及节拍安排:考虑到需形成后续微指令的地址,由微指令下地址字段 Ad(CMDR) 指出。黑色表示 “微程序控制单元” 外部的操作、蓝色表示 “微程序控制单元” 内部的操作。
注:指令含义见“10.1.2节-微操作的节拍安排”。
上述共10条指令,一共包含20种微操作(节拍)、38条微指令(节拍中包含的所有动作)。
2. 确定微指令字长
“微操作”的数量决定的“操作控制字段”的位宽,“微指令”的数量决定“控制存储器”的存储单元数量。于是上述10条指令,一共包含20种微操作、38条微指令,也就对应“操作控制字段”位宽为20,“控制存储器”的存储单元个数最少是38,于是“地址字段”最少需要6位。于是微指令字长最少为 20+6=26 位。
但微程序控制器的结构还可以进一步简化!这是因为上述所有和 CMAR 相关的19条微指令中,只有 1 条是 【OP(IR)→微地址形成部件→CMAR】,剩余18条都是【Ad(CMDR)→CMAR】。若设置“控存地址线”,将上述两种微指令直接输出到“控存地址线”,则不仅省去输至CMAR的时间,也可以省略 CMAR!此时便消除了19条微指令、2个微操作。总计10条指令,只剩下18种微操作、19条微指令!于是“操作控制字段”最少取18位,存储单元最少为19个,“下地址字段”最少取5位。
考虑留有一定的余量,“操作控制字段”设置为 24 位,“下地址字段”设置为 6 位,水平型微指令共 30 位。
3. 编写微指令码点
根据前两步,我们便可以定义“操作控制字段”每一位所对应的控制动作,然后就可以以表格的方式给出微程序所包含的微指令,也就是如下的“微指令码点”: