Bob Playground


Welcome to Bob‘s blog.


实现 Y86 处理器 —— 需要的部件

从本篇起,我们将自己实现一个 Y86 处理器。

首先看一下为了实现 Y86 处理器,我们都需要哪些部件。

我们已经知道,CPU 会逐条地执行机器指令。那么 CPU 是如何判断正在执行的指令是否执行完毕,继而可以开始执行下一条指令的呢?

答案是:CPU 并不对此进行判断。

它采用固定的时长来执行每一条指令,CPU 能够保证各种指令均能在该时长内被执行完毕。

所以,每隔固定的时长 CPU 便开始执行下一条指令。

时钟

由于 CPU 采用了上述的机制执行指令,自然需要一个定时器,间隔固定时长周期性地通知 CPU 执行下一条指令。这个定时器被称为 时钟

一般采用矩形波状的电位变化来实现时钟。每当时钟变成高电位时,PC(程序计数器) 应该更新指令地址,继而执行下一条指令。

时钟信号

组合逻辑电路

  • 有的指令在执行时,需要对数据进行算数或逻辑运算。

    如 IA32 中的 addlorl 等指令。

  • 有的指令在执行时,需要将数据按照某种规则进行筛选。

    如在下面这段指令的第一句指令,CPU 即要从 0x80482910x8048296 中筛选出一个值。

    804828f: je 8048296
    8048291: call 80482b4
    

以上两种需求均可以概括为:将输入数据按照某种规则处理后输出结果

这两种需求,在 CPU 中均通过组合逻辑电路(简称组合电路)予以实现。

组合电路只是简单地根据输入信号和某种规则进行信号输出,不存储任何信息。

组合电路会在后文进一步介绍。

存储器

  • 有的指令在执行时,需要根据地址从寄存器文件或存储器中获取数据。

    这种操作和 组合逻辑电路 一节中所描述的需求很相近,即 将输入数据按照某种规则处理后输出结果

    即,从存储器中读取数据时,存储器的表现就像是一个组合电路。

  • 有的指令在执行完毕时,需要将结果保存在寄存器或存储器中。

    当时钟信号变为高电位时,当前指令已经执行完毕,此时即可将数据写入到存储器中。

    即,时钟信号控制着存储器的写入。

下面来看我们在 Y86 处理器中使用的两类存储器:

时钟寄存器和随机访问存储器。

时钟寄存器(简称寄存器)

时钟寄存器操作

时钟寄存器只存储单个位或字。

  1. 大多数时候,寄存器都保持在稳定状态(用 x 表示),产生的输出等于它保存的值。

    这是它的读状态,无论输入是什么,它都只会输出自身保存的值。

  2. 当时钟变成高电位时,输入值才被加载到寄存器中,并输出该值。

在 Y86 处理器中,会使用时钟寄存器来保存程序计数器(PC)、条件代码(CC)和程序状态(Stat)。

随机访问存储器(简称存储器)

随机访问存储器存储多个字,用地址来选择读或写哪个字。

比如虚拟存储器系统和寄存器文件。

下面来看一个典型的寄存器文件:

寄存器文件

它有两个读端口(A 和 B),和一个写端口(W)。

为什么读端口有两个而写端口只有一个呢?

看一下之前的 IA32 指令可以发现:任何指令,最多只会读取两个寄存器中的值,最多只会向一个寄存器中写入。

Y86 将要制定的指令与 IA32 相类似。

下面来看另外一个存储程序数据的存储器:

数据存储器

这个存储器只有一个地址接口。

这意味着在一个时钟周期内,要么进行读操作,要么进行写操作。

在 Y86 处理器中,使用随机访问存储器包括寄存器文件、指令存储器、程序数据存储器等。

小结

考察一个时钟周期的实质:

当时钟电压上升——即一个新的时钟周期开始后,“源头时钟寄存器”的输出(可能)会发生改变;

这里所说的“源头时钟寄存器”可初步认为是 PC,后文将会看到还有其他“源头”寄存器。

由此,会引发一系列的改变:

组合电路的输出会随着输入的改变而改变,存储器会因为读取地址的改变而改变输出值。

由源头时钟寄存器输出改变而引发的变动在 CPU 中不断向前传递。最终,CPU 中各个部件的输入输出都会稳定下来。

这时,CPU 就纯粹是在等待下一个时钟周期的到来了。