본문으로 건너뛰기
code0.HDL

27검증 문제

직접 작성한 Bits 인스턴스 고치기

1. 문제와 수정 범위

unpack은 pack이 정한 프로토콜 코드를 거꾸로 되돌려야 합니다. 프로토콜은 Idle에 01, Start에 10, Stop에 11을 할당합니다. starter의 pack은 이 표를 따르지만, unpack은 다른 대응표를 사용합니다.

unpack 안의 디코딩 분기만 수정하세요. Command 선언, Bits#(Command, 2) instance 머리, pack, 보조 함수 두 개, mkTop은 그대로 둡니다.

Bits#(Command, 2)는 두 함수의 타입과 폭만 검사합니다. 두 분기표가 서로 맞는지는 검사하지 않으므로 starter는 컴파일됩니다. 잘못된 대응은 시뮬레이션에서 다른 명령이 출력되는 증상으로 드러납니다.

2. starter 읽기와 실행 전 예측

Command, instance 머리, pack, unpack, mkTop 순서로 읽어 보세요. pack의 세 분기를 enum label과 2비트 코드의 표로 적고, unpack의 분기를 같은 표에 겹쳐 적습니다. mkTop의 첫 출력은 인코딩 하나를, 두 번째 출력은 디코딩 하나를 보여 줍니다.

실행을 누르기 전에 두 출력을 예측해 보세요.

출력현재 결과요구 결과
Stop의 코드1111
01의 디코딩StartIdle

첫 출력은 이미 맞고 두 번째 출력만 틀립니다. instance를 찾지 못한 컴파일 오류가 아니라, 두 방향의 대응표가 어긋난 의미 오류입니다. 실행 결과로 이 예측을 확인해 보세요.

3. 최소 수정과 완료 조건

pack의 표를 기준으로 unpack의 분기만 역방향 표로 고치세요. 새 순서를 만들지 말고 기존 인코딩을 그대로 뒤집습니다. 수정을 마치면 다음 계약이 모두 성립해야 합니다.

  • 01, 10, 11은 각각 Idle, Start, Stop으로 디코딩됩니다.
  • 할당되지 않은 00은 Idle로 디코딩됩니다.
  • 세 명령 모두 unpack(pack(value)) == value가 성립합니다.
  • pack의 코드와 2비트 폭은 바뀌지 않습니다.

수정한 뒤 실행에서 Stop은 계속 11로, 01은 Idle로 출력되어야 합니다. 화면에 보이는 01 하나만 맞추어서는 완료가 아닙니다. 2비트 입력 네 개를 모두 표로 확인하세요. 00은 Idle로 정규화되므로, 디코딩한 값을 다시 pack하면 00이 아니라 01이 됩니다.

4. 단계형 힌트

힌트 1: 어긋난 계약 찾기

타입클래스는 변환 함수의 타입과 폭을 고정합니다. 프로토콜은 여기에 두 함수가 하나의 대응을 반대 방향으로 표현해야 한다는 조건을 더합니다. enum 선언 순서가 아니라 두 대응표를 비교해 보세요.

힌트 2: 수정 위치 좁히기

프로토콜과 충돌하는 곳은 unpack의 case뿐입니다. 할당된 세 코드를 먼저 각 명령과 연결하세요.

힌트 3: 미할당 코드 처리하기

2비트 코드 네 개 가운데 하나는 어느 명령에도 할당되지 않았습니다. 나머지 경우를 받는 분기가 이 코드를 맡아 요구된 안전한 값을 반환하게 하세요. 디코더에 맞춰 pack을 고치지는 않습니다.

5. 추가 실험

수정을 마친 뒤 mkTop이 디코딩하는 입력만 잠시 10으로 바꿔 보세요. Start가 출력될 것이라고 먼저 예측하고, 실행으로 확인한 뒤 입력을 01로 되돌리세요. 01만 예외로 처리한 수정과 대응표 전체를 고친 수정은 이 실험에서 결과가 갈립니다.

개념 다시 보기
준비
Main.bsv