본문으로 건너뛰기
code0.HDL

12검증 문제

4비트 정수의 부호 확장하기

1. 부호 해석이 정해지는 시점 찾기

asSignedByte는 Bit#(4) 패턴을 같은 값의 Int#(8)로 반환해야 합니다. starter의 반환식은 안쪽부터 읽어 보세요. zeroExtend가 먼저 8비트 패턴을 만들고, unpack이 그 패턴을 Int#(8)로 해석합니다. mkTop의 입력 1101은 4비트 2의 보수에서 -3입니다.

실행하기 전에 현재 결과를 예측해 보세요. 코드는 컴파일되지만 실행은 -3이 아니라 양수 13을 표시합니다. 0 확장으로 새 최상위 비트가 0이 된 다음에 부호 있는 타입으로 해석하므로 값이 양수가 됩니다. 원래 3번 비트가 0인 입력은 정상처럼 보이고, 1인 입력만 잘못됩니다. 원인은 출력 형식이 아니라 변환 순서입니다.

수정 범위는 함수의 반환식입니다. package, 함수 시그니처와 mkTop은 변경하지 마세요.

2. 해석한 뒤 폭 확장하기

원래 네 비트를 먼저 Int#(4)로 해석해야 3번 비트가 부호 비트가 됩니다. 그다음 부호 있는 값의 폭을 늘려 새 상위 비트에 부호 비트를 복사합니다. 조건문, 수동 mask, 상태 소자는 필요하지 않습니다.

수정한 뒤 실행하면 1101이 8비트에서도 -3으로 표시되어야 합니다. 이 결과는 출력 서식이 아니라 8비트 2의 보수 표현 11111101이 만들어졌다는 뜻입니다. 이 근거를 직접 설명해 보세요.

3. 완료 조건

Int#(4)가 표현하는 전체 범위에서 값이 유지되어야 합니다.

  • 0000은 0이고 0111은 최댓값 7입니다.
  • 1000은 최솟값 -8입니다.
  • 1101처럼 0과 1이 섞인 음수 패턴은 같은 음숫값을 유지합니다.
  • 추가된 모든 상위 비트는 원래 부호 비트와 같습니다.

0111과 1000을 함께 검사하면 0 확장이 양수 예시에서만 통과하는 문제를 찾을 수 있습니다.

4. 단계형 힌트

힌트 1: 부호 타입

Bit#(4) 자체에는 부호 있는 수치 해석이 없습니다. 어떤 목적지 타입이 3번 비트를 부호로 해석해야 하는지 정해 보세요.

힌트 2: 두 동작 분리

비트 패턴을 바꾸지 않고 Int#(4)로 해석하는 동작과, 이미 부호가 정해진 값을 넓히는 동작을 분리하세요.

힌트 3: 연산 순서

값이 4비트일 때 unpack하고, 그 결과에 signExtend를 적용하세요. 두 연산의 순서를 바꾸지 않습니다.

5. 추가 실험

수정 전 순서를 잠시 복원하고 1000과 0111을 각각 실행해 보세요. 어느 입력만 오류를 드러낼지 먼저 예측합니다. 비교가 끝나면 올바른 순서로 복원하세요. 부호 경계 양쪽을 검사해야 하는 이유를 확인하는 실험입니다.

개념 다시 보기
준비
Main.bsv