(밑바닥부터 만드는 컴퓨팅 시스템 2판, 인사이트(insight), 2023)을 학습하고 개인 학습용으로 정리한 내용입니다.
1. 목표 : 반가산기, 전가산기, 가산기, 증분기, ALU 구현
2. 구현 팁
- 1장에서 설명한 게이트들을 활용하면 만들 수 있다.
- project 01을 성공적으로 구현했더라도, 내장형 칩 사용을 권장한다. (내장형 칩을 사용하기 위해서는 project/02 경로에, project 01에서 만든 *.hdl 파일을 넣지 않으면 된다.)
- 이 장에서 나온 순서대로 구현한다. (반가신기 → 전가산기 → 가산기 → 증분기 → ALU)
3. 구현
- 반가산기 HalfAdder.hdl
in | out | ||
a | b | carry | sum |
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 0 |
sum(a,b)와 carry(a,b)의 출력이 특정 논리게이트와 동일하다.
// This file is part of http://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:
And(a=a, b=b, out=carry);
Xor(a=a, b=b, out=sum);
}
- 전가산기 FullAdder.hdl
a | b | c | carry | sum |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 0 | 1 |
0 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 0 | 1 |
1 | 0 | 1 | 1 | 0 |
1 | 1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 | 1 |
반가산기 2개와 기본 논리게이트 하나로 구현할 수 있다
// This file is part of http://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:
HalfAdder(a=a, b=b, carry=c1, sum=s1);
HalfAdder(a=c, b=s1, carry=c2, sum=sum);
Or(a=c1, b=c2, out=carry);
}
- 가산기 Add.hdl
0 | 1 | 0 | |||
1 | 0 | 1 | 1 | a | |
... | 0 | 0 | 1 | 0 | b |
... | 1 | 1 | 0 | 1 | out |
// This file is part of http://www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/02/Adder16.hdl
/**
* 16-bit adder: Adds two 16-bit two's complement values.
* The most significant carry bit is ignored.
*/
CHIP Add16 {
IN a[16], b[16];
OUT out[16];
PARTS:
HalfAdder(a=a[0], b=b[0], carry=c0, sum=out[0]);
FullAdder(a=a[1], b=b[1], c=c0, carry=c1, sum=out[1]);
FullAdder(a=a[2], b=b[2], c=c1, carry=c2, sum=out[2]);
FullAdder(a=a[3], b=b[3], c=c2, carry=c3, sum=out[3]);
FullAdder(a=a[4], b=b[4], c=c3, carry=c4, sum=out[4]);
FullAdder(a=a[5], b=b[5], c=c4, carry=c5, sum=out[5]);
FullAdder(a=a[6], b=b[6], c=c5, carry=c6, sum=out[6]);
FullAdder(a=a[7], b=b[7], c=c6, carry=c7, sum=out[7]);
FullAdder(a=a[8], b=b[8], c=c7, carry=c8, sum=out[8]);
FullAdder(a=a[9], b=b[9], c=c8, carry=c9, sum=out[9]);
FullAdder(a=a[10], b=b[10], c=c9, carry=c10, sum=out[10]);
FullAdder(a=a[11], b=b[11], c=c10, carry=c11, sum=out[11]);
FullAdder(a=a[12], b=b[12], c=c11, carry=c12, sum=out[12]);
FullAdder(a=a[13], b=b[13], c=c12, carry=c13, sum=out[13]);
FullAdder(a=a[14], b=b[14], c=c13, carry=c14, sum=out[14]);
FullAdder(a=a[15], b=b[15], c=c14, carry=c15, sum=out[15]);
}
- 증분기 inc16.hdl
+1을 어떻게 만들것인가 고민해야 한다.
// This file is part of http://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
*/
CHIP Inc16 {
IN in[16];
OUT out[16];
PARTS:
Not(in=in[0], out=n0);
Or(a=in[0], b=n0, out=p1);
HalfAdder(a=in[0], b=p1, sum=out[0], carry=c0);
FullAdder(a=in[1], b=c0, sum=out[1], carry=c1);
FullAdder(a=in[2], b=c1, sum=out[2], carry=c2);
FullAdder(a=in[3], b=c2, sum=out[3], carry=c3);
FullAdder(a=in[4], b=c3, sum=out[4], carry=c4);
FullAdder(a=in[5], b=c4, sum=out[5], carry=c5);
FullAdder(a=in[6], b=c5, sum=out[6], carry=c6);
FullAdder(a=in[7], b=c6, sum=out[7], carry=c7);
FullAdder(a=in[8], b=c7, sum=out[8], carry=c8);
FullAdder(a=in[9], b=c8, sum=out[9], carry=c9);
FullAdder(a=in[10], b=c9, sum=out[10], carry=c10);
FullAdder(a=in[11], b=c10, sum=out[11], carry=c11);
FullAdder(a=in[12], b=c11, sum=out[12], carry=c12);
FullAdder(a=in[13], b=c12, sum=out[13], carry=c13);
FullAdder(a=in[14], b=c13, sum=out[14], carry=c14);
FullAdder(a=in[15], b=c14, sum=out[15], carry=c15);
}
- 산술 논리 장치 ALU.hdl
왼쪽에서 오른쪽으로 연산을 수행한다. zx → nx → zy → ny → f → no → out (결과출력) | ||||||
x 입력이 미리 설정됨 | y 입력이 미리 설정됨 | + 또는 &, 계산 | 출력이 나중에 설정됨 |
ALU 출력 결과 |
||
if zx then x=0 | if nx then x=!x | if zy then y=0 | if ny then y=!y | if f then out=x+y else out=x&y |
if no then out=!out |
out(x, y) = |
zx | nx | zy | ny | f | no | out |
1 | 0 | 1 | 0 | 1 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 1 | 1 |
1 | 1 | 1 | 0 | 1 | 0 | -1 |
0 | 0 | 1 | 1 | 0 | 0 | x |
1 | 1 | 0 | 0 | 0 | 0 | y |
0 | 0 | 1 | 1 | 0 | 1 | !x |
1 | 1 | 0 | 0 | 0 | 1 | !y |
0 | 0 | 1 | 1 | 1 | 1 | -x |
1 | 1 | 0 | 0 | 1 | 1 | -y |
0 | 1 | 1 | 1 | 1 | 1 | x+1 |
1 | 1 | 0 | 1 | 1 | 1 | y+1 |
0 | 0 | 1 | 1 | 1 | 0 | x-1 |
1 | 1 | 0 | 0 | 1 | 0 | y-1 |
0 | 0 | 0 | 0 | 1 | 0 | x+y |
0 | 1 | 0 | 0 | 1 | 1 | x-y |
0 | 0 | 0 | 1 | 1 | 1 | y-x |
0 | 0 | 0 | 0 | 0 | 0 | x&y |
0 | 1 | 0 | 1 | 0 | 1 | x|y |
기본 논리 게이트를 이용해서 제어 비트 동작을 구현한다.
제어 비트는 순서대로 구현한다. ( zx → nx → zy → ny → f → no → out → zr/ng)
// This file is part of http://www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/02/ALU.hdl
/**
* ALU (Arithmetic Logic Unit):
* Computes out = one of the following functions:
* 0, 1, -1,
* x, y, !x, !y, -x, -y,
* x + 1, y + 1, x - 1, y - 1,
* x + y, x - y, y - x,
* x & y, x | y
* on the 16-bit inputs x, y,
* according to the input bits zx, nx, zy, ny, f, no.
* In addition, computes the output bits:
* zr = (out == 0, 1, 0)
* ng = (out < 0, 1, 0)
*/
// Implementation: Manipulates the x and y inputs
// and operates on the resulting values, as follows:
// if (zx == 1) sets x = 0 // 16-bit constant
// if (nx == 1) sets x = !x // bitwise not
// if (zy == 1) sets y = 0 // 16-bit constant
// if (ny == 1) sets y = !y // bitwise not
// if (f == 1) sets out = x + y // integer 2's complement addition
// if (f == 0) sets out = x & y // bitwise and
// if (no == 1) sets out = !out // bitwise not
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) or (out = x & y)?
no; // negate the out output?
OUT
out[16], // 16-bit output
zr, // (out == 0, 1, 0)
ng; // (out < 0, 1, 0)
PARTS:
//process zx
Mux16(a=x, b[0..15]=false, sel=zx, out=rzx);
//process nx
Not16(in=rzx, out=nrzx);
Mux16(a=rzx, b=nrzx, sel=nx, out=rx);
//process zy
Mux16(a=y, b[0..15]=false, sel=zy, out=rzy);
//process ny
Not16(in=rzy, out=nrzy);
Mux16(a=rzy, b=nrzy, sel=ny, out=ry);
//process f
Add16(a=rx, b=ry, out=xplusy);
And16(a=rx, b=ry, out=xny);
Mux16(a=xny, b=xplusy, sel=f, out=rf);
//process no
Not16(in=rf, out=nrf);
Mux16(a=rf, b=nrf, sel=no, out=out, out[15]=msb, out[0..7]=lo, out[8..15]=ho);
//for zr
Or8Way(in=lo, out=rlo);
Or8Way(in=ho, out=rho);
Or(a=rlo, b=rho, out=ro);
Mux(a=true, b=false, sel=ro, out=zr);
//for ng
Mux(a=false, b=true, sel=msb, out=ng);
}
'밑바닥부터 만드는 컴퓨팅 시스템 (Nand to Tetris)' 카테고리의 다른 글
[Chapter 3] 순차 칩 (Sequential Chip) (0) | 2024.02.15 |
---|---|
[Chapter 3] Memory (0) | 2024.02.14 |
[Chapter 2] 산술 논리 장지 (Arithmetic Logic Unit, ALU) (0) | 2024.02.09 |
[Chapter 2] 가산기 (0) | 2024.02.09 |
[Chapter 2] 불 연산 (Boolean Arithmetic) (0) | 2024.02.09 |