From Nand To Tetris 从与非门到俄罗斯方块

9、P1 W1 U1.8 总结、作业1答案

2019-07-29  本文已影响0人  shazizm

视频:
如果本次课程对应的 Coursera 的视频打不开,可以点击下面链接
P1W1U1.8 - Perspectives

软件:
全课程所需软件项目包官方下载:
https://www.nand2tetris.org/software
备了一份软件项目包放在CSDN了,版本2.6支持Mac、Linux、Windows:
https://download.csdn.net/download/shazizm/11268147

本节课程实际上,是增加的答疑环节。我来用几句话总结完毕,然后写作业:

1.不光是用Nand可以完成“Hack小电脑”的制作,用其它也行,比如Nor。

2.区分一下电子工程和计算机科学的边界,课程不会去讨论逻辑门如何在物理上实现。

3.课程里的HDL是两位老师为简化学习,专门做教学目的。同学在工作上通常见到的是 Verilog,VHDL。

4.复杂的电路是如何设计的?搜索百度“IC设计专业”。





已知:

第一次作业,毕竟整个课程名叫NandtoTetris,所以一开始只有Nand能用。如下图


开始我们只有 Nand

下载 nand2tetris.zip

全课程所需软件项目包官方下载:
https://www.nand2tetris.org/software
备了一份软件项目包放在CSDN了,版本2.6支持Mac、Linux、Windows:
https://download.csdn.net/download/shazizm/11268147

启动 硬件模拟器

Windows用 HardwareSimulator.bat
下图是在Mac上启动

启动 Hardware Simulator

设计方法“三步转换”

老师推荐了一个设计方法和流程,回忆参考:
P1 W1 U1.4 硬件描述语言HDL

硬件模拟器 操作说明

写好硬件代码,如何用硬件模拟器调试,测试,对比结果,回忆参考:
P1 W1 U1.5 硬件模拟

1、Not

第一个Not 只能用Nand来设计。这个貌似没法用“三步转换”的方法。直接看着Nand的真值表发现其中包含一个Not真值表,貌似有思路了,准备工作环境。


红框内是个Not的真值表

1、写代码

我自己增加一个“作业”的目录,新建“1_Not”用来存放我的作业代码,新建一个文件叫 Not.hdl,用编辑器打开。

Hardware Simulator 硬件模拟器不能编辑Not.hdl。需要自己找个编辑器来写代码,如图用的VScode

代码可以自己设计,也可以直接采用老师提供的 逻辑门接口命名(下载包/nand2tetris/projects里)然后只设计逻辑部分,我这里采取老师的命名规则,以免之后不方便用老师提供的工具排查问题。

打开/nand2tetris/projects/01里的Not.hdl,复制其中提供的代码 到我们自己的/作业/1_Not/Not.dhl里。

在 代码 PARTS:下加入自己的思考

Nand(a=true,b=in,out=out);
//下面也都行
//Nand(a=in,b=true,out=out);
//Nand(a=in,b=in,out=out);

完整代码:

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Not.hdl

/**
 * Not gate:
 * out = not in 这里已经给出布尔函数,一般用三部转换推导出来,这个not貌似不能。
 */

CHIP Not { 
    IN in; // 接口名称
    OUT out; // 接口名称

    PARTS:
    // Put your code here: 自己的代码写在下面
    Nand(a=true,b=in,out=out);
}

2、测试
拷贝 /nand2tetris/projects/01 里的 \color{red}{Not.tst}\color{red}{Not.cmp} 。到/作业/1_Not里准备测试。

测试时会生成一个Not.out,此文件用来和Not.cmp做对比

测试结果如果没有报错,如上图 successfully 了,说明 作业写对了。可以进行下一个了。

2、And

1、真值表

先把逻辑门的符号,或者语言描述的功能等,归纳成真值表。

我们知道And 的真值表 如下图


2、三步转换
有了真值表,怎么转换成 布尔函数,回忆参考:P1 W1 U1.2 布尔函数

三步转换方法粗糙总结就是:找出真值表 out列等于 “1” 的行,a 等于 0就写 “Not(a)”, b 等于1 就写 “b”,ab用And连接。多行out等于1的,用Or连接。

如上图得 布尔函数:
这里需要布尔代数的操作再转成 只用 Not 和 Nand 的表示方式。回忆参考:P1 W1 U1.1 布尔逻辑

//只有最后一行out等于1,得:
a And b 
// 可是我们没有And,我们目前只有 Nand 和 Not,因为 布尔代数?布尔恒等式? a And b = Not(a Nand b),得:
Not(a Nand b)

布尔函数Not(a Nand b) 转 HDL 代码:

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/And.hdl

