第五章 中央处理器(上)

包括CPU组成,如何工作的,数据通路是什么,如何组织,控制器是什么,由什么组成,异常和中断是什么,如何处理,指令流水线技术是什么。

CPU的组成和工作流程

CPU的功能

认识CPU的组成,需要先认识其功能,了解CPU的需求。

CPU会循环的执行指令,并且在这个过程中接受异常和中断请求并处理。

什么是中断和异常

中断是外设向CPU发出的信号,它试图改变程序正常执行的顺序。而异常是CPU内部给自己的信号,同样意在暂停现在的程序执行,而去执行一个特殊的处理程序,被称作事件处理程序,这样我们把中断和异常统称为事件。事件被处理完就可以返回暂停的程序继续执行了。

CPU具体来说分为控制的部件和用来执行指令的部件,因此我们把CPU的功能再分类一下。

控制部件:CPU执行指令的时候需要有个东西发信号说指令需要执行了,这就是操作控制,也就是产生指令执行所需的操作控制信号,并且具体什么时候发信号又得有部件控制,这是时间控制,也就是控制操作控制信号产生的时序。这里的信号就叫作控制信号。

执行部件:执行的时候就有不同的模块,分别有不同的功能了,比如控制指令的执行顺序的部件,执行指令中数据运算的部件,访问外设的部件,处理异常和中断的部件这几类。这些叫作CPU功能中的操作功能

总结一下,操作的实现就是功能部件实现操作功能,操作控制的部件发出给定的控制信号。

CPU的组成

基本部件

CPU的功能决定了CPU需要哪些部件。CPU需要操作和时间的控制信号(操作控制),因此就有时序信号形成电路、操作控制信号形成电路,这就是操作控制。CPU还有各种执行部件,需要操作功能,因此有对应指令控制的PC 、IR、ID(指令译码器),对应数据处理的ALU、FPU(运算),寄存器组、状态寄存器(存放),对应访问外部的总线逻辑电路、缓冲寄存器(内-外),MMU(地址变换),对应处理异常和中断的中断机构。

组成部件图

image-20251222021858565

先不用理解每个部件,我们回忆谈到的部件,它们都对应了CPU的需求,而这种需求我们可以分成两种,一种是控制,一种是处理。其中用来处理和执行的部件我们叫数据通路,而控制的部件就叫控制器。再回来看上图,其实控制器就是图中的CU,没有别的,而剩下的就是数据通路,毕竟数据通路是数据所经过的路径及路径上的部件,而控制器是进行指令译码并产生指令执行所需控制信号的部件

寄存器的组织

这里要提到寄存器是有分类的,上图中寄存器组里的寄存器和指令部件中的PC和IR显然不是一类人。一般来说,用户可见的寄存器,也就是说程序可以使用的寄存器一般是通用寄存器GPR和状态寄存器PSR,其中通用寄存器人如其名就是放数据和地址这些汇编中常用到的东西,而状态寄存器放的是程序运行状态,比如ZF这种结果标志,还有跟踪标志TF,中断允许标志IF这种执行标志。有时通用寄存器会特化成数据和地址寄存器两种,这样逻辑地址位数就不必等于机器字长了。专用寄存器则是PC,IR这种,还有MAR和MDR,这两个的作用就是前几章提过的取指阶段让PC就跳到下一条,因为取指阶段理论上PC的信号得是持续的,但我又想乐观的预判PC应该顺序的跳,那就得先把PC的值存到MAR里,让MAR去作取指的参考地址,然后取回来放到MDR里,最后才把MDR的值放到IR里。

CPU的工作流程

基本的,取指令,分析指令,执行指令,计算下一条指令地址。还有需要处理异常和中断。因此工作流程是循环地执行指令+响应中断/异常。

只有中断和异常的处理和返回时通过软件执行的(处理程序),其他的,比如指令执行的过程,异常和中断的检测(采样信号线),响应(保存断点等操作)都是由硬件执行的。

image-20251222025210111

这是加上中断和异常检测的CPU工作流程图,它分为指令周期中断周期

指令周期的组成

image-20251222025545822

指令周期细化就是上图,不必按图记,心中有数即可(能看懂图)

指令执行的特征

回忆指令执行有三步走,取指,译码,执行。我们想知道,哪些步骤是时序逻辑,哪些是组合逻辑电路呢?我们不妨把通过时序逻辑电路执行的叫做操作,也就是需要给定信号实现的功能。那么取指阶段需要多个操作,也就是多个取值,多个部件控制信号。毕竟取指确实需要一步步来。而译码阶段显然是组合逻辑电路,所以没有操作。而执行阶段也是多个操作。再想想,取指阶段是通用的,所有指令的路径相同,但执行阶段不同的指令由于功能不同,电路路径截然不同。

指令执行的过程

