ALU 구현 및 테스트
ALU
구현
- 6개의 제어 비트를 사용해야 한다. (zx, nx, zy, ny, f, no)
- 책에 나와 있는 힌트로는, 16비트 값을 0으로 만들거나 반전하는 논리 설계를 먼저 하라고 한다. ⇒ zx, zy, nx, ny, no가 우선적으로 설정되어야 한다.
- zx, zy 등을 만들기 위해서는 고급 프로그래밍 언어의 if와 같이 조건을 설정해야 한다.
하드웨어에서 조건을 만들려면 멀티플렉서를 사용한다.
예를 들어, zx 비트가 1이면 x입력을 0으로 만들고, 0이면 원래 x값을 사용할 수 있도록 한다.
- zx, zy 등을 만들기 위해서는 고급 프로그래밍 언어의 if와 같이 조건을 설정해야 한다.
- 그 다음으로는 f에 따라 + 연산과 And 연산을 선택하도록 하면 된다.
- 이 주요 6기능이 제대로 동작하는지 확인 후 zr과 ng 출력에 필요한 기능을 이어서 구현한다.
진리표
zx nx zy ny f no out(ALU의 출력 결과) 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 HDL
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, // if (out == 0) equals 1, else 0 ng; // if (out < 0) equals 1, else 0 PARTS: Mux16(a= x, b= false, sel= zx, out= xAfterZx); Not16(in= xAfterZx, out= negateX); Mux16(a=xAfterZx, b=negateX, sel=nx, out=xFinal); Mux16(a= y, b= false, sel= zy, out= yAfterZy); Not16(in= yAfterZy, out= negateY); Mux16(a=yAfterZy, b=negateY, sel=ny, out=yFinal); And16(a=xFinal, b=yFinal, out=andResult); Add16(a = xFinal, b = yFinal, out = addResult); Mux16(a= andResult, b= addResult, sel= f, out= fResult); Not16(in=fResult, out=notFResult); Mux16(a=fResult, b=notFResult, sel=no, out=out, out[0..7]=aluResultLow, out[8..15]=aluResultHigh, out[15]=ng); Or8Way(in=aluResultLow, out=or8waylow); Or8Way(in=aluResultHigh, out=or8wayhigh); Or(a=or8waylow, b=or8wayhigh, out=nzr); Not(in=nzr, out=zr); }
- zr 비트를 구하는 게 어려웠고 어려울 수 있다.
출력을 여러 개로 나누어서 우리가 가지고 있는 Or8Way 칩을 활용할 수 있도록 생각해내는 게 어려웠다. - ng 비트는 출력의 MSB를 확인하면 된다. (1이면 음수고 0이면 0이상의 정수인데, 정확히 ng비트의 역할과 똑같다.)
정리
앞서 가산기까지 구현한 것들은 효율성을 고려하지 않은 방식이었다.(그러나 가장 표준적이고 학습에 있어서 합리적인 접근 방식이었다.)
실제로 사용한 방법은 자리올림 비트가 n개 비트 덧셈에 전달되는 데 걸리는 지연 시간 때문에 효율적이지 않다.
자리올림수 예측(carry lookahead) 기법을 실행하는 논리 회로를 사용하면 속도를 올릴 수 있다.
덧셈은 컴퓨터에서 가장 많이 수행되는 연산이므로 이런 최적화가 전체 성능을 매우 끌어올릴 수 있다.
이 책에서 항상 말하듯이 이런 부분은 하드웨어를 전공하는 사람들에게 맡기는 걸로 하고 우리는 블랙박스처럼 원인과 결과만 잘 생각하자. (그래도 이런 게 있다 정도는 알면 좋을 것 같다.)
산술, 논리 연산을 하드웨어(ALU)로 처리할지, 소프트웨어(OS)에서 처리할지는 성능/비용 관점에서 바라볼 수 있다.
하드웨어가 좋은 성능을 가지지만 플랫폼 구현에 많은 비용이 들어가고, OS는 그 반대이다.
지금 나오고 있는 컴퓨터 시스템들은 이런 고민들을 석박사 선생님들께서 열심히 한 결과물이라고 볼 수 있다.
이 책에서의 절충안은 ALU의 기능을 최소화하고 추가적으로 필요한 수학 연산은 소프트웨어로 구현하는 것을 채택했다.
'개발 > 개발 공부' 카테고리의 다른 글
테스트 코드는 왜 작성하기 어려울까? (0) | 2025.05.31 |
---|---|
검색 구현을 위한 기초 공부 (0) | 2025.05.05 |
[밑바닥부터] 7일차 - 2장 불 연산: 가산기와 증분기 구현 (0) | 2025.04.13 |
[밑바닥부터] 6일차 - 2장 불 연산: 반가산기, 전가산기 구현 (0) | 2025.04.13 |
[밑바닥부터] 5일차 - 2장 불 연산: 가산기 아키텍처, ALU 설계 (0) | 2025.04.10 |