08Implementation
Reverse the bytes of a word
Problem
Intended behavior. ByteSwap converts a 32-bit word between little-endian
and big-endian byte order. The least significant byte must move to the top and
the most significant byte to the bottom: 0x11223344 becomes 0x44332211.
Current behavior. The starter already views the word as four bytes through
asTypeOf(Vec(4, UInt(8.W))), but it packs the same Vec straight back, so
every word comes out unchanged.
Task. Keep the bytes view and change only the connection on the TODO
line so the bytes leave in reverse order. Keep both ports 32 bits.
Read the starter
Decide which byte of 0x11223344 sits in bytes(0). The bundles and vecs
chapter states where element 0 of a Vec lands when it is packed; the same rule
applies in reverse when asTypeOf unpacks a flat value into a Vec. Once you
know where bytes(0) comes from, you know where it must go.
Predict before running
The public run prints three words: 11223344, 000000ff, and deadbeef. Write
the swapped value of each before running, and confirm that the starter prints
each word unchanged.
Run and explain
A correct design prints 44332211, ff000000, and efbeadde. bytes(0) holds
0x44, the low byte; asUInt would put it back at the bottom, which is why the
starter is an identity. Reversal needs an ordering in which element 0 is placed
highest. Note that deadbeef reverses bytes, not characters: ef keeps its two
hex digits in order.
Completion check
- Byte 0 and byte 3 exchange places, and so do byte 1 and byte 2, for every 32-bit word.
- A single set bit anywhere in the input moves to the mirrored byte while keeping its position inside that byte.
- Swapping the two 16-bit halves is a different operation and does not count.
Progressive hints
Hint 1
Two packing rules point in opposite directions: asUInt on a Vec puts element
0 lowest, while Cat puts its first argument highest.
Hint 2
A Vec is also a Scala sequence during elaboration, so Scala collection methods
can rearrange its elements before VecInit turns them back into a hardware
Vec. Listing the four bytes explicitly in Cat, which needs
chisel3.util._, works as well.
Concept
asTypeOf and asUInt apply one fixed layout in both directions, so packing an
unpacked value without change is always an identity. Byte order is changed by
rearranging elements during elaboration; the rearrangement is pure wiring and
adds no logic.
Transfer experiment
Change the view in a scratch copy to Vec(2, UInt(16.W)) and apply the same
reversal. Predict the output for 11223344 and explain why the result is a
halfword swap rather than a byte swap.