이것이 점프 투 공작소

NandToTetris-Hardware simulator / 조합 게이트 실습 (밑바닥부터 만드는 컴퓨팅 시스템) 본문

NandToTetris

NandToTetris-Hardware simulator / 조합 게이트 실습 (밑바닥부터 만드는 컴퓨팅 시스템)

겅겅겅 2024. 12. 19. 22:39

친구의 추천을 받아 '밑바닥부터 구현하는 컴퓨팅 시스템'책을 읽고있습니다.

직접 구현해보는 내용들이 좀 있이서,

공부 내용 정리 및 학습 목적으로 책에서 진행한 실습들을 포스팅해보려 합니다.

 

실습은 공식 사이트에서 Web IDE를 통해 진행하였습니다.

 

공식사이트 주소

https://www.nand2tetris.org/software

 

Software | nand2tetris

Two OS implementations are supplied: (i) a collection of eight .vm class files, written originally in Jack (just like Unix is written in C), and (ii) a faster implementation of all the OS services, embedded in the supplied VM Emulator.

www.nand2tetris.org

 

웹 IDE 주소

https://nand2tetris.github.io/web-ide/chip/

 

NAND2Tetris

 

nand2tetris.github.io

 

 

NandGate

NandToTetris에서 기초가 되는 NandGate의 진리표입니다.

NotGate

0이 들어오면 1, 1이 들어오면 0 을 출력하는 게이트입니다.

Not의 경우 NandGate를 그대로 활용하면 원하는 출력을 얻을 수 있습니다.

 

HDL의 PARTS 섹션에서는 하위 칩들을 사용해 논리를 구현하며, 핀에 신호를 전달하는 과정을 표현합니다.

Nand칩을 사용해 두 입력핀 a,b로부터 out이라는 신호를 생성 후 외부로 전달합니다.

CHIP Not {
    IN in;
    OUT out;

    PARTS:
    Nand(a= in, b= in, out=out);
}

 

AndGate

1과1이 들어올때는 1, 나머지는 0을 출력하는 AndGate입니다.

Nand과 앞서 만들어둔 Not을 활용하여 만들 수 있습니다.

Nand칩에서 aNandb라는 임시 내부 신호를 만들고 Nand의 출력핀 out이 신호를 Not칩으로 전달합니다.

CHIP And {
    IN a, b;
    OUT out;
    
    PARTS:
    Nand(a= a, b= b, out= NandAB); 
    Not(in= NandAB, out= out);
}

 

 

OrGate

a,b 둘중 하나라도 1이면 1을 출력합니다.

두 신호를 Not하고 각각 변경된 신호를 Nand 게이트에 전달합니다.

CHIP Or {
    IN a, b;
    OUT out;

    PARTS:
    Not(in=a, out=notA);
    Not(in=b, out=notB);
    Nand(a= notA, b=notB, out=out );
}

 

 

XorGate

두 입력값 중 하나만 1일 때 1을 나머지는 0을 반환합니다.

Not, And, Or을 활용해서 만들 수 있습니다.

CHIP Xor {
    IN a, b;
    OUT out;

    PARTS:
    Not(in=b, out=notB);
    Not(in=a, out=notA);
    And(a=a, b=notB, out=aAndNotB);
    And(a=notA, b=b, out=notAAndB);
    Or(a=aAndNotB, b=notAAndB, out=out);
}

 

멀티플렉서 (MUL, Selector)

a,b의 데이터 비트와 sel 선택비트 3가지 input을 가집니다.

a,b 중 sel에 의해 선택된 값을 out으로 내보냅니다.

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

    PARTS:
    Not(in=sel, out=NotSel);
    And(a=a, b=NotSel, out= aAndNotSel);
    And(a=b, b=sel, out= bAndSel);
    Or(a= aAndNotSel, b=bAndSel, out=out);
}

 

디멀티플렉서

멀티플렉서와 반대의 기능을 합니다.

in과 입력신호(sel)를 각각 하나씩 받아서 2개의 출력(a,b)으로 전달하는데, 입력신호(sel)가 0이면 a에 in을 1이면 b에 in을 전달합니다.

in이 전달되지 않는 신호에는 0을 전달합니다.

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

    PARTS:
    Not(in= sel, out=NotSel);
    And(a=in, b=NotSel , out=a);
    And(a=in , b=sel , out=b );
}

 

16BIT And, Or, Not, Mux

16비트 게이트들은 단순하게 앞에서 작업했던 And, Not, Or, Mux들을 각 비트에 맞게 16번씩 반복해주면 됩니다.

 

Or8Way (M입력 Or)

다입력되는 m개의 비트 중 적어도 하나가 1이면 1을 출력하는 게이트입니다.

들어오는 모든 bit를 순서대로 OR게이트로 비교하면 원하는 결과를 얻을 수 있습니다.

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

    PARTS:
    Or(a=in[0] , b=in[1] , out=out1 );
    Or(a=out1 , b=in[2] , out=out2 );
    Or(a=out2 , b=in[3] , out=out3 );
    Or(a=out3 , b=in[4] , out=out4 );
    Or(a=out4 , b=in[5] , out=out5 );
    Or(a=out5 , b=in[6] , out=out6 );
    Or(a=out6 , b=in[7] , out=out );
}

 

Mux4Way16 (M입력 N비트 멀티플렉서)

m개의 n비트 입력 중 하나를 선택해서 n비트 출력으로 전달합니다.

00이면 a, 01이면 b, 10이면 c, 11이면 d를 출력합니다.

참고로 2진수에서는 오른쪽이 하위 비트이기에 sel이 01이라면 sel[0]은 1, sel[1]은 0입니다.

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=aMuxb);
    Mux16(a=c, b=d, sel=sel[0] , out=cMuxd);
    Mux16(a=aMuxb , b=cMuxd , sel=sel[1] , out=out );    
}

 

Mux8Way16 (M입력 N비트 멀티플렉서)

Mux8Way16은 앞서 만들었던 Mux4Way16을 이용해서 구현할 수 있습니다.

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=sel[0..1] , out=abMuxCd);
    Mux4Way16(a=e , b=f , c=g , d=h , sel=sel[0..1] , out=efMuxGh);
    Mux16(a=abMuxCd , b=efMuxGh , sel=sel[2] , out=out);
}

 

DMux4Way (M입력 N비트 디멀티플렉서)

멀티플렉서와 반대의 기능을 합니다.

들어온 sel에 따라 a,b,c,d로 출력을 전달합니다.

CHIP DMux4Way {
    IN in, sel[2];
    OUT a, b, c, d;

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

 

DMux8Way (M입력 N비트 디멀티플렉서)

앞서 만들었던 DMux4Way를 활용해서 만들 수 있습니다

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

    PARTS:
    DMux(in=in, sel=sel[2], a=in1, b=in2);
    DMux4Way(in=in1, sel=sel[0..1], a=a, b=b, c=c, d=d);
    DMux4Way(in=in2, sel=sel[0..1], a=e, b=f, c=g, d=h);
}