CPU 的主要职责分析

CPU 需要有运算器和控制器两个基本的结构,然后完成大概下面的任务:

  • 指令控制:完成取指令,分析指令和指令执行的操作,即程序的顺序控制。

  • 操作控制:控制产生操作信号,然后传送到所对应的部件上,让其来配合完成整条指令。

  • 时间控制:对各种操作加以时间上的控制。

  • 数据加工:对数据进行算数和逻辑运算,这里主要由运算器完成。

  • 中断处理:处理异常情况和特殊请求。

运算器 Calculator 的基本结构

下图可以看出运算器 Calculator 主要是由 ALU 和各类寄存器组成的:

255.jpg

主要部件 ALU 的工作原理在前面章节的数据表示和运算里面已经说明了,下面主要说一下运算器的工作流程。

首先引入了一个叫作 CPU 内部总线的东西,这个东西负责整个 CPU 内部的数据传输,但是 CPU 有很多个部件,同一时间只能有一个数据信号发送方,为了防止数据传送冲突,就在每个部件上都接入一根 in 和一根 out 控制线,负责控制元器件数据信号的发送和接收。只有 in 控制线有电流,元器件才会从总线上接收数据,只有 out 控制线有电流,元器件才能将自己存储的数据传送到数据总线上去。

这样通过控制器控制对应元器件的 in 和 out 线路,实现元器通过总线的数据传输。

控制器 Controlor 的基本结构

下面的内容都是控制器的所有包括内容,PC:Program Counter,IR:Instruction Register,ID:Instruction Decoder,PSW:Program Status Word,MAR,MDR,CU而里面的核心:微操作信号发生器

256.jpg

同样也是利用了 CPU 的内部总线,需要注意的是上面的 PSW,是一组程序状态字寄存器,上面的图片是有介绍的,用来记录当前程序运行所产生的特殊的状态。

因为 MAR 和 MDR 都是集成在 CPU 的内部,所以在和主存进行通信的时候,需要额外的数据总线和地址总线,用来传输信息。

指令周期

我们首先引入一系列的周期概念,主要分为运行时间决定的时间周期,和指令执行过程的指令周期。

周期概念

时钟周期 CLK,也被称为节拍,是 CPU 的最基本单位,也就是我们常用的 GHZ 单位。

机器周期 是一个微指令完成的实现,由若干个时钟周期组成,如从 PC 中取出指令并送入 MAR 中为一个取址机器周期.

指令周期 是通过执行若干个机器周期完成一条明确的指令所需要的时间被称为一个指令周期。

257.jpg

我们将一个指令拆分成不同的周期就是为了能够利用执行不同机器周期所需要的硬件资源不同,从而实现多个指令同时执行的并行效果。要实现并行就要记录指令正在执行的机器周期,这里使用不同的触发器来记录。

就是上面的 FE IND EX INT 几种不同的触发器来记录目前的程序有什么特殊的状态。

取址周期

非常普通的一个周期,PC -> MAR -> 地址总线 -> 内存 -> 数据总线 -> MDR -> IR ,其中 PC 会自增。

间址周期

没啥好说的,就是多了个间址。

中断周期

中断的目的就是暂停当前正在执行的任务,转去执行其他的任务(这也是多线程的实现基础),为了恢复当前任务,会使用堆栈保存当前任务的断点,将当前的程序指令的地址(从 PC 中获取),压入堆栈中,然后通过向量地址来获取下一个程序要执行的指令的地址,将其放入 PC 中,然后继续取址执行等等。

指令执行方案

执行方案指的是指令的运行顺序和时间的设计方案。

  • 单指令周期:所有指令使用相同的执行时间,只需要一个计数器数够次数即可,电路设计简单,是但是因为所有的指令使用的执行时间都是耗时最长的那个指令的执行时间,所以速度会很慢。

  • 多指令周期:指每个不同的指令使用不同的执行时间,虽然电路设计会复杂一点,但是相较于单指令周期,整体的效率是提高了。

  • 流水线模式:每间隔一段时间都启动一个指令的执行,让指令并行执行,效率最高,但也最难设计。(原理是指令执行的不同截断会使用不同的硬件)

