본문으로 건너뛰기
code0.HDL

13구현 문제

polymorphic 값을 pack하기

1. TODO보다 함수 시그니처 먼저 읽기

bitsOf의 인자 타입 t와 반환 폭 n은 정의할 때 고정되지 않습니다. Bits#(t, n) proviso가 타입 t의 표준 비트 표현과 폭 n을 연결합니다. starter는 시그니처, 수정 가능한 지역 값 encoded, 반환문, mkTop의 호출 순서로 읽어 보세요.

mkTop의 4비트 인자가 해당 호출의 t와 n을 결정합니다. 함수 본문은 그 타입의 Bits 인스턴스가 정한 표현을 그대로 반환해야 합니다. 실행하기 전에 ?로 둔 현재 결과를 예측해 보세요. ?는 정해진 값을 보장하지 않으므로 입력과 출력 사이에 관찰 가능한 관계가 생기지 않습니다.

수정 범위는 TODO가 있는 encoded 선언입니다. polymorphic 시그니처, proviso, 반환문, package와 mkTop은 그대로 두세요.

2. 타입별 분기 대신 proviso의 연산 사용하기

함수 본문에서 Bool, UInt, Bit을 각각 판별하면 polymorphic 계약이 깨집니다. Bits#(t, n)이 제공하는 연산 하나로 t 값을 Bit#(n)으로 바꾸세요. encoded의 선언 타입이 결과 폭을 검사하므로 고정 폭 중간 값은 필요하지 않습니다.

수정한 뒤 실행에서 예시의 네 비트가 보존되는지 확인하세요. 같은 정의가 다른 타입과 폭에도 적용되는 이유를 proviso와 각 호출의 타입 결정으로 설명할 수 있어야 합니다.

3. 완료 조건

각 타입의 Bits 인스턴스가 정한 비트가 모두 보존되어야 합니다.

  • False와 True는 각각 대응하는 1비트 표현을 반환합니다.
  • UInt#(3)은 같은 3비트 packed 패턴을 반환합니다.
  • Bit#(4)는 입력 네 비트를 그대로 반환합니다.
  • 함수 본문은 폭 4를 가정하거나 비트 보수를 만들지 않습니다.

4. 단계형 힌트

힌트 1: proviso의 계약

Bits#(t, n)은 사용할 연산과 결과 폭 관계를 함께 제공합니다. t에서 Bit#(n)으로 변환하는 연산을 찾아보세요.

힌트 2: 변환 방향

함수는 타입 t의 값으로 시작해 원시 비트를 반환합니다. 비트에서 값을 만드는 역방향 연산은 맞지 않습니다.

힌트 3: 지역 값만 완성

인자를 pack한 결과로 encoded를 초기화하세요. 타입 변수를 구체 타입으로 바꾸거나 반환문을 수정하지 않습니다.

5. 추가 실험

mkTop에 Bool 지역 값과 UInt#(3) 지역 값을 임시로 추가하고, 각각 bitsOf에 전달해 보세요. 컴파일하기 전에 두 반환 폭을 적어 봅니다. 실험이 끝나면 추가한 코드는 제거하세요. 함수 정의 하나가 각 호출에서 독립적으로 구체화되는지 확인하는 실험입니다.

개념 다시 보기
준비
Main.bsv