How binary data flows through your computer — from bits to circuits
In my years studying and building digital systems, I've traced the journey of binary data through the entire hardware stack countless times. This article is a guided tour of how a single binary value flows from a logic gate through the CPU, memory, and I/O system to produce a meaningful result. If you have read the other articles in this series on gates, adders, registers, and interrupts, this is where everything connects into a complete picture.
Every digital circuit is built from combinations of seven fundamental logic gates: AND, OR, NOT, NAND, NOR, XOR, and XNOR. Each gate takes binary inputs (logic 0 or 1, represented by voltage levels) and produces a binary output. A NAND gate, for instance, outputs 0 only when all inputs are 1 — otherwise it outputs 1.
I've come to think of these gates as the atoms of digital logic. A modern CPU uses billions of transistors configured into these gate patterns. The key insight is that any Boolean function can be implemented using only NAND gates or only NOR gates — these are called universal gates. This is why early integrated circuits were built entirely from NAND logic.
An adder is the first meaningful circuit you build from logic gates. A half adder takes two binary inputs (A and B) and produces a sum (S = A XOR B) and a carry output (C = A AND B). A full adder extends this by adding a carry input (Cin), making it possible to chain adders for multi-bit addition.
To add two 8-bit numbers, you connect 8 full adders in a ripple-carry configuration: the carry output of each stage feeds the carry input of the next. The critical path through all 8 stages determines the propagation delay. In my experience debugging timing issues, this ripple delay is why modern CPUs use carry-lookahead adders — they compute all carries in parallel using additional logic, cutting the delay from O(n) to O(log n).
The ALU is the computational heart of the CPU. It combines an adder with other arithmetic and logical circuits (subtractors, shifters, comparators, bitwise AND/OR/XOR) into a single functional block controlled by a selection input. A typical ALU has two data inputs (A and B), a function select input (often 3–4 bits encoding 8–16 operations), and outputs for the result, carry, zero flag, overflow flag, and sign flag.
In the data path, the ALU sits between the register file and the data memory. After the register file provides the two operand values on the ALU input buses, the control unit sets the ALU function select lines, and the ALU's combinational logic computes the result within a single clock cycle. I've spent many hours tracing ALU output flags to debug arithmetic overflow bugs in low-level code.
A register is a group of D flip-flops sharing a common clock signal, each storing one bit. A 64-bit register holds 64 bits using 64 flip-flops. A register file is an array of registers with read and write ports, used as the CPU's working storage. A typical register file might have 32 registers of 64 bits each, with two read ports and one write port for single-cycle read and write access.
The register file is critical for performance because it is the fastest storage the CPU can access — typically 0.25–0.5 ns. In contrast, accessing main memory takes 50–100 ns. The difference of two orders of magnitude is why compilers spend significant effort on register allocation, keeping frequently used values in registers rather than spilling them to the stack.
The data path is the collection of functional units and buses that binary data travels through during execution. A simplified single-cycle data path includes the program counter (holding the current instruction address), instruction memory (reading the instruction word at that address), the register file (providing operand values), the ALU (computing the result), data memory (for load/store instructions), and write-back (storing the result back to the register file).
Each of these steps involves bits flowing across dedicated buses — groups of parallel wires, one wire per bit. A 64-bit data bus has 64 parallel wires, each carrying one bit position. The PC updates to the next instruction address at the end of each cycle. Modern CPUs pipeline this process, overlapping the execution of multiple instructions across 5–20 stages.
When the CPU needs data not in its register file or cache, the memory controller takes over. The memory controller translates the CPU's memory request into the precise electrical signals required by DRAM: it sends the row address on the address bus with RAS (Row Address Strobe) asserted, then the column address with CAS (Column Address Strobe) asserted, and reads the data on the data bus after a CAS latency of typically 10–20 nanoseconds.
DRAM stores each bit as charge in a capacitor (1 transistor + 1 capacitor = 1T1C cell). This charge leaks away over milliseconds, so the memory controller must refresh all rows thousands of times per second. The controller also handles bank interleaving and burst transfers to maximize throughput. I've seen how a poorly configured memory controller can halve effective memory bandwidth despite the same DRAM chips.
In the traditional chipset architecture, the Northbridge connects the CPU to high-speed components (memory, PCIe graphics) via dedicated high-bandwidth buses, while the Southbridge connects to lower-speed peripherals (USB, SATA, audio, Ethernet) through shared buses. Modern CPUs integrate the memory controller and PCIe lanes directly on the CPU die (like the Northbridge functionality), with the Platform Controller Hub (PCH) handling legacy I/O.
PCI Express (PCIe) is the primary high-speed interconnect for modern peripherals. Data is serialized and sent over differential pair lanes at speeds up to 32 GT/s (PCIe 5.0). Each lane uses 128b/130b encoding to embed the clock. A x16 slot has 16 lanes providing about 63 GB/s of bidirectional bandwidth — enough for the GPU to stream textures and geometry data at frame rate.
The clock signal is a square wave generated by a crystal oscillator, alternating between high (logic 1) and low (logic 0) at a fixed frequency. A 4 GHz clock completes one cycle every 0.25 nanoseconds. The clock synchronizes all components: all registers update on the rising edge, combinational logic between registers has exactly one clock period to compute its result, state machines advance one state per cycle, and bus protocols use the clock to define when addresses and data are valid.
This is the essence of the Von Neumann architecture: a single shared bus for both instructions and data, sequenced by a central clock, with binary data flowing through the fetch-decode-execute cycle. Every instruction, every memory access, every I/O operation is ultimately a sequence of binary values synchronized to this clock cadence — and understanding that is the key to understanding how computers work at the hardware level.
Open the Binary Code Decoder in a new tab and enter some binary patterns to see the results instantly. All conversions happen in your browser — no data is sent to any server.