25Implementation
Turn a hex digit into its ASCII character
Problem
Intended behavior. HexChar converts a 4-bit digit into the ASCII code
of its lowercase hexadecimal character. Digits 0 to 9 become '0' to '9'
(codes 48 to 57), and 10 to 15 become 'a' to 'f' (codes 97 to 102).
ascii is combinational: it follows digit without waiting for a clock edge.
Current behavior. Digits 0 to 9 are already right. For 10 to 15 the
starter keeps counting past '9' and produces the punctuation characters that
follow it in the ASCII table.
Your task. Change the line under the TODO so that all sixteen digits map
correctly. The hardware lives in HexChar. TracedHexChar adds only a
printf to the same hardware, and the public run simulates it; keep that
class and the ports unchanged.
Read and predict
The printf reports two signals with three format specifiers: digit in hex,
ascii as a character, and ascii in decimal. The public bench pokes the
digits 0 to 15, one per clock step, and prints nothing itself. Every line of
output comes from the circuit.
Before running, predict:
- how many lines the run prints, and whether the reset cycle chiseltest runs first adds one;
- how the
digit=andchar=columns relate on every line of a correct converter; - what
char=shows for digit 10 in the starter, given that:follows9in the ASCII table.
Diagnose
For a correct converter, the hex digit printed by %x and the character
printed by %c are the same symbol on every line. The lines where they differ
are the inputs still to fix, and the code= column shows how far off each one
is. The starter adds one offset, the code of '0', to every digit. Letters
need a different offset, because 'a' does not come right after '9' in
ASCII.
Completion check
- All sixteen digits produce the right code, with lowercase
'a'to'f', matching what%xprints. - The boundary between the two ranges is exact: 9 still becomes
'9', and 10 becomes'a'. asciiis right in the same cycle the digit is applied, for inputs in any order.
Hints
Hint 1
Split the digits into two ranges and give each range its own starting character. The trace already shows the first line where the second range goes wrong.
Hint 2
digit is a hardware value, so the choice between the two results needs a
hardware selection on a comparison of digit with 10, not a Scala if. In
the letter range, digit 10 has to land exactly on the code of 'a'.
Concept
%c turns a number into a character only when it is printed. The hardware
carries plain 8-bit codes. Printing %x next to %c lets you compare the
symbols on every non-reset edge without working out each expected code by
hand. The trace does not assert that they match; you must inspect it.
Variation
Make the letters uppercase. Predict the new code= values for 10 to 15, and
explain why the digit= and char= columns stop matching even though the
converter is now correct for uppercase.