数据传输方式

  • 总线模式

一条总线负责整个 CPU 内部的所有的数据的传输,电路设计简单,但是没有办法实现数据的并行传输,效率低。

258.jpg

  • 专线模式

每个部件之间的数据传输使用部件之间的专有线路,可以并行传输,效率高。

259.jpg

CU 的输入输出

269.jpg

控制单元就是根据当前执行指令内容(IR),当前执行时期(标志位),执行时间间隔(时钟周期),突发情况(外来信号),结合这些信息之后,发出来合适的控制信号给各种部件来完成指令的执行。

而输入进来的数据其实是下面这样的:

270.jpg

其中多了操作码译码器和节拍发生器对输入进来的数据进行处理,其中前者我们已经非常清楚了,而节拍发生器的作用则是将内部的统一时钟信号 CLK 转化为 T0 ~ Tm 的固定周期的电路信号,从而组成一个机器周期:

260.jpg

控制器 CU 设计

一般来说 CU 就是解析指令,然后根据解析的结果,像各个部件发出控制信号,指挥它们去完成指令的执行。

而生成控制型号的 CU 单元,有两种不同的设计模式,分别是硬布线设计模式和微指令设计模式。

硬布线设计模式:CU 控制信号是依靠输入进来的指令信息,时序系统,标志等经过内部复杂电路的计算之后,得到的一个控制信号的输出。是依靠硬件电路设计得到控制信号的,因此也叫硬布线。因为只要电流流过相应的电路,结果就直接被计算出来了,所以速度很快。

微指令设计模式:CU 控制信号是被完整的存储到了一个微指令存储器中,输入指令,直接从微指令内存中读取相应的控制信号,然后输出。因为涉及到微指令存储器的读取,所以速度会慢一点。但是这样设计的电路会简单一些。

比对图:273.jpg

硬布线 CU

CU 设计流程

  1. 分析每个阶段应该执行的微操作序列,举个例子,加法指令应该执行的微操作序列如下:

271.jpt

  1. 选择 CPU 的控制方式,即:产生不同的微操作命令序列所用的时序控制方式。后面会介绍三种不同的 CPU 控制方式。

  2. 安排微操作时序。

  3. 电路设计。

CPU 的控制方式

CPU 控制方式:产生不同的微操作命令序列所用的时序控制方式。作用就是用来控制微指令在执行过程中消耗的时间。

  • 同步控制方式:整个系统的控制信号均来自于一个统一的时钟信号,也就是 CPU 的主频。这样的话所有的微指令执行时间长度都必须是主频周期的整数倍,可能会有点慢。

  • 异步控制方式:这里是使用应答机制来确定微指令的执行时间,当一个微指令执行完毕,就会发送信号给 CU,然后 CU 启动下一条微指令的执行进程。这种方式微指令执行周期不受 CPU 主频的约束,但是电路设计会复杂很多。

  • 联合控制方式:将上面两种控制方式结合在一起,大部分使用同步控制方式,小部分使用异步执行方式。

微操作时序

微操作时序也就是设定一个指令所需要执行的所有微操作被执行的顺序和时间段,然后才能按照设定的时间去执行。

设计原则:

  1. 微操作的先后顺序不得被随意更改。
  2. 被控对象不同的微操作尽量被安排到一个节拍中完成
  3. 占用时间较短的微操作尽量安排在一个节拍中完成,并允许有先后顺序。

下面的 T0 T1 T2 就是节拍时间,后面跟着这个节拍中需要被执行的微操作,PC+1 被控对象和主存寻址不同,所以一起安排到了 T1 节拍中,4 5 指令执行占用时间较短,所以也被安排到了一个节拍中:

272.jpg

而这个安排节拍就是上面一个 CLK 生成的一个 Tn 周期,上图所安排的 T0 T1 T2 三个节拍指令会在三个 CLK 的时间内完成指令的执行。这三个节拍指令组成了一个机器指令完成所需要的时间的机器周期。

电路设计

因为微操作的数量是有限的,所以我们的基本设计思路就是用电路来计算在当前状态和时间,当前指令下,应该发出的控制型号是否为某种微操作。