/**
 * And gate: 
 * out = 1 if (a == 1 and b == 1)
 *       0 otherwise
 */

CHIP And {
    IN a, b;
    OUT out;

    PARTS:
    // Put your code here:
    Nand(a=a,b=b,out=nandout);
    Not(in=nandout,out=out);
}

最后跟上一个Not的操作一样,用硬件模拟器测试,没有问题,OK。之后的都按此流程就能完成本周所有的作业。


测试 And 成功

3、Or

1、真值表



2、布尔函数(三步转换)

布尔代数,在 P1 W1 U1.1 布尔逻辑 这个教程里讲的并不全。在做转换的时候参考了下面网站(有自动简化工具 和 更全的布尔恒等式)。
http://electronics-course.com/boolean-algebra
(另一个最小化工具,如果上面的打不开)
http://tma.main.jp/logic/index_en.html

~(Not)、*(And)、+(Or)
//真值表里out等于“1”的行 用 Or 连接,得:
(Not(a) And b) Or (a And Not(b)) Or (a And b)  // 参考:[P1 W1 U1.2 布尔函数](https://www.jianshu.com/p/a7c784aa3224)
// 目前我们有 Nand、Not、And了。上行 进过 布尔恒等式 简化如下:
(Not(a) And b) Or  ( (a And Not(b)) Or (a And b) )
(Not(a) And b) Or  ( a And (Not(b) Or b) )
(Not(a) And b) Or a
a Or (Not(a) And b)
( a Or Not(a) ) And ( a Or b)
1 And (a Or b)
a Or b // 貌似绕了一大圈,获得了一个本来就知道的答案。。。也许只是验证三步转换法。。。
Not(Not(a Or b)) // 把 Or 用 Not 和 And 表示
Not( Not(a) And Not(b) )

布尔函数Not( Not(a) And Not(b) )转 HDL 代码:

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Or.hdl

 /**
 * Or gate:
 * out = 1 if (a == 1 or b == 1)
 *       0 otherwise
 */

CHIP Or {
    IN a, b;
    OUT out;

    PARTS:
    // Put your code here:
    Not(in = a,out = nota);
    Not(in = b,out = notb);
    And(a = nota, b = notb, out = andout);
    Not(in = andout, out = out);
}

最后 用 硬件模拟器,测试设计结果


现在有Nand、Not、And、Or了

4、Xor

0、描述
Xor 异或: 如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

1、真值表
根据描述:推出真值表

2、布尔函数

( Not(a) And b) Or ( a And Not(b) )  //貌似没法简化了

3、HDL

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Xor.hdl

/**
 * Exclusive-or gate:
 * out = not (a == b)
 */

CHIP Xor {
    IN a, b;
    OUT out;

    PARTS:
    // Put your code here:
    Not(in = a,out = notaout);
    Not(in = b,out = notbout);
    And(a = notaout ,b = b ,out = notaandbout);
    And(a = a ,b = notbout ,out = aandnotbout );
    Or(a = notaandbout, b = aandnotbout, out = out );
}

4、测试
硬件模拟器测试成功。

5、Mux

0、描述
Multiplexor(多路选择器)用 Mux 表示

sel 设置为0 时,out 输出 是 a 的内容。
sel 设置为1 时,out 输出 是 b 的内容。

1、真值表
根据描述:推出真值表


2、布尔函数

(a And ( Not(b) ) And Not(sel) ) Or 
(a And b And Not(sel) ) Or
(Not(a) And b And sel ) Or
(a And b And sel )

// 有时候打不开:http://electronics-course.com/boolean-algebra
//(a * ( ~b ) * (~sel) ) + 
//(a * b * (~sel) ) +
//((~a) * b * sel ) +
//(a * b * sel )

// 用另一个在线简化工具(推荐):http://tma.main.jp/logic/index_en.html
// (A(~B)(~C))+(AB(~C))+((~A)BC)+(ABC) => a~c + bc => a And Not(sel) Or b And sel
//优先级:()> not > and > or
( a And (Not sel) ) Or ( b And sel)

3、HDL

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Mux.hdl

/** 
 * Multiplexor:
 * out = a if sel == 0
 *       b otherwise
 */

CHIP Mux {
    IN a, b, sel;
    OUT out;

    PARTS:
    // Put your code here:
    Not( in = sel , out = notselout);
    And( a = a , b = notselout , out = aandnotselout);
    And( a = b, b = sel, out = aandselout);
    Or( a = aandnotselout, b = aandselout, out = out);
}

4、测试
硬件模拟器 测试成功

6、DMux

