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

作者: shazizm | 来源:发表于2019-07-29 10:18 被阅读0次

    视频:
    如果本次课程对应的 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);
    }
    

    相关文章

      网友评论

        本文标题:9、P1 W1 U1.8 总结、作业1答案

        本文链接:https://www.haomeiwen.com/subject/neoprctx.html