Posts 从零开始构建计算机chapter2_布尔运算
Post
Cancel

从零开始构建计算机chapter2_布尔运算

背景知识

二进制

十进制是以10为基底,二进制是以2为基底。 二进制加法本质上跟十进制加法是一样的, 只是要注意溢出问题。

补码

p1 取x的补码,最简单的方法就是,所有位取反,然后再加一。

  • 加法操作

(-2)+(-3) 可表示为 2 + 3 取反

  • x-y可以看作x+(-y)

规范详解

加法器

  • 半加器 两位加法 p5

    1
    2
    3
    4
    
      PARTS:
      // Put you code here:
      Xor(a = a, b = b, out = sum);
      And(a = a, b = b, out = carry);
    
  • 全加器 三位加法 p6

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    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:
      HalfAdder(a=a, b=b, sum=o1, carry=o2);
      HalfAdder(a=c, b=o1, sum=sum, carry=o3);
      Xor(a=o2, b=o3, out=carry);
    }
    
  • 加法器 n位加法 p7

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
        PARTS:
     // Put you code here:
      HalfAdder(a=a[0], b=b[0], sum=out[0], carry=o1);
      FullAdder(a=a[1], b=b[1], c=o1, sum=out[1], carry=o2);
      FullAdder(a=a[2], b=b[2], c=o2, sum=out[2], carry=o3);
      FullAdder(a=a[3], b=b[3], c=o3, sum=out[3], carry=o4);
      FullAdder(a=a[4], b=b[4], c=o4, sum=out[4], carry=o5);
      FullAdder(a=a[5], b=b[5], c=o5, sum=out[5], carry=o6);
      FullAdder(a=a[6], b=b[6], c=o6, sum=out[6], carry=o7);
      FullAdder(a=a[7], b=b[7], c=o7, sum=out[7], carry=o8);
      FullAdder(a=a[8], b=b[8], c=o8, sum=out[8], carry=o9);
      FullAdder(a=a[9], b=b[9], c=o9, sum=out[9], carry=o10);
      FullAdder(a=a[10], b=b[10], c=o10, sum=out[10], carry=o11);
      FullAdder(a=a[11], b=b[11], c=o11, sum=out[11], carry=o12);
      FullAdder(a=a[12], b=b[12], c=o12, sum=out[12], carry=o13);
      FullAdder(a=a[13], b=b[13], c=o13, sum=out[13], carry=o14);
      FullAdder(a=a[14], b=b[14], c=o14, sum=out[14], carry=o15);
      FullAdder(a=a[15], b=b[15], c=o15, sum=out[15], carry=o16);
      }
    
  • 增量器 对指定数字加一

    1
    2
    3
    4
    5
    6
    7
    8
    
    CHIP Inc16 {
      IN in[16];
      OUT out[16];
    
      PARTS:
      // Put you code here:
     Add16(a=in, b[0]=true,b[1..15]=false, out=out);
    }
    

算数逻辑单元ALU

p2

p3

p4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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:
    // zx
    Mux16(a=x, b=false, sel=zx, out=o1);

    // nx
    Not16(in=o1, out=o2);
    Mux16(a=o1, b=o2, sel=nx, out=o3);

    //zy
    Mux16(a=y, b=false, sel=zy, out=s1);

    //ny
    Not16(in=s1, out=s2);
    Mux16(a=s1, b=s2, sel=ny, out=s3);    

    // f
    Add16(a=o3, b=s3, out=f1);
    And16(a=o3, b=s3, out=f2);
    Mux16(a=f2, b=f1, sel=f, out=f3);

    // no 这里有两个输出值 注意一下。
    Not16(in=f3, out=no1);
    Mux16(a=f3, b=no1, sel=no, out=out ,out = no3);


    //zr
    Or16Way(in = no3, out = zr1);
    Not(in = zr1, out = zr);

    //ng
    IsNeg(in = no3, out = ng);
}


总结

  • And16 IN a[16], b[16]; OUT out[16]
  • DMux IN in, sel; OUT a, b;
  • DMux4Way IN in, sel[2]; OUT a, b, c, d
  • Mux16 IN a[16], b[16], sel; OUT out[16];
  • Mux4Way16 IN a[16], b[16], c[16], d[16], sel[2]; OUT out[16];
  • Or16 这个有点特殊 IN a[16], b[16]; OUT out[16]; // * for i = 0..15 out[i] = (a[i] or b[i])
  • Or8Way IN in[8]; OUT out;

怎么说呢,以Mux8Way16作为举例。16 始终代表输入的位数。8way则代表输入输出路数。

This post is licensed under CC BY 4.0 by the author.

Contents

Trending Tags