0、描述
Demultiplexor(反向多路选择器?)用 DMux 表示

当sel = 0 ,a = in ,b=0
当sel = 1 ,a = 0 , b =in
貌似功能和Mux 正相反。

这个图有点和之前的不一样,贴出来方便理解

1、真值表
根据描述:推出真值表


2、布尔函数
这个怎么用“三步转换” ?两个输出。。。

//貌似不用 Or 连接了,分别写两个

//a
in And Not(sel)

//b
in And sel

3、HDL

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/DMux.hdl

/**
 * Demultiplexor:
 * {a, b} = {in, 0} if sel == 0
 *          {0, in} if sel == 1
 */

CHIP DMux {
    IN in, sel;
    OUT a, b;

    PARTS:
    // Put your code here:
    Not(in=sel, out=nsel);
    And(a=in, b=nsel, out=a);
    And(a=in, b=sel, out=b);
}

4、测试
硬件模拟器 测试成功

7、Not16

这个可以理解为 16 个 Not ,Not16 能一次处理 16个输入同时进行Not逻辑运算。

1、HDL

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Not16.hdl

/**
 * 16-bit Not:
 * for i=0..15: out[i] = not in[i]
 */

CHIP Not16 {
    IN in[16];
    OUT out[16];

    PARTS:
    // Put your code here:
    Nand(a=in[0], b=in[0], out=out[0]);
    Nand(a=in[1], b=in[1], out=out[1]);
    Nand(a=in[2], b=in[2], out=out[2]);
    Nand(a=in[3], b=in[3], out=out[3]);
    Nand(a=in[4], b=in[4], out=out[4]);
    Nand(a=in[5], b=in[5], out=out[5]);
    Nand(a=in[6], b=in[6], out=out[6]);
    Nand(a=in[7], b=in[7], out=out[7]);
    Nand(a=in[8], b=in[8], out=out[8]);
    Nand(a=in[9], b=in[9], out=out[9]);
    Nand(a=in[10], b=in[10], out=out[10]);
    Nand(a=in[11], b=in[11], out=out[11]);
    Nand(a=in[12], b=in[12], out=out[12]);
    Nand(a=in[13], b=in[13], out=out[13]);
    Nand(a=in[14], b=in[14], out=out[14]);
    Nand(a=in[15], b=in[15], out=out[15]);
}

2、测试
硬件模拟器测试成功

8、And16

同理

1、HDL

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/And16.hdl

/**
 * 16-bit bitwise And:
 * for i = 0..15: out[i] = (a[i] and b[i])
 */

CHIP And16 {
    IN a[16], b[16];
    OUT out[16];

    PARTS:
    // Put your code here:
    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]);
}

2、测试
硬件模拟器测试成功

9、Or16

同理

1、HDL

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Or16.hdl

/**
 * 16-bit bitwise Or:
 * for i = 0..15 out[i] = (a[i] or b[i])
 */

CHIP Or16 {
    IN a[16], b[16];
    OUT out[16];

    PARTS:
    // Put your code here:
    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]);
}

2、测试
硬件模拟器测试成功

10、Mux16

同理
1、HDL

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Mux16.hdl

/**
 * 16-bit multiplexor: 
 * for i = 0..15 out[i] = a[i] if sel == 0 
 *                        b[i] if sel == 1
 */

CHIP Mux16 {
    IN a[16], b[16], sel;
    OUT out[16];

    PARTS:
    // Put your code here:
    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]);
}

2、测试
硬件模拟器测试成功

11、Or8Way

这个应该用在 满足 8种情况,有一种为true。输出就为true的情况

搞明白这个Or8Way,要先搞明白老师的命名规则,我推断是:
Or16:Or 的2way 16bit?(输入 a[16] ,b[16], 输出 out[16] )
Or8Way :Or 的 8way?1bit? (输入 in[8](可以看作 a,b,c,d,e,f,g,h), 输出out)
Or4Way16 :Or 的 4way? 16bit? (输入 a[16], b[16], c[16], d[16], 输出 out[16] ?)
Mux4Way16 : Mux 的 4way 16bit(输入 a[16], b[16], c[16], d[16], sel[2],输出 out[16] )

我分析这个逻辑门 应该用在 “有8种情况下,有一种为true。输出就为true”的情况

这里“三步转换”从老师提供的接口得知:
8-way Or gate: out = in[0] Or in[1] Or ... Or in[7].

