15、P1 W2 U2.6 总结、作业2答案

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

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

常见问题:

  1. 第二周做的这些芯片(逻辑单元)是标准的吗?
    大部分是,但ALU是经过简化的。
  2. 为什么ALU没有设计更多的操作?
    优化为了至简,这样就能在硬件模拟器中实现。
  3. 这些芯片(逻辑单元)是高效的吗?
    大部分是。但比如加法器,就会有更优化的设计。
  4. 为什么建议每周先使用硬件模拟器里内建的芯片(逻辑单元)?
    方便定位每周的设计错误。

求:
HalfAdder
FullAdder
Add16
Inc16(自加1)
ALU




一、HalfAdder (半加器)

已知下图:
完成 HalfAdder.hdl


提示:可以用两个基础逻辑门组成

1、真值表
已知 Half Adder


2、布尔函数

两个输出 sum 、carry 。老师貌似没提怎么处理这种情况。和上周作业DMux类似,就写两个试试吧。

提醒:真值表转布尔函数,我总结了一个
假设输出是单项的,先看输出项(例如上图sum)有1的行。
在这行(例如上图第2行)看输入项为0加Not(例如上图2行的a项就写成Nota),多项输入间用And(Nota And b)。
多行输出有1的(例如上图第2行 和 第3行),用Or连接。
如果输出是多项的(sum 和 carry),自己写自己的。。。

//sum
 (Not(a) And b) Or ( a And Not(b) ) // 如果你不知道这是怎么来的,回忆一下上周作业吧


//carry
a And b

3、HDL

根据运算优先级:()> not > and > or 写硬件语言

// 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/02/HalfAdder.hdl

/**
 * Computes the sum of two bits.
 */

CHIP HalfAdder {
    IN a, b;    // 1-bit inputs
    OUT sum,    // Right bit of a + b 
        carry;  // Left bit of a + b

    PARTS:
    // Put you code here:
    Not(in = a, out = nota);
    Not(in = b, out = notb);
    And( a = nota, b = b, out = notaandb);
    And( a = a, b = notb , out = aandnotb);
    And( a = a , b = b, out = carry);
    Or(a = notaandb, b = aandnotb, out = sum);
}


4、测试
测试成功。

PS:第一周作业详情说了如何用 Hardware Simulator 硬件模拟器 进行测试。这里就贴一张图

Hardware_Simulator 本文最开始 软件处下载




二、FullAdder(带进位 全加器)

已知下图:
完成 FullAdder.hdl


提示:可以用两个半加器组成

1、真值表
已知 Full Adder

2、布尔函数

那上一个Half Adder 测试没问题。多输出(sum、carry)也可以按照机械的公式转换。

a、b、c 为输入
sum、carry 为输出

// sum
(Nota And Notb And c) Or
(Nota And b And Notc) Or
(a And Notb And Notc) Or
(a And b And c)
// 公式貌似东西有点多
// 转写成(~a)(~b)c + (~a)b(~c) + a(~b)(~c) + (abc)
// 用http://tma.main.jp/logic/index_en.html 简化一下。结果还是这个。。。HDL写起来就累一点了。

//  carry
(Nota And b And c) Or
(a And Notb And c) Or
(a And b And Notc) Or
(a And b And c)

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/02/FullAdder.hdl

/**
 * Computes the sum of three bits.
 */

CHIP FullAdder {
    IN a, b, c;  // 1-bit inputs
    OUT sum,     // Right bit of a + b + c
        carry;   // Left bit of a + b + c

    PARTS:
    // Put you code here:
    Not(in = a, out = nota);
    Not(in = b, out = notb);
    Not(in = c, out = notc);
    //挑几个sum和carry复用的And
    And(a = notb, b = c, out = notbc);
    And(a = a, b = notc, out = anotc); //
    And(a = b, b = notc, out = bnotc);
    And(a = nota, b = b, out = notab);
    And(a = a, b = b, out = ab);
    And(a = ab, b = c, out = abc);
    // sum
    And(a = nota, b = notbc, out = notanotbc);
    And(a = nota, b = bnotc, out = notabnotc);
    And(a = anotc, b = notb, out = anotbnotc);
    // carry
    And(a = notab, b = c , out = notabc);
    And(a = a, b = notbc , out = anotbc);
    And(a = a, b = bnotc , out = abnotc);
    // sum
    Or(a = notanotbc, b = notabnotc, out = or1);
    Or(a = anotbnotc, b =  abc, out = or2);
    Or(a = or1, b = or2,out = sum);
    // carry
    Or(a = notabc, b = anotbc, out = or3);
    Or(a = abnotc, b =  abc, out = or4);
    Or(a = or3, b = or4,out = carry);
}

4、测试
测试成功




三、Add16

已知下图:
完成 Add16.hdl

貌似很简单,这个参考 And16,Or16 之类的,就是考虑一下进位怎么搞。

