Project 5: Computer
在本项目中我们将对之前完成的(并非)各个计算机组成部分进行整合、连接,最终制造成为一个可以运行的Hack计算机。
CPU
首先回归课程中的几个核心知识点。
首先需要明确的一点,也是我们操作的入手点,就是我们将要写的这种架构的CPU究竟能处理哪些类型的指令?显然我们可以处理A类型的指令和C类型的指令,A主要是涉及到向A-寄存器中存入数据,相对简单;而C主要是操控ALU进行一些运算,同时涉及一些向内存中的读写,以及对程序计数器的状态修改。
我一开始写CPU的时候迟迟无法下笔,就是因为没有搞清楚CPU实现的根本入手点,导致无法推测出图1中第一个$MUX16$的含义。
而如果搞明白这一点,我们就可以知道第一个$MUX16$的作用:让CPU知道自己处理的到底是A-instruction还是C-instruction。这需要我们读入机器指令的第15位作为Control bit。如果$c=0$,那么执行A-instruction,把instruction作为地址输出;反之则执行C-instruction。
这里的第二个难点是,执行C-instruction的时候,为什么要把 ALU output 传出去?
这里还涉及到对整个架构运行顺序的一点理解。在第一个时钟周期内,我们无法进行任何ALU的运算,因为我们没有在A或者D这两个寄存器中存入任何数据,而寄存器只有在下一个时钟周期的时候才会把它存储的值发射出去。
所以比如说我们想要让ALU运行一个指令。
|
|
它会被拆成两句话,第一句话是取数据地址,作为下一轮的inM。而此时PC++,新的instruction指令传入,但是它不是直接通过那张图里面显式画出的方式传到对应的ALU和PC里面的,而是通过一些未画出的线,以control bit(s)的身份传入其中的。
因此我们只需要按照图中的顺序,分别完成每个部分的传输即可。翻阅课程教材第2课和第4课的内容,找到对应的指令编码各个位置的含义即可。
|
|
自此,我们基本完成了一个CPU架构。这部分的设计精巧而复杂,值得反复品鉴。
Memory
和CPU相比,内存的实现就要简单很多很多了。
这个过程可以基本拆解为以下几步:
- 判断输入的数据是否应该被存入内存,应该被存入哪个内存。(这一部分我一开始出错了)
- 并行从RAM,SCREEN,KBD中分别获得output
- 使用MUX根据地址判断应该输出哪个部分的内存读取结果
这里还有一点需要我们注意,就是在硬件电路中我们虽然无法直接实现两个数比较大小,但是由于所有数字存在的形式都是二进制的格式,所以我们可以根据特定的二进制位进行比较。
比如本题,我们想比较address和$16384=2^{14}$,如果address比后者小的话,第15位应该是0,反之是1。这就为我们使用MUX16提供了一个很好的入手点。
|
|
Computer
按照此图直接无脑连接即可。
|
|
这一章Project的难度已经有了比较明显的提升,当然关键不是在于编程本身,而是在于理解整个电路进行各种运算的内在逻辑。在写这个Project之前我以为我已经很了解电脑内部的运行机制了,但是代码实现的时候我发现我只是知道了各个部分的作用,但是没有把它们串联成为一个整体,而这份Project很好地帮助我加深了对电脑内部体系结构的理解。