前言
Nand2Tetris是一个有趣的项目,教授了如何从门电路开始构建一个属于自己的俄罗斯方块小游戏。
以下记录了我在学习该项目过程中遇到的问题以及解决答案。
项目资源
链接: https://pan.baidu.com/s/1TM9M-lk4RCUYQZ4itaC5cQ?pwd=wwj7 提取码: wwj7
PS:资源是由我从其他地方淘来的,不对里面的任何其它链接负责。
基础门电路的构建
项目资源的具体使用办法在《计算机系统要素》内有所说明,这里不再赘述。
Nand门已经被项目实现,需要做的便是利用Nand门和以及实现过的门逐步实现下面的门电路。
1.Not
由于 x Nand x 的值恒和x 相反,显然易得:
Not x = x Nand x
PARTS:
Nand(a=in, b= true, out=out);
2. And
And 真值表和Nand 相反,显然易得:
X And Y = Not(X Nand Y)
PARTS:
Nand (a=a,b=b,out=xnandy);
Not (in=xnandy,out=out);
3.Or
反演律化简
X Or Y = Not(Not(X Or Y)) = Not(Not X And Not Y)
PARTS:
Not (in = a, out = nota);
Not (in = b, out = notb);
And (a = nota, b = notb,out =notaandnotb );
Not (in = notaandnotb, out=out);
4.Xor
异或门,X和Y在逻辑上是对称的,易得
X Xor Y = (X Or Y)And(Not(X) Or Not(Y))
PARTS:
Or (a = a, b = b, out = w1);
Not (in = a, out = nota);
Not (in = b, out = notb);
Or (a = nota, b = notb, out = w2);
And (a = w1, b = w2, out = out);
5.Multiplexor
双路选择器。当sel位为0时,输出a,sel位为1时,输出b。
Mux(a,b,sel)=(a And Not(sel)) Or (b And sel)
PARTS:
Not(in=sel,out=i);
And(a=a,b=i,out=j);
And(a=b,b=sel,out=k);
Or(a=j,b=k,out=out);
6.Dmultiplexor
双路数据分配器。当sel位为0时,输出位为a,b为0,sel位为1时,输出位为b,a为0。
PARTS:
Not(in=sel,out=i);
And(a=in,b=i,out=a);
And(a=in,b=sel,out=b);
7.Not16
16位Not门并联。
PARTS:
Not(in=in[0],out=out[0]);
Not(in=in[1],out=out[1]);
Not(in=in[2],out=out[2]);
Not(in=in[3],out=out[3]);
Not(in=in[4],out=out[4]);
Not(in=in[5],out=out[5]);
Not(in=in[6],out=out[6]);
Not(in=in[7],out=out[7]);
Not(in=in[8],out=out[8]);
Not(in=in[9],out=out[9]);
Not(in=in[10],out=out[10]);
Not(in=in[11],out=out[11]);
Not(in=in[12],out=out[12]);
Not(in=in[13],out=out[13]);
Not(in=in[14],out=out[14]);
Not(in=in[15],out=out[15]);
8.And16
16位And并联。
PARTS:
And(a=a[0],b=b[0],out=out[0]);
And(a=a[1],b=b[1],out=out[1]);
And(a=a[2],b=b[2],out=out[2]);
And(a=a[3],b=b[3],out=out[3]);
And(a=a[4],b=b[4],out=out[4]);
And(a=a[5],b=b[5],out=out[5]);
And(a=a[6],b=b[6],out=out[6]);
And(a=a[7],b=b[7],out=out[7]);
And(a=a[8],b=b[8],out=out[8]);
And(a=a[9],b=b[9],out=out[9]);
And(a=a[10],b=b[10],out=out[10]);
And(a=a[11],b=b[11],out=out[11]);
And(a=a[12],b=b[12],out=out[12]);
And(a=a[13],b=b[13],out=out[13]);
And(a=a[14],b=b[14],out=out[14]);
And(a=a[15],b=b[15],out=out[15]);
9.Or16
16位Or门并联。
PARTS:
Or(a=a[0],b=b[0],out=out[0]);
Or(a=a[1],b=b[1],out=out[1]);
Or(a=a[2],b=b[2],out=out[2]);
Or(a=a[3],b=b[3],out=out[3]);
Or(a=a[4],b=b[4],out=out[4]);
Or(a=a[5],b=b[5],out=out[5]);
Or(a=a[6],b=b[6],out=out[6]);
Or(a=a[7],b=b[7],out=out[7]);
Or(a=a[8],b=b[8],out=out[8]);
Or(a=a[9],b=b[9],out=out[9]);
Or(a=a[10],b=b[10],out=out[10]);
Or(a=a[11],b=b[11],out=out[11]);
Or(a=a[12],b=b[12],out=out[12]);
Or(a=a[13],b=b[13],out=out[13]);
Or(a=a[14],b=b[14],out=out[14]);
Or(a=a[15],b=b[15],out=out[15]);
10.Mux16
16位双路数据选择器并联。
PARTS:
Mux(a=a[0],b=b[0],sel=sel,out=out[0]);
Mux(a=a[1],b=b[1],sel=sel,out=out[1]);
Mux(a=a[2],b=b[2],sel=sel,out=out[2]);
Mux(a=a[3],b=b[3],sel=sel,out=out[3]);
Mux(a=a[4],b=b[4],sel=sel,out=out[4]);
Mux(a=a[5],b=b[5],sel=sel,out=out[5]);
Mux(a=a[6],b=b[6],sel=sel,out=out[6]);
Mux(a=a[7],b=b[7],sel=sel,out=out[7]);
Mux(a=a[8],b=b[8],sel=sel,out=out[8]);
Mux(a=a[9],b=b[9],sel=sel,out=out[9]);
Mux(a=a[10],b=b[10],sel=sel,out=out[10]);
Mux(a=a[11],b=b[11],sel=sel,out=out[11]);
Mux(a=a[12],b=b[12],sel=sel,out=out[12]);
Mux(a=a[13],b=b[13],sel=sel,out=out[13]);
Mux(a=a[14],b=b[14],sel=sel,out=out[14]);
Mux(a=a[15],b=b[15],sel=sel,out=out[15]);
11.Or8Way
输入一个8位的变量,如果其中有一个或更多个1,输出就为1,否则为0。
8个Or门串联,每下一个的输入是上一个的输出。
PARTS:
Or(a=in[0],b=in[1],out=i1);
Or(a=i1,b=in[2],out=i2);
Or(a=i2,b=in[3],out=i3);
Or(a=i3,b=in[4],out=i4);
Or(a=i4,b=in[5],out=i5);
Or(a=i5,b=in[6],out=i6);
Or(a=i6,b=in[7],out=out);
12.Mux4Way16
-
in: a[16] , b[16] , c[16] , d[16] , sel[2]
-
out: out[16]
-
func:
sel out 00 a 01 b 10 c 11 d
4路16位数据选择器。可以分为两组,a,b 和 c,d 。用两个双路数据选择器分别选择,然后再把输出端与第三个双路数据选择器相接,通过sel位的选择,即可控制4路数据的选择输出。
PARTS:
Mux16(a=a,b=b,sel=sel[0],out=amuxb);
Mux16(a=c,b=d,sel=sel[0],out=cmuxd);
Mux16(a=amuxb,b=cmuxd,sel=sel[1],out=out);
13.Mux8Way16
- in:a[16],b[16],c[16],d[16],e[16],f[16],g[16],h[16],sel[3]
- out:out[16]
- func: 同Mux4Way16表,不再赘述。
8路16位数据选择器。每4个为一组,则分为了两个4路16位数据选择器,最后再将输出接到一个16位数据选择器上,即实现了8路数据的选择输出。
PARTS:
Mux4Way16(a=a,b=b,c=c,d=d,sel=sel[0..1],out=abmux4Waycd);
Mux4Way16(a=e,b=f,c=g,d=h,sel=sel[0..1],out=efmux4Waygh);
Mux16(a=abmux4Waycd,b=efmux4Waygh,sel=sel[2],out=out);
14.DMux4Way
-
in: in , sel[2]
-
out: a , b , c , d
-
func:
sel a b c d 00 in 0 0 0 01 0 in 0 0 10 0 0 in 0 11 0 0 0 in
4路数据分配器,和数据选择器的构造逻辑相反,先用一个双路数据分配器分为两组数据,再用两个数据分配器分开形成4路。
PARTS:
DMux(in=in,sel=sel[1],a=i1,b=i2);
DMux(in=i1,sel=sel[0],a=a,b=b);
DMux(in=i2,sel=sel[0],a=c,b=d);
15.DMux8Way
8路数据分配器,func基本如上,构造方法便是把输入通过一个4路数据分配器分为4个,再接4个双路数据分配器。
PARTS:
DMux4Way(in=in,sel=sel[1..2],a=i1,b=i2,c=i3,d=i4);
DMux(in=i1,sel=sel[0],a=a,b=b);
DMux(in=i2,sel=sel[0],a=c,b=d);
DMux(in=i3,sel=sel[0],a=e,b=f);
DMux(in=i4,sel=sel[0],a=g,b=h);
总结
这是Nand2Tetris项目的第一节,实现了基本的门电路和一些简单的组合电路,下一节会通过组合已经实现过的门电路,实现一个简单的ALU单元。
引用
感谢