提示:可以由16个全加器组成。进位可以一个接一个。最后的进位忽略。

1、真值表

2、布尔函数

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/02/Adder16.hdl

/**
 * Adds two 16-bit values.
 * The most significant carry bit is ignored.
 */

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

    PARTS:
   // Put you code here:
    FullAdder(c=false, a=a[0],  b=b[0],  sum=out[0],  carry=c0); //最低位没有进位
    FullAdder(c=c0,    a=a[1],  b=b[1],  sum=out[1],  carry=c1);
    FullAdder(c=c1,    a=a[2],  b=b[2],  sum=out[2],  carry=c2);
    FullAdder(c=c2,    a=a[3],  b=b[3],  sum=out[3],  carry=c3);
    FullAdder(c=c3,    a=a[4],  b=b[4],  sum=out[4],  carry=c4);
    FullAdder(c=c4,    a=a[5],  b=b[5],  sum=out[5],  carry=c5);
    FullAdder(c=c5,    a=a[6],  b=b[6],  sum=out[6],  carry=c6);
    FullAdder(c=c6,    a=a[7],  b=b[7],  sum=out[7],  carry=c7);
    FullAdder(c=c7,    a=a[8],  b=b[8],  sum=out[8],  carry=c8);
    FullAdder(c=c8,    a=a[9],  b=b[9],  sum=out[9],  carry=c9);
    FullAdder(c=c9,    a=a[10], b=b[10], sum=out[10], carry=c10);
    FullAdder(c=c10,   a=a[11], b=b[11], sum=out[11], carry=c11);
    FullAdder(c=c11,   a=a[12], b=b[12], sum=out[12], carry=c12);
    FullAdder(c=c12,   a=a[13], b=b[13], sum=out[13], carry=c13);
    FullAdder(c=c13,   a=a[14], b=b[14], sum=out[14], carry=c14);
    FullAdder(c=c14,   a=a[15], b=b[15], sum=out[15], carry=c15); //c15 一般就舍弃不考虑了
}

4、测试
测试成功




四、Inc16

已知下图:
完成 Inc16.hdl
注:这个本周貌似没有提到,应该是 一个 16bit的二进制数,加1。


提示:在HDL里 1位的0 或 1位的1,可以对应用 false 和 true 来代替。最后的进位忽略

1、真值表

2、布尔函数

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/02/Inc16.hdl

/**
 * 16-bit incrementer:
 * out = in + 1 (arithmetic addition)
 */

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

    PARTS:
   // Put you code here:
   Add16(a[0]=true, b=in, out=out);  //老师这里给了提示,1bit = true 就可以代表一个二进制 “1”。
}

4、测试
测试成功




五、ALU

在写ALU这个作业时,还是很有感慨的,小时候有许多好奇和“魔术”,在成长的过程中一一被破解,生活中“原来如此”的惊喜越来越少。
记得小时候第一次接触电脑的时候,就种了一个“好奇”的草。

叛逆
高中
姑娘
工作
辞职
喜悦
低谷
平静

时隔20年,也许只有当平静时,初心才有机会闪耀。

已知下图:
完成 ALU.hdl


提示:会用到Add16和第一周做的逻辑门组成。HDL的代码可以少于20行。

1、真值表

2、布尔函数

3、HDL

貌似 zx、nx、zy、ny、f、no 6个输入。有一个输出用来选择不同公式。(如下图),但这个选择貌似跟 之前的真值表不是一个意思,没用吧。不能推导用。


再思考下图的处理顺序:

X[16] 先要 zx 处理后,再nx 处理。
Y[16] 先要 zy 处理后,再 ny 处理。
X[16] 和 Y[16] ,再f处理。
最后f的输出,no再后处理一下。

先按上面顺序写个“伪代码”吧

//X 预处理
zx = true, outzx = false //置零
zx = false, outzx = X 
nx = true,  outnx = Not16(outzx) //取反
nx = false, outnx = outzx
//Y 预处理
zy = true, outzy = false
zy = false, outzy = Y 
ny = true,  outny = Not16(outzy)
ny = false, outny = outzy
// 选择 function
f = true,outf = outnx Add16 outny  //Add 运算
f = false,outf = outnx And16 outny // And 运算
// out 最后处理
no = true,out = Not16(outf) //取反
no = false, out = outf 

用来选择的,有Mux,仔细思考,上面的伪代码"X预处理"部分再进一步转化一下,看起来“真HDL”了

Mux16(a = X, b = false, sel = zx,out = outzx )
Not16(in = outzx, out = notoutzx)
Mux16(a = outzx, b =  notoutzx, sel = nx,out = outnx)

同理类似的都这么处理就行了。
另外有两个 zr 和 ng 输出标志位,需要琢磨搜索搜索。

“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/02/ALU.hdl

