본문으로 건너뛰기
code0.HDL

28구현 문제

퍼센트 리터럴 정의하기

1. 문제와 수정 범위

Percent 타입의 크기 미지정 정수 리터럴은 정수 퍼센트를 뜻하고, 필드 basisPoints에는 퍼센트포인트의 10분의 1 단위로 저장됩니다. 이 문제의 배율은 1퍼센트포인트당 저장값 10입니다. 유효한 리터럴의 범위는 0부터 100까지이며, 두 끝값을 포함합니다.

주의. 기존 필드 이름과 출력에는 basis point라는 표현이 남아 있지만, 표준 베이시스 포인트는 1퍼센트포인트의 100분의 1입니다. 이름과 실행 코드는 유지하고, 이 문제에서 정한 10배 배율을 구현하세요. 표준 베이시스 포인트 변환과는 다릅니다.

starter의 Literal#(Percent) instance는 이 계약을 지키지 않습니다. fromInteger는 정수를 단위 변환 없이 그대로 저장하고, inLiteralRange는 10비트 필드가 표현할 수 있는 0부터 1023까지를 모두 허용합니다.

fromInteger와 inLiteralRange의 본문만 수정하세요. Percent 구조체, instance 선언, 10비트 필드, mkTop은 그대로 둡니다.

2. starter 읽기와 실행 전 예측

구조체, fromInteger, inLiteralRange, mkTop의 show 순서로 읽어 보세요. 구조체는 저장 단위를, fromInteger는 변환 규칙을, inLiteralRange는 허용할 리터럴을 정합니다. Percent sample = 37에서는 왼쪽 타입 선언이 크기 미지정 리터럴 37의 타입을 정합니다.

실행 전에 출력을 예측해 보세요. 컴파일은 성공하고 37퍼센트의 저장값이 37로 출력됩니다. 폭 오류가 아니라 단위 변환 오류입니다. 범위 함수는 101과 1023도 허용하지만, 공개 실행은 이 값을 쓰지 않으므로 출력에는 드러나지 않습니다.

3. 최소 수정과 완료 조건

표현 범위와 리터럴 범위는 서로 다른 계약입니다. UInt#(10)은 1000까지 저장할 수 있어 100퍼센트를 담기에 충분합니다. 그렇다고 남는 비트 패턴이 모두 유효한 퍼센트가 되지는 않습니다.

두 함수의 역할을 나누어 고치세요.

함수수정 후 동작
fromInteger정수 퍼센트에 단위 배율을 적용한 뒤 필드 타입으로 변환합니다
inLiteralRange배율을 적용하기 전의 정수 퍼센트가 0 이상 100 이하인지 판정합니다

주의. bsc는 리터럴을 컴파일할 때 사용자 정의 inLiteralRange를 호출하지 않습니다. 범위 검사가 컴파일 단계에서 자동으로 적용되는 것은 내장 타입뿐입니다. Percent의 범위 함수는 코드에서 직접 호출해야 효과가 있는 계약입니다.

수정한 뒤 실행에서 예시의 필드 값이 370으로 출력되어야 합니다. inLiteralRange는 0과 100에서 True, -1과 101에서 False를 반환해야 합니다. 37만 따로 처리하면 나머지 값에서 계약이 깨집니다. 수정이 끝나면 저장 단위와 소스 단위가 다른 이유를 한 문장으로 설명해 보세요.

4. 단계형 힌트

힌트 1: 두 함수의 역할 나누기

Percent 값을 반환하는 함수와 Bool을 반환하는 함수를 구분하세요. 범위 판정에 단위 변환을 섞지 않습니다.

힌트 2: 단위 따라가기

fromInteger의 인자는 elaboration 시점의 정수 퍼센트입니다. 필드 타입으로 바꾸기 전에 이 문제에서 정한 배율 10을 곱하세요.

힌트 3: 양쪽 끝값 검사하기

하한 비교와 상한 비교를 함께 쓰세요. 두 끝값은 포함하고, 바로 바깥의 정수는 제외합니다.

5. 추가 실험

수정을 마친 뒤 상한값 100으로 Percent 선언을 하나 더 추가하고, 저장될 필드 값을 예측해 보세요. 이어서 리터럴을 101로 바꾸고 다시 예측해 보세요. bsc가 사용자 정의 inLiteralRange를 리터럴에 적용하지 않으므로 빌드는 성공하고 저장값 1010이 저장됩니다. inLiteralRange를 100과 101로 직접 호출하는 $display를 잠시 추가하면 범위 함수가 101을 거부하는 것을 볼 수 있습니다. 확인한 뒤에는 mkTop을 원래대로 되돌리세요.

개념 다시 보기
준비
Main.bsv