Endianness

Fall 2023

The questions below are due on Wednesday September 13, 2023; 11:59:00 PM.
 
You are not logged in.

Please Log In for full access to the web site.
Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.

As we start representing things that are more complicated than single bits we'll need a sensible way of ordering bits into larger structures. For instance, we could arrange 8 bits together as a byte. This leaves us with the choice of choosing which bit occupies the 1's place, the 2's place, the 4's place, and so on. We could make the rightmost bit occupy the 1's place, the next-rightmost bit occupy the 2's place, and so on - or we could reverse the order and use the leftmost bit for the same thing instead.

As a quick example, let's take the number 42, which we can represent in binary in one of two ways:

  • As 101010, where we have a 1 in the 32s place, a 0 in the 16's place, a 1 in the 8's place, and so on.
  • As 010101, where we have a 0 in the 1's place, a 1 in the 2's place, a 0 in the 4's place, and so on.

These are the same number - they're both 42 - but the order is reversed. In the first case, we're putting the Most Significant Bit first - for this number, that's the one in the 32's place. In the second case, we're putting the Least Significant Bit first - for this number, that's the one in the 1's place. These are called Big Endian and Little Endian ordering respectively, and using Big Endian to order bits is the default in the digital world. It's probably what you've seen before.

This idea extends to orderings of bytes as well. For instance, if we're trying to represent a 16-bit number on a system that can only take 8-bit bytes, we'll have to split it into two bytes, and choose an order to store them in. This works at the byte-level just like it does at the bit-level: big endian encoding stores the Most Significant Byte first, and little endian encoding stores the Least Significant Byte first.

Keeping this distinction in mind becomes especially important when sending information across interfaces. For example, serial (UART), USB, and Ethernet all use little endian at the bit level, so each byte has the LSB come first. Other protocols like I2C are big endian, and some (like SPI) can vary.

There's also plenty of 'mixed-endian' systems that don't use the same endianness at the bit level and byte level. For example, although Ethernet uses little endian at the bit level, it uses big endian at the byte level! So, a 16-bit value having the bits 0 to 15 (as LSB to MSB) will be transmitted by Ethernet as bit order: 8-9-10-11-12-13-14-15 - 0-1-2-3-4-5-6-7. See IEEE 802.3 Clauses 3.1.1, 3.2.6, and 3.3 for the gruesome details. Delightful.

For flexibility, let's write a module that can reorder the bits in a byte. Finish up the module below that takes the 8-bit data_in and flips the bit order based on the value of flip in order to produce data_out.