/**
 * The ALU (Arithmetic Logic Unit).
 * Computes one of the following functions:
 * x+y, x-y, y-x, 0, 1, -1, x, y, -x, -y, !x, !y,
 * x+1, y+1, x-1, y-1, x&y, x|y on two 16-bit inputs, 
 * according to 6 input bits denoted zx,nx,zy,ny,f,no.
 * In addition, the ALU computes two 1-bit outputs:
 * if the ALU output == 0, zr is set to 1; otherwise zr is set to 0;
 * if the ALU output < 0, ng is set to 1; otherwise ng is set to 0.
 */

// Implementation: the ALU logic manipulates the x and y inputs
// and operates on the resulting values, as follows:
// if (zx == 1) set x = 0        // 16-bit constant
// if (nx == 1) set x = !x       // bitwise not
// if (zy == 1) set y = 0        // 16-bit constant
// if (ny == 1) set y = !y       // bitwise not
// if (f == 1)  set out = x + y  // integer 2's complement addition
// if (f == 0)  set out = x & y  // bitwise and
// if (no == 1) set out = !out   // bitwise not
// if (out == 0) set zr = 1
// if (out < 0) set ng = 1

CHIP ALU {
    IN  
        x[16], y[16],  // 16-bit inputs        
        zx, // zero the x input?
        nx, // negate the x input?
        zy, // zero the y input?
        ny, // negate the y input?
        f,  // compute out = x + y (if 1) or x & y (if 0)
        no; // negate the out output?

    OUT 
        out[16], // 16-bit output
        zr, // 1 if (out == 0), 0 otherwise
        ng; // 1 if (out < 0),  0 otherwise

    PARTS:
    // Put you code here:
    // X预处理
    // X预处理
    Mux16(a = x, b = false, sel = zx, out = outzx);
    Not16(in = outzx, out = notoutzx);
    Mux16(a =  outzx, b = notoutzx, sel = nx, out = outnx);
    // Y预处理
    Mux16(a = y, b = false, sel = zy, out = outzy);
    Not16(in = outzy, out = notoutzy);
    Mux16(a =  outzy, b = notoutzy, sel = ny, out = outny);
    // 选择 function
    Add16(a = outnx, b = outny, out = outaddf);
    And16(a = outnx, b = outny, out = outandf);
    Mux16(a = outandf, b = outaddf,sel = f, out=outf);
    // no 后处理
    Not16(in = outf, out = notoutf);
    // 这里out的多种表达方式,老师有提到吗?
    // out[0..7] = outlow ... 出其不意的操作,不说谁知道啊?
    Mux16(a = outf, b = notoutf,sel = no, out=out, out[0..7]=outlow, out[8..15]=outhigh, out[15]=ng);
    
    // zr    outno = 0时,zr = 1
    Or8Way(in = outlow,out = outor8waylow);
    Or8Way(in = outhigh,out = outor8wayhigh);
    Or(a = outor8waylow,b = outor8wayhigh, out = nzr);
    Not(in = nzr,out = zr);

    //ng  outno < 0时,ng = 1
    //参考 https://www.jianshu.com/p/e15d757b1623 里观察,貌似out[15] 为1 就是负数。
 
}

4、测试
测试成功

太棒了,我们实现了CPU里最核心的部件了。不过别忘了我们是在老师已经设计好的蓝图下完成的。那蓝图又应该怎么思考得来呢?

下周就要进行存储相关的探索了,尤其软件程序的可存储化,在计算机历史上还是很重要的一个节点。标志着通用计算机的诞生。

另外 下周还会引入 时序逻辑。不准确、形象的解释一下就是之前两周学习的逻辑门电路,都是没有时序控制的。有点像“静”的。加入时序脉冲(电脑里常说的CPU频率就是在说明这个脉冲的快慢),特定的逻辑组合会有不同的特性,各个电路有了一个协调有序的节奏,这种在统一节奏下工作的逻辑电路,就叫时序电路了。时序的引入才使CPU“脉动”起来,不过遗憾的时,老师将这部分实现时序的电路省略了(可能无法用逻辑电路实现),在硬件模拟器里默认提供了。
换一种看法:如果我们到现在做好的ALU,比做一个静止机械的机器。那么只有通过引入脉冲来体现“时间”的流动,它才能看起来是运动的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • 视频:如果本次课程对应的 Coursera 的视频打不开,可以点击下面链接P1W2U2.5 - Project 2...
    shazizm阅读 1,119评论 0 1
  • 视频:如果本次课程对应的 Coursera 的视频打不开,可以点击下面链接P1W2U2.4 - Arithmeti...
    shazizm阅读 1,591评论 0 2
  • 现在是7月31日晚上9:16,我在这里写点东西吧! 再有100天就要再次面对消防考试了,这是我一生中最艰难的一次考...
    魏sir阅读 191评论 0 1
  • 冬天里的夜 夜与暗香一同爬上来, 撑起河床, 朦胧的月色一簇簇倾泻, 轻轻拾起又落下。 黑色里的念想, 星星点点,...
    汐颜张阅读 1,381评论 5 15