Altifigence Academy

3 / 24 · 실습

실습: 8비트 ALU의 기준 모델

독립 실행 파일로 ADD, SUB, AND, XOR와 carry·borrow 경계를 검증합니다.

숫자 계약을 실행 가능한 검사로 바꾸기

이 실습에서는 조합 ALU의 기능을 JavaScript 정수 모델로 작성합니다. 입력은 0~255와 op=0~3만 사용합니다. 모델이 출력하는 y는 항상 0~255이며 flag는 ADD carry 또는 SUB borrow입니다. 논리 연산의 flag는 0으로 정의합니다. 특히 borrow는 a가 b보다 작을 때 1이라는 이번 인터페이스의 약속입니다. 어떤 프로세서의 carry 플래그가 반대 의미를 쓸 수 있으므로 다른 장치의 규칙을 그대로 가져오지 않습니다.

로컬 폴더 또는 Digital Design Studio에서 빈 프로젝트를 수동으로 만든 뒤 alu-model.mjs 파일을 추가하고 아래 내용을 복사하여 저장하세요. Node.js가 설치된 터미널에서 그 파일이 있는 폴더로 이동하고 node alu-model.mjs를 실행합니다. DDS에서 파일을 편집하는 것과 JavaScript를 실행하는 것은 별도 동작입니다. 여기서는 특정 메뉴나 자동 가져오기 기능을 전제로 하지 않습니다. 아래 파일은 표준 Node 모듈만 사용하므로 패키지 설치가 필요 없습니다.

javascript
import assert from 'node:assert/strict';
function alu(a, b, op) {
  if (op === 0) {
    const wide = a + b;
    return { y: wide & 255, flag: Number(wide > 255) };
  }
  if (op === 1) return { y: (a - b) & 255, flag: Number(a < b) };
  if (op === 2) return { y: a & b, flag: 0 };
  if (op === 3) return { y: a ^ b, flag: 0 };
  throw new RangeError('operation');
}
assert.deepEqual(alu(250, 10, 0), { y: 4, flag: 1 });
assert.deepEqual(alu(3, 5, 1), { y: 254, flag: 1 });
assert.deepEqual(alu(170, 204, 2), { y: 136, flag: 0 });
assert.deepEqual(alu(170, 204, 3), { y: 102, flag: 0 });
let checks = 0;
for (let a = 0; a < 256; a++) {
  for (let b = 0; b < 256; b++) {
    const add = alu(a, b, 0), sub = alu(a, b, 1);
    assert.equal(add.y + 256 * add.flag, a + b);
    assert.equal(sub.y - 256 * sub.flag, a - b);
    assert.equal(alu(a, b, 2).y | alu(a, b, 3).y, a | b);
    checks += 3;
  }
}
console.log(`ALU PASS: ${checks} identities`);

250+10은 260이므로 y=4와 carry=1로 복원됩니다. 3-5는 -2이므로 y=254와 borrow=1로 원래 차를 복원합니다. AND와 XOR 예제의 170은 10101010, 204는 11001100이므로 겹치는 비트는 10001000=136, 서로 다른 비트는 01100110=102입니다. 위 반복문은 65536개의 입력 쌍마다 합·차 복원과 논리 항등식 세 가지를 검사합니다. 정상 종료 메시지는 196608개의 항등식 검사가 통과했다는 뜻입니다.

수치 모델과 RTL은 구현 방식을 다르게 잡아야 실수를 함께 복사할 가능성이 줄어듭니다. 예를 들어 RTL이 9비트 가산기로 carry를 구한다면 모델은 넓은 정수의 범위 비교를 사용합니다. 그래도 이 검사는 HDL의 X/Z, 합성된 회로의 타이밍이나 클록 처리를 검사하지 않습니다. 이후 실제 ALU를 만들면 같은 입력 벡터를 HDL 테스트벤치에도 넣고 결과를 비교하세요. flag를 검증하지 않고 y만 비교하면 순환 결과는 맞는데 범위 정보가 틀린 오류를 놓칩니다.

직접 생각해 보기

SUB의 flag를 0으로 고정하는 오류를 넣으면 가장 먼저 어떤 수치 관계가 실패할까요? a=0, b=1로 손으로 확인하고 원래 구현으로 되돌리세요.

해설 보기

y는 255인데 flag=0이면 y-256×flag=255입니다. 실제 0-1=-1과 다르므로 차 복원 검사가 실패합니다. borrow=1이면 255-256=-1이 되어 맞습니다. 데이터 y만 검사했다면 이 오류를 발견하지 못합니다.

실습 파일

alu-model.mjs ↓

선택은 이 브라우저에만 적용됩니다. 언제든 푸터에서 변경할 수 있습니다.