728x90

모든 코드는 깃허브에 있음을 알린다.

ALU

열심히 한 끝에 결국 2장의 마지막 끝판왕 ALU까지 오게 되었다.

아 이 ALU를 하려고 1장부터 몇번을 다시 봤는지 모르겠고,

기초를 차곡차곡 쌓는게 중요하다고 다시한번 느낀 그런 날이다.

이전 내용은 2장 불연산 앞부분 회고를 참고하면 되겠다.

일단 ALU는 산술논리연산장치 로서

덧셈, 뺄셈 같은 두 숫자의 산술연산과 배타적 논리합, 논리곱,

논리합 같은 논리연산을 계산하는 디지털 회로이다.

ALU는 CPU의 내부 구성 요소중 하나이며, 실제적인 연산을 담당하는 하드웨어 모듈이다.

컴퓨터시스템의 다른 부품들은 사실 ALU가 연산하기 위해 처리될

데이터를 가져오거나,

그 결과를 저장하기 위한 용도라고 해도 틀린 말이 아니다.

ALU는 구성이 산술, 그리고 논리로 되어있다.

산술

ALU는 덧셈만 있지 나눗셈, 곱셉은 존재하지 않는다.

곱셈은 그냥 * 5 해줄것을 5번 더해주는것으로 생각하고

나눗셈은 / 5 해주는 것을 5번 빼주는식으로 해주면 된다.

그래서 ALU는 덧셈으로 산술연산을 모두 처리할 수 있다.

논리

이 논리 연산으로 같은 값인지? 다른값인지 누가더 큰지 이런것을 비교하여 값을 받을 수가 있다.

회로도

조건식은

  • zx
    • if zx then x = 0
  • nx
    • if nx then x = !x
  • zy
    • if zy then y = 0
  • ny
    • if ny then y = !y
  • f
    • if f then out = x + y else out = x & y
  • no
    • if no then out = !out

이 셀렉터들의 조건이 있다.

그리고 아래는 회로도를 직접 그려본 것이다.

IMG_2742

처음에 위의 저 조건들은 당연히 이해를 했다.

그래서 아 이것도 쉽구나 하고 쭉 구현해보려고 했는데 문제가 있는 부분은

현재 그림으로 no 셀렉터 값을 가진 16비트 멀티플렉서 를 지나는 지점부터 이해가 잘 되지 않았다.

왜냐면 생각이 안들기 때문이었다. ㅋㅋㅋㅋㅋㅋ

그러니까 기초가 부족했던 탓이라고 생각했다. 😅

이제 출력값이 세개였는데

Output : 16비트 출력
zr : out = 0 일때 True 출력
ng : out < 0 일 때만 출력

이 세개가 왜 나와야하는지 그리고 저게 뭘 의미하는지 사실 잘 몰랐었다.

근데 2장을 앞부분으로 되돌아가면

16비트는 정상 출력을해주고

out이 0보다 작다는 소리는 맨 앞부분이 부호비트 라는 것을 생각해보면

아! 맨 앞 비트를 뽑아주면 되는구나!

까지 생각했다.

그래서 저 두개 부분은 금방 해결을 했다.

마지막 해결 부분

마지막 out = 0 일때 True 출력

이 부분은 사실 8개씩 나누어 두개의 Or8Way 를 사용하였다.

비트를 압축해야 하는데 자른 8개의 비트중에 하나라도 1이라면 그냥 1이 되게 되어있다.

그래서 no 라는 셀렉터가 값을 반전시키기 때문에 전부 0이 나올때만 1로 출력되게 해주어야 했다.

그래서 Or8Way로 비트를 2개로 압축한다. 이 결과를 다시 Or조건으로 넣으면

16비트 전부 0이 나오면 이제 그 0을 반대값으로 환산해서 모두가 0일때

참으로 나와주게끔 구현을 한 것이다.

아래는 nand2tetris의 코드이다.

CHIP ALU {
    IN  
        x[16], y[16],  // 16-bit 입력        
        zx,
        nx,
        zy,
        ny,
        f,
        no;

    OUT 
        out[16],
        zr,
        ng;

    PARTS:

    // zx, zy
    Mux16(a=x, b=false, sel=zx, out=o1);
    Mux16(a=y, b=false, sel=zy, out=o2);

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

    //ny
    Not16(in=o2, out=noto2);
    Mux16(a=o2, b=noto2, sel=ny, out=o4);

    // f연산
    And16(a=o3, b=o4, out=andxy);
    Add16(a=o3, b=o4, out=addxy);
    //add or and 정의해놓고 멀티플렉서로 선택함
    Mux16(a=andxy, b=addxy, sel=f, out=result);

    //no연산
    Not16(in=result, out=notresult);

    //위와 같이 not 구현해놓고 not연산에 해당하는 값을 멀티플렉서로 선택함
    Mux16(a=result, b=notresult, sel=no, out=out, out[0..7]=front, out[8..15]=back, out[15]=ng);

    Or8Way(in=front, out=frontout);
    Or8Way(in=back, out=backout);
    Or(a=frontout, b=backout, out=orout);
    Not(in=orout, out=zr);

}

결론

드디어 끝을 보니까 너무 후련했다.

위의 코드를 HardwareSimulator를 실행해서 테스트 케이스를 통과할 때의 그 기분은 느낀 사람만 알 것이다.

확실히 손으로 그려보고 딱딱 만들어 가는 과정이 나는 더 잘 맞는것 같다.

근데 이 고통을 겪어서 그런가 감히 다음장에 나오는 플립플롭, 레지스터에 도전하고 싶다.

728x90

'CS' 카테고리의 다른 글

Cache  (0) 2022.08.09
불 연산 회고  (0) 2022.08.09
불 논리 정리 2  (0) 2022.08.09
불 논리 회고  (0) 2022.08.07

+ Recent posts