利用 2 Associative Law 可以推导:
in[0] Or in[1] Or in[2] Or in[3] Or in[4] Or in[5] Or in[6] Or in[7]
( in[0] Or in[1] ) Or ( in[2] Or in[3] ) Or ( in[4] Or in[5] ) Or ( in[6] Or in[7] )
( ( in[0] Or in[1] ) Or ( in[2] Or in[3] ) ) Or ( ( in[4] Or in[5] ) Or ( in[6] Or in[7] ) )

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Or8Way.hdl

/**
 * 8-way Or gate: out = in[0] Or in[1] Or ... Or in[7].
 */

CHIP Or8Way {
    IN in[8];
    OUT out;

    PARTS:
    Or(a=in[0], b=in[1], out=c1);
    Or(a=in[2], b=in[3], out=c2);
    Or(a=in[4], b=in[5], out=c3);
    Or(a=in[6], b=in[7], out=c4);
    Or(a=c1, b=c2, out=c5);
    Or(a=c3, b=c4, out=c6);
    Or(a=c5, b=c6, out=out);
}

12、Mux4Way16

命名定义:
Mux4Way16 : Mux 的 4way 16bit(输入 a[16], b[16], c[16], d[16], sel[2],输出 out[16] )

我分析这个用在 “比如有 4路 16bit 输入,需要从中选择一种”的情况。

sel[2] = 00,01,10,11分别可以代表 4 路选择

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Mux4Way16.hdl

/**
 * 4-way 16-bit multiplexor.  
 * out = a if sel == 00
 *       b if sel == 01
 *       c if sel == 10
 *       d if sel == 11
 */


CHIP Mux4Way16 {


    IN a[16], b[16], c[16], d[16], sel[2];

    OUT out[16];

    PARTS:
    Mux16(a=a, b=b, sel=sel[0], out=c1);
    Mux16(a=c, b=d, sel=sel[0], out=c2);
    Mux16(a=c1, b=c2, sel=sel[1], out=out);
}

13、Mux8Way16

命名定义:
Mux8Way16 : Mux 的 8way 16bit(输入 a[16], b[16], c[16], d[16],e[16],f[16],g[16],h[16], sel[3],输出 out[16] )

我分析这个用在 “比如有 8路 16bit 输入,需要从中选择一种”的情况。

sel[3] = 000,001,010,011,100,101,110,111,分别可以代表 8 路选择

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/Mux8Way16.hdl

/**
 * 8-way 16-bit multiplexor.  
 * out = a if sel == 000
 *       b if sel == 001
 *       etc.
 *       h if sel == 111
 */


CHIP Mux8Way16 {
    IN a[16], b[16], c[16], d[16],
       e[16], f[16], g[16], h[16],
       sel[3];
    OUT out[16];

    PARTS:
    Mux4Way16(a=a, b=b, c=c, d=d, sel[0]=sel[0], sel[1]=sel[1], out=c1);
    Mux4Way16(a=e, b=f, c=g, d=h, sel[0]=sel[0], sel[1]=sel[1], out=c2);
    Mux16(a=c1, b=c2, sel=sel[2], out=out);
}

14、DMux4Way

这个东西,跟 Mux 是反正着的。估计用在跟Mux4Way 相反的作用上。

1bit “进” 4路选择后 1bit “出”

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/DMux4Way.hdl

/**
 * 4-way demultiplexor.  
 * {a,b,c,d} = {in,0,0,0} if sel == 00
 *             {0,in,0,0} if sel == 01
 *             {0,0,in,0} if sel == 10
 *             {0,0,0,in} if sel == 11
 */


CHIP DMux4Way {


    IN in, sel[2];

    OUT a, b, c, d;

    PARTS:
    DMux(in=in, sel=sel[1], a=c1, b=c2);
    DMux(in=c1, sel=sel[0], a=a, b=b);
    DMux(in=c2, sel=sel[0], a=c, b=d);
}

15、DMux8Way

1bit “进” 8路选择后 1bit “出”

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/01/DMux8Way.hdl

/**
 * 8-way demultiplexor.  
 * {a,b,c,d,e,f,g,h} = {in,0,0,0,0,0,0,0} if sel == 000
 *                     {0,in,0,0,0,0,0,0} if sel == 001
 *                     etc.
 *                     {0,0,0,0,0,0,0,in} if sel == 111
 */


CHIP DMux8Way {
    IN in, sel[3];
    OUT a, b, c, d, e, f, g, h;

    PARTS:
    DMux(in=in, sel=sel[2], a=c1, b=c2);
    DMux4Way(in=c1, sel[0]=sel[0], sel[1]=sel[1], a=a, b=b, c=c, d=d);
    DMux4Way(in=c2, sel[0]=sel[0], sel[1]=sel[1], a=e, b=f, c=g, d=h);
}
上一篇下一篇

猜你喜欢

热点阅读