본문으로 건너뛰기
code0.HDL

25구현 문제

16진 숫자를 ASCII 문자로 바꾸기

1. 요구 동작

HexChar는 4비트 digit을 소문자 16진 문자의 ASCII 코드로 바꿉니다.

digit문자코드
0~9'0'~'9'48~57
10~15'a'~'f'97~102

ascii는 조합 출력입니다. 클록 에지를 기다리지 않고 digit을 바로 따라갑니다.

2. 관찰되는 증상

0부터 9까지는 이미 맞습니다. 10부터 15까지는 시작 코드가 '9' 다음 코드를 계속 세어, ASCII 표에서 '9' 뒤에 오는 문장 부호를 출력합니다.

TODO 아래 줄을 고쳐 16개 숫자를 모두 올바르게 바꾸세요. 하드웨어는 HexChar에 있습니다. TracedHexChar는 같은 하드웨어에 printf만 추가한 클래스이고, 공개 실행은 이 클래스를 시뮬레이션합니다. TracedHexChar와 포트는 바꾸지 않습니다.

3. 실행 전 예측

printf는 신호 두 개를 형식 지정자 세 개로 출력합니다. digit은 16진수로, ascii는 문자와 10진수로 출력합니다. 공개 테스트벤치는 클록 step마다 숫자 0부터 15까지 하나씩 넣으며, 자체 출력은 없습니다. 출력되는 모든 줄은 회로가 만듭니다.

실행하기 전에 다음을 예측해 보세요.

  • 출력되는 줄 수. chiseltest가 먼저 수행하는 리셋 사이클에서도 한 줄이 출력되는지 판단해 보세요.
  • 올바른 변환기에서 digit= 열과 char= 열의 관계
  • 시작 코드에서 숫자 10의 char= 값. ASCII 표에서 9 다음 문자는 :입니다.

4. 원인 진단

올바른 변환기라면 모든 줄에서 %x가 출력한 16진 숫자와 %c가 출력한 문자가 같은 기호입니다. 두 열이 다른 줄이 아직 고쳐야 할 입력이고, code= 열은 각 입력이 기대값에서 얼마나 벗어났는지 보여 줍니다.

시작 코드는 모든 숫자에 '0'의 코드라는 offset 하나만 더합니다. ASCII에서 'a'는 '9' 바로 다음에 오지 않으므로 문자 범위에는 다른 offset이 필요합니다.

5. 완료 조건

  • 16개 숫자가 모두 올바른 코드를 출력합니다. 문자는 %x 출력과 같은 소문자 'a'~'f'입니다.
  • 두 범위의 경계가 정확합니다. 9는 '9', 10은 'a'가 됩니다.
  • 입력 순서와 관계없이, 숫자를 넣은 사이클에 바로 올바른 ascii가 나옵니다.

6. 힌트

힌트 1

숫자를 두 범위로 나누고 범위마다 시작 문자를 따로 정해 보세요. 출력에서 두 번째 범위가 처음 틀리는 줄을 이미 확인할 수 있습니다.

힌트 2

digit은 하드웨어 값입니다. 두 결과 중 하나를 고르려면 Scala if가 아니라 digit과 10의 비교를 조건으로 하는 하드웨어 선택이 필요합니다. 문자 범위에서는 숫자 10이 정확히 'a'의 코드가 되어야 합니다.

개념 설명

%c는 출력할 때만 숫자를 문자로 바꿉니다. 하드웨어가 전달하는 값은 8비트 코드일 뿐입니다. %x와 %c를 나란히 출력하면 리셋 중이 아닌 에지마다 두 기호를 직접 비교할 수 있어 기대 코드를 일일이 계산할 필요가 없습니다. 두 값의 일치를 자동으로 검사하지는 않으므로 출력은 직접 확인해야 합니다.

7. 추가 실험

문자를 대문자로 바꿔 보세요. 10부터 15까지의 새 code= 값을 예측하고, 대문자 기준으로는 맞는 변환기인데도 digit= 열과 char= 열이 더 이상 일치하지 않는 이유를 설명해 보세요.

개념 다시 보기
준비

CheerpJ로 브라우저에서 실행합니다. 첫 실행에는 Java 약 14.5 MB와 JAR 약 47 MB를 내려받습니다. 컴파일에 1분 정도 걸릴 수 있습니다. 라이선스

Main.scala