본문으로 건너뛰기
code0.HDL

51검증 문제

부호 있는 값의 비트 보존하기

1. 문제와 수정 범위

mkSignedAdapter.encode는 Int#(32)를 받아 signedCarrier(value)를 foreignSignedBits에 넘깁니다. 이 외부 함수 선언은 부호 없는 32비트 carrier를 씁니다. C 쪽이 부호를 직접 해석하려면 값의 2의 보수 비트 패턴 전체를 받아야 합니다. 그런데 수정할 수 있는 signedCarrier가 0을 반환하므로 공개 실행은 -7에 대해 carrier = 00000000을 출력합니다.

signedCarrier의 본문만 수정하세요. Int#(32) 입력 타입, Bit#(32) 반환 타입, adapter, 외부 함수 선언, mkTop은 그대로 둡니다.

2. starter 읽기와 실행 전 예측

  1. signedCarrier의 본문보다 타입을 먼저 읽어 보세요. 입력 타입에는 부호 의미가 있고, 반환 타입은 폭이 같은 비트 벡터입니다.
  2. 결과가 foreignSignedBits로 가는 경로를 따라가 보세요. 기본 실행에서는 같은 시그니처로 인자를 그대로 반환하는 BSV 대역 함수가 쓰이므로, C 경계를 넘을 값이 그대로 출력됩니다.
  3. 실행 전에 -7의 32비트 2의 보수 패턴을 16진수로 적어 보세요. starter의 출력과 고친 뒤의 출력을 예측해 보세요.

3. 최소 수정과 완료 조건

이 변환은 계산이 아니라 표현의 변경입니다. 부호 반전, 절댓값, 확장은 필요하지 않습니다. 두 타입이 모두 32비트이므로 모든 비트가 그대로 carrier에 도착해야 합니다. 반환 식만 바꾼 뒤 다시 실행하고, carrier 타입에 부호가 없는데도 부호 비트가 남는 이유를 설명해 보세요.

  • 모든 Int#(32) 값에서 carrier는 그 값을 pack한 비트와 같습니다.
  • 음수, 0, 양수 모두 부호 비트를 포함한 모든 비트를 유지합니다.
  • 함수 타입과 외부 함수 선언은 바뀌지 않습니다.
  • 화면의 -7만 따로 처리하면 다른 입력에서 실패합니다.

4. 단계형 힌트

힌트 1: 의미와 비트 구분하기

C carrier에는 부호가 없지만 BSV 입력 타입에는 부호 의미가 남아 있습니다. 경계는 비트만 넘기고, 받는 쪽이 의미를 다시 붙입니다.

힌트 2: 쓸 변환

산술 연산 없이 타입 있는 값을 Bits 표현으로 변환하세요. 두 타입의 폭이 같으므로 폭 변환은 필요하지 않습니다.

5. 추가 실험

공개 입력을 바꾸기 전에 -1, 0, 1의 carrier를 예측해 보세요. 그중 하나로 입력을 바꾸어 실행한 뒤 -7로 되돌리세요. 부호 해석과 비트 전달이 어디서 나뉘는지 확인하는 실험입니다.

개념 다시 보기
준비
Main.bsv