Sign in

Learn

Practice

Binary and Hexadecimal

In software, a value lives in a memory box that your program visits when an instruction reaches it. In hardware there are no boxes and no visits. A value is a set of voltage levels sitting on physical wires, and every wire holds its level all the time, in parallel. Nothing fetches a number. The number is there, as long as the circuit is powered. This topic exists to make that mental switch, and it starts with the most basic question: how do wires represent a number at all?

A Number Is a Bundle of Wires

One wire carries one bit: high voltage reads as 1, low voltage as 0. To carry anything bigger, you lay wires side by side. Eight wires form an 8-bit bus, and the pattern of highs and lows across the bundle, read all at once, is the value. There is no "first the left bit, then the next": all eight levels exist simultaneously. When you later declare ports and signals Entities and Modules, you are deciding how many wires each bundle gets.

Counting in Base 2

Binary is ordinary positional notation with base 2. In decimal, 374 means 3×100 + 7×10 + 4×1. In binary, each position's weight doubles: a 4-bit pattern has weights 8, 4, 2, 1. So 1011 is 8 + 0 + 2 + 1 = 11.

Going the other way, subtract the largest power of two that fits, and repeat. Decimal 165:

165 - 128 = 37    -> bit for 128 is 1
 37 -  32 =  5    -> bit for 64 is 0, bit for 32 is 1
  5 -   4 =  1    -> bit for 16 is 0, bit for 8 is 0, bit for 4 is 1
  1 -   1 =  0    -> bit for 2 is 0, bit for 1 is 1

165 = 128 + 32 + 4 + 1 = 10100101

Hex: Four Wires per Digit

Long bit strings are easy to misread, so hardware people compress them: one hexadecimal digit stands for exactly four bits.

DecimalBinaryHexDecimalBinaryHex
000000810008
100011910019
200102101010A
300113111011B
401004121100C
501015131101D
601106141110E
701117151111F

To convert, split the bit string into groups of four, starting from the right: 10100101 becomes 1010 0101, which the table reads as A and 5: hex A5. The conversion never involves arithmetic; it is pure regrouping, which is why hex (and not decimal) is the everyday shorthand for wire bundles.

Bit Widths

N wires can form 2^N distinct patterns, so an unsigned bus holds values from 0 up to 2^N − 1:

WiresPatternsUnsigned range
120 to 1
4160 to 15
82560 to 255
1665,5360 to 65,535

The width is fixed when you design the circuit. A bus is physical copper, and it cannot grow at runtime the way a Python integer can. A value must fit its wires: decimal 9 needs at least 4 bits, and on an 8-bit bus it appears as 00001001. The leading zeros are real wires, held low.

Writing Values in HDL

Here is the one statement this lesson hands you: a concurrent assignment that connects a wire bundle to a constant pattern.

led      <= "0110";     -- binary literal: one character per wire (4 wires)
data_bus <= x"C3";      -- hex literal: each digit covers 4 wires (8 wires)
year     <= 12D"2026";  -- decimal literal (VHDL-2008): you state the width yourself

Read the <= as a permanent connection, not an action: "the led wires are soldered to the pattern 0110." The statement doesn't execute once and finish; it holds, forever, like copper does.

Every literal above states its width through its length. A binary literal is a double-quoted string with exactly one character per wire. A hex literal x"..." covers four wires per digit, so an 8-bit bus needs two hex digits (x"0F" for decimal 15, leading zero included). A length that doesn't match the wires is a compile error.

In the Example

The example panel on the right (One Value, Three Ways) drives three 8-bit outputs with the value from this lesson's conversion. bin is spelled in binary, hex in hex, dec in decimal. Open the waveform and check two things. First, all three outputs read exactly the same value: the spelling is for humans, and only the wire pattern reaches the hardware. Second, nothing ever changes: the traces are flat from the first nanosecond to the last. No program ran, no statements executed in order; you are looking at three wire bundles soldered to a constant.

Key Takeaways

  • A value in hardware is a bundle of parallel wires, all present at once. Width is fixed at design time, and N wires hold 0 to 2^N − 1.
  • One hex digit is exactly four bits; converting between hex and binary is regrouping, not arithmetic.
  • An assignment (y <= ...) is a permanent connection, and the literal's width must match the wires it drives.
Loading editor...
Waveform not yet available. Run sync-content --examples to generate.