这里就贴几张PPT的图吧,RGL创造了他自己的一套demo_IS指令集架构,然后以这个为例做了几个汇编原子操作的示例

image-20251222031600860

image-20251222031641007

image-20251222031655149

image-20251222031707607

image-20251222031720543

这里提到一个$\mu OP$的概念,CPU内部最小的操作就是$\mu OP$了:

image-20251222033734403

这是四种$\mu OP$。而实现$\mu OP$自然要有操作控制的信号,这个叫做$\mu OPCmd$微操作命令。对于这种基本操作,我们要求源数据和结果都要放在时序部件中,保证它的独立性。以及这种基本操作要具有原子性(不可分成两步走)

指令周期的组织

我们之前都是在分析一个个的指令周期内的状态,但状态是静止的,如何在状态间转换,才是指令周期的状态机的重点。

首先我们这里说的操作都指的是时序逻辑电路,那就得有时钟,而操作的定时基准叫做主时钟。对于一个微操作($\mu OP$)来说,完成它的时间叫做一个节拍,这可能要几个时钟周期。对于一个指令来说,也是有可能一个时钟周期或者多个,分别对应单周期CPU和多周期CPU。

单周期CPU,顾名思义,它一个时钟周期就对应一个指令。这里的问题在于,不同指令执行的时间不一样,这是由于一条指令所包含的$OP$数是不一样的,那简单的指令就不得不也采取最长的指令要执行的时间,类似短板效应。这就是为什么一般来说都是多周期CPU,它的时钟周期只要是最大的基本$\mu OP$的长度就好了。

程序可以是串行的,也可以流水线并行,如下图:

image-20251222040155632

这样每个部件都不闲着。

数据通路的组织

数据通路的组成

功能部件

取指阶段的PC、IR、Adder(地址加法器)、IMEM(指令MEM)等,执行阶段的ALU、GPRs、PSR、DMEM(数据MEM)等。至于译码阶段由于是纯组合逻辑无操作所以被并入CU也就是控制器中了。顺带提一句数据MEM和指令MEM在冯诺依曼结构下是可以合并的,被一起放在储存系统中。

刚才指令执行过程的示例中已经有了数据通路部件组成示例,所以这里略去。

部件互连

对于总线结构,要求部件出端有三态门,入端有暂存器,使得一个$OP$内发送信号的部件只有一个,只有一个组合逻辑信号不被锁存(而是在接收总线上的信号)总线结构的特点就是同时仅传送一个数据,围绕这个目的设计总线上的部件。

特别注意的是,硬件拓扑结构是静态的、通用的,不管你现在想运行什么指令(无论是加法 ADD,还是取数 LOAD,还是跳转 JUMP),这些线就在那儿,不会断开,也不会凭空多出一根线。也就是数据连线无关于指令功能,指令功能的实现是靠控制信号的调度。

对于专用结构就比较简单,入端要有选择器,出端就没有要求了。而且数据连线基于指令功能,这一根根具体的线,完全是因为“指令集里有这个功能需求”,我才去拉的。如果指令集里没有“PC+立即数”的功能,我就绝对不会把 PC 和立即数生成部件连起来。专用结构的特点就是能同时传送多个数据。

总结

image-20251222111318853

数据通路的$\mu OP$及其控制

之前说过$\mu OP$的要求,源数据和结果都要放在时序部件中,保证它的独立性。以及这种基本操作要具有原子性(不可分成两步走)现在再来说它的种类,基本操作和特殊操作,特殊操作指的是信号的复位置位,比如PC+’1’。

$\mu OP$的实现方法同样是分成执行部件和控制部件。如图:

image-20251222111950099

至于这个$\mu OP$内部的事详见以下几个例子:

image-20251222114030966

image-20251222114046113

指令执行过程的组织

其实和上一节一样,都是在举例子,这回是完整的$\mu OP$序列

image-20251222115539305

image-20251222115603552

分别是总线结构和专用结构的

image-20251222115645409

数据通路的设计

设计基于需求,我们现在知道需求了,接下来就能够设计数据通路了。我们第一个要决定的事情就是要实现单周期CPU还是多周期CPU,他们两个有以下不同:

image-20251222120158571

设计一个单周期DP如下:

image-20251222135207785

这个设计要求时钟周期为最长的指令周期

image-20251222135657231

每个指令只有一种状态,取指和译码的时候不需要用$\mu OPCmd$

image-20251222135949284

多周期数据通路的设计

image-20251222145820119

增加了一些额外的寄存器。

每个指令周期会有状态转换。

image-20251222151059108

总结

数据通路就是负责服从CU指挥的部件,用来实现操作的。关注的部分有部件和互连两个方面,而具体的实现方法是通过$\mu OP$来控制,$\mu OP$有基本操作和特殊操作两种,它们接收$\mu OPCmd$来实现。一条指令的执行就是在执行$\mu OPCmd$序列

image-20251222151713485