Nand2Tetris - Week 3 依据基本原则构建现代计算机

Nand2Tetris - Week 3 依据基本原则构建现代计算机_第1张图片
week 3

第三周

介绍

这是啥?

这是一个由希伯来大学的 Shimon Schocken与 Noam Nisan讲授的课程。
教你从最简单的与非门实现计算机,并在计算机上实现操作系统,最后在构建的计算机上完成俄罗斯方块的制作。

官网主页:http://www.nand2tetris.org

Coursera课程主页:https://www.coursera.org/learn/build-a-computer

我将它的视频课程搬运到了B站,方便大家学习:https://space.bilibili.com/69824765/#/channel/detail?cid=56426

如果能科学上网的话,也可以在youtube搜索Nand2Tetris。

新的东西 - Time

从这一周开始,计算机引进了一个新的东西:时间。在电路中用时钟信号表现。

触发器 Flip Flop

触发器是一种可以存储电路状态的电子元件,所以存储器实现的基本单位就是触发器。

项目中已经实现了D触发器,可以像最开始使用Nand门那样实用D触发器(DFF)。

在讨论D触发器的真值表之前,先得搞清楚一个问题:

Conbinatorial Logic vs. Sequential Logic - 组合逻辑 vs. 时序逻辑

对于组合逻辑,它相当于一个函数f(x),输入x,输出f(x)。

但是对于时序逻辑,它的作用时是持续的,如果将1秒规定为一个逻辑处理时间单位,时序逻辑将不会更改这一秒的逻辑输出,而是会作用于下一秒的输出。

可以简单的看作:f(x - 1) = f(x)

因为它总是作用于下一个输出,所以我们永远不会知道第一个输出是多少,所以忽略第一个输出。

对于D触发器,时序图为:

Nand2Tetris - Week 3 依据基本原则构建现代计算机_第2张图片
D Flip Flop

当CP为1(严格讲应该是上升沿),Q(n+1) = D,当cp = 0,Q不变化。

项目中的DFF门接受一个输入in,一个输出out。设当前D触发器的值为A

in = 0时,out(t + 1) = A
in = 1时,out(t + 1) = Not(A)

OK,然后我们来实现最小的内存单位:Bit。

Bit

Bit有两个输入,一个为in,一个为load,一个输出out。

当load为1的时候,意思就是将Bit的值置为in。

load = 0时不更改。

其中一个与之前的门不一样的就是,我们需要把当前的out,传给下一个门的输入。然而时序电路就是为了允许这样的操作,所以实现如下:

Nand2Tetris - Week 3 依据基本原则构建现代计算机_第3张图片
Bit电路图

跟着它演绎一遍,即:

Mux(a=dffout, b=in, sel=load, out=muxout);
DFF(in=muxout, out=dffout);
Or(a=dffout, b=dffout, out=out);

可能你有两个问题:

  • Q1: 第一行的dffout是啥,凭空出现的?
    • dffout就是上一个门的输出值,在第二行的out=dffout也可以体现,它将dffout传给了下一个的输入。
  • Q2: 为什么不在第二行中out=out呢?
    • Q1回答中已经提到,它必须将out传出去,然后再输出值。所以第三行没有别的作用,只是为了输出out。

Register - 寄存器

此项目完成的是一个16位的计算机,所以寄存器实现为16位的。寄存器中存放16个Bit就好了。

Register芯片接受两个输入in和load,一个输出out。

功能类比Bit,当load = 1时,将寄存器的值置为in的值,否则不变。

实现如下:

Bit(in=in[0], load=load, out=out[0]);
Bit(in=in[1], load=load, out=out[1]);
Bit(in=in[2], load=load, out=out[2]);
Bit(in=in[3], load=load, out=out[3]);
Bit(in=in[4], load=load, out=out[4]);
... 以此类推

RAM8 - 8位随机存储器

这里的8位代表8个寄存器。这个芯片时用来管理8个寄存器,来修改/读取其中某个寄存器的值。

RAM8接受三个输入in,load,address,一个输出out。

其中in为16位(一个寄存器存储单位),load为0/1,address为3位(3位二进制能表示8个不同的值)。