这样计算出来的为 true 的微操作,就可以直接向外界发送自己对应的控制信号了。

状态的话有三个变量:工作周期标记,当前节拍,和状态标记。

剩下的输入就是 IR 提供的指令内容了,通过译码器会被转化为某一根线的电信号,代表着某个指令。

我们将指令作为横坐标,整个机器周期的工作周期,工作周期的节拍,节拍对应可能微操作命令作为纵坐标,列一个表格。然后将指令和对应的微操作命令符合的地方写上 1 ,表示一个指令的微操作命令的组合(当然这是一个简化的版本,省略了很多其他的指令,也没有特殊的状态条件)。

274.jpg

我们就根据当前正在执行的指令,当前的工作周期,节拍,条件状态,判断某个微操作是否要将自己执行的控制信号发送出去。用 M(MAR)->MDR 这条微操作为例子,计算是否发送本微操作的控制信号的计算公式如下:

FE*T1+IND*T1*(ADD+STA+LDA+JMP+BAN)+EX*T1(ADD+LDA)

首先看 FE*T1 这里是指在取指周期 FE 中的 T1 节拍的所有机器指令都需要执行 M(MAR)->MDR 这个微操作。所以将 FE 周期信号线和 T1 节拍信号线做 and 运算,如果结果为 true 那么就确定此状态为取值周期中的 T1 节拍,因为无论任何指令都需要执行 M(MAR)->MDR 这个微操作,所以仅凭 FE 和 T1 两个信号就可以决定是否发送 M(MAR)->MDR 这个微指令的控制信号了。

后面的则是对其他周期可能执行情况的计算。分别是处于间址周期 IND 的 T1 节拍的 ADD STA LDA JMP BAN 指令,还有处于执行周期 EX 的 T1 节拍的 ADD LDA 指令。

将上面的计算式子进行化简,也就是将 T1 提出来,简化电路,然后就可以根据这个画出来计算电路了,只要有电路能够流入 IV 中,他就会向控制总线中发送自己存储的 M(MAR)->MDR 微操控制信号。

275.jpg

微指令 CU

概念

将每一条机器指令编写成一个微程序,这些微程序可以存到一个控制存储器中,用寻址用户程序机器指令的办法来寻址每个微程序中的微指令。

我们应该很清楚了微操作命令这个东西,比如上面一直使用的 M(MAR)->MDR 就是一个微操作命令。我们将能同时执行的微操作命令称为相容性微操作命令,不能同时执行的称为互斥性微操作命令。

我们可以将我们所需要的若干个相容性微操作命令组合编码成一个微指令,因为微指令控制器的核心就是将机器指令转化为若干个微指令,这若干个微指令组成的一个集合就是此机器指令的微程序。读取到机器指令之后从控制存储器中读取对应机器指令执行的微程序,然后依次解析微程序的组成:微指令,微指令里面就记录了该向控制总线发送哪个微操作的控制信号。

这里微指令里面微操作的组成类似于硬布线对微操作进行节拍安排,会将可容性微操作命令放到一个节拍中执行,同理,可以将可容性微操作命令放到一个微指令中执行。

就像下面这样,微指令中为 1 的位表示此位对应的微操作需要被执行:

276.jpg


  • 微操作:一条机器指令可以分解成一个微操作序列,这些微操作是计算机中最基本的、不可再分解的操作。比如寻址中将 PC 地址放入 MAR 中:PC->MAR,就是一个不可分解的微操作。

  • 微命令:在微程序控制的计算机中,将控制部件向执行部件发出的各种控制命令称为微命令,它是构成控制序列的最小单位。每个微操作都对应一个自己的微命令。

  • 微指令:此概念只存在于微指令控制器中,微指令是若干微命令的集合,微指令又分为操作控制字段和顺序控制字段,操作控制地段决定本微指令在一个节拍中需要被执行的所有微操作,顺序控制字段决定下一条微指令的地址。

  • 微程序:微指令的有序集合,一条机器指令的功能由一段微程序来实现。

  • 微周期:微周期通常指从控制存储器中读取一条微指令并执行相应的微操作所需的时间。

基本结构

微指令控制器内部像是一个砍掉了 CU 和 ALU 的小主机,任务就是将传入的机器指令解析成对应微程序在控制存储器中的地址,在顺序逻辑器的控制下,依次读取微程序在存储器里面的每一条微指令,然后解析微指令将对应的微操作的控制信号发送给控制总线,作为整个大主机的控制信号。

需要说明的是,微指令里面不仅仅包括要之心干的微操作,还有下一条微指令的地址,下地址会被送入顺序逻辑器中,顺序逻辑器会自己判断使用微地址形成部件的地址还是 CMDR 送来的微地址,作为地址中转传入 CMAR 中,控制微程序的完整读取。

277.jpg

控制存储器

这里比较值得一说的就是控制存储器里面的结构,首先会将所有指令都会有的取值周期放到控制存储器的一个公共的部分,来减少存储占用。而组成指令的其他微程序则每个单独存储在一块中。

278.jpg

微指令

水平和垂直

水平型微指令:一次能够定义并执行多个并行操作。操作控制 + 顺序控制 微程序短,速度快。

垂直型微指令:微操作码决定微指令的功能。微操作码 + 目的地址 + 源地址 微指令短,速度慢。

水平微指令编码

我们直接讲字段直接编码方式,水平微指令组成是 操作控制 + 顺序控制,我们先来看操作控制。

这里讲操作控制部分分段,每段经过译码之后发出一个微操作控制信号,分了多少段就能同时执行多少个微操作。所以分段原则为:

279.jpg

(当然直接编码方式可以看图)

设计原理

设计原理如下图,具体的我也不会……

280.jpg

指令流水线

指令流水线设计概念

流水线的设计是通过将机器指令的执行过程拆分成多个步骤,然后将每个步骤错开运行,来保证最大的硬件使用率。

比如将机器指令周期拆分为:取指,解码,执行,定位,回写。这五个步骤所用位置是不一样的,就可以同时执行不同的指令。一些设计的细节可以看图:

281.jpg

流水线设计影响因素

资源冲突

指两个指令在同一时间争夺同一硬件资源导致的冲突。

解决方法:

  1. 后一指令运行暂停一个周期。
  2. 进行硬件分组,比如将指令和数据分别存储到不同的存储器中,两个周期访问的硬件资源分开,从而避免资源冲突。

数据冲突

即前一个指令的计算结果,是下一个指令所需要的内容。这就导致下一个指令的执行必须等上一个指令完整执行结束才可以进行。

解决方法:

  1. 硬件阻塞:发现这种情况的时候,就然下一条指令无限等待,直到上一条指令执行结束,数据能被访问到后再执行下一条指令。
  2. 软件插入 NOP:也就是编译器在编译代码的时候,就考虑这样的问题,在两个有数据冲突的指令之间,插入合适数量的不执行的空指令 NOP
  3. 数据旁路:将上一条指令执行出结果,但没存储的数据直接用旁路给下一条指令,不过这样电路设计就过于复杂了。
  4. 编译优化:编译器调整指令顺序,将两个数据冲突指令之间,插入不影响执行顺序的其他需要被执行的指令,尽可能利用资源。

控制冲突

由于控制相关的转移指令的存在,导致了流水线断流。

断流的解决方法就是尽快的将流接上,尽量不影响效率:

  1. 尽早判断转移是否发生,然后填入应该执行的指令到流水线里。
  2. 将转移和不转移两种情况的指令都放到流水线里。
  3. 用统计学统计转移概率,然后将概率大的指令放入流水线中。

多发技术

指令流水线的多发技术指的是:

超标量技术

通过一种元器件复制多份,从而在实现流水线的同时,每个流水线阶段又能同时执行多个指令。如下图:

282.jpg

这样的实现就需要对指令的顺序做一个优化,在编译程序的时候,将能够同时执行的指令放到一起。

超流水技术

在一个时钟周期之内,在细分多段,也就是能在同一个时钟周期,将一个部件功能同时使用多次。

283.jpg

超长指令字

由编译器分析一些可以同时执行的指令,然后将这些指令的执行阶段合并成一条超长的指令字,然后设计多个相同部件来同时执行它们。

284.jpg