in与load的作用不言而喻,address即用来指示in与load作用与哪一个寄存器。

使用DMux8Way16,根据load输出对应0-7对应的load(i),然后使用load(i),与in对Register(i)操作,输出对应的out(i)。

最后,使用Mux8Way16,传入out(i ~ 8),address,并最终输出out。

实现如下:

// 选出哪个Register将要被load
DMux8Way(in=load, sel=address, a=loada, b=loadb, c=loadc, d=loadd, e=loade, f=loadf, g=loadg, h=loadh);

Register(in=in, load=loada, out=outa);
Register(in=in, load=loadb, out=outb);
Register(in=in, load=loadc, out=outc);
Register(in=in, load=loadd, out=outd);
Register(in=in, load=loade, out=oute);
Register(in=in, load=loadf, out=outf);
Register(in=in, load=loadg, out=outg);
Register(in=in, load=loadh, out=outh);

// 选出哪个操作的输出将要被最终out
Mux8Way16(a=outa, b=outb, c=outc, d=outd, e=oute, f=outf, g=outg, h=outh, sel=address, out=out);

RAM64 - RAM512 - RAM4K - RAM16K

RAM64 = 8 * RAM8
RAM512 = 8 * RAM64
RAM4K = 8 * RAM512
RAM16K = 4 * RAM4K

芯片的输出都是三个in,load,address。在位数上,也只有address与RAM8不同,64个寄存器需要6位的address寻址,512个寄存器需要9位,以此类推。

在寻址上,我们需要分段,比如对于RAM64,由于其相当于8个RAM8,所以我们将6位的address拆分为两部分0-2与3-5。其中0-2用来寻找操作哪个RAM8,3-5的值只需传给RAM8即可。对于RAM512,也只需要0-2来选择RAM64,然后将3-8传给RAM64。对于RAM16K,其相当于4个RAM4K,所以只需要0-1来选择RAM4K。

这里只给出两个的实现:

RAM64

Nand2Tetris - Week 3 依据基本原则构建现代计算机_第4张图片
RAM64

RAM16K

Nand2Tetris - Week 3 依据基本原则构建现代计算机_第5张图片
RAM16K

PC

PC芯片是用来控制指令执行的。计算机总是取一条指令,然后计算,然后再取下一条指令,然后计算....

这里PC芯片用来给计算机指示吓一条指令的位置,芯片接受四个输入:in,load,inc,reset。

其逻辑为:

/**
 * if      (reset[t] == 1) out[t+1] = 0
 * else if (load[t] == 1)  out[t+1] = in[t]
 * else if (inc[t] == 1)   out[t+1] = out[t] + 1  (integer addition)
 * else                    out[t+1] = out[t]
 */

我的第一想法就是,这使用Mux就解决了呀~ (我真的太聪明了,快夸我。)

然后又思考了下,这是有优先级的,reset是最优先的,这是if-elseif-else,而不是switch。所以要倒着来:

在倒着来之前,先将上一次输出的值自增1保存下:Inc16(in=feedback, out=inced);

先用inc来选择是否改变out的值,然后再用load选择是否改变,在用reset选择是否重置。这样如果inc为1,load为1的情况下,inc虽然也改变了out,但是load又将它的更改覆盖了,也就有了优先级之说。

最后实现:

Nand2Tetris - Week 3 依据基本原则构建现代计算机_第6张图片
PC

完成

OK,这一周的芯片都完成了。从刚开始的时序逻辑电路到最后实现寄存器再到实现其他存储器,似乎构建的东西越来越接近计算机实体了。

我是谁?

我是iimT,大学生,技术宅,计算机科技爱好者,电音小王子。

我的博客:www.iimt.me

我在Weibo:@_iimT

我在B站:https://space.bilibili.com/69824765/#/

想看到我的更多更新的话,很乐意你关注我!

你是谁?

欢迎在文后留下评论,一起讨论,欢迎认识新朋友。

如果你也有博客,在分享你的东西,欢迎交流、友链(本人博客底部可申请)。

下一篇见~

你可能感兴趣的:(Nand2Tetris - Week 3 依据基本原则构建现代计算机)