Loading header...

Address Decoding and Chip Select - How One Bus Talks to Many Chips

When the CPU places an address on its bus, several chips may see the same wires: ROM, RAM, display controllers, GPIO ports, ADCs, or external peripherals. Only one of them should respond to a given address. Address decoding is the hardware that turns an address range into a chip-select signal.

A chip-select signal, often written CS or active-low CS_N, enables exactly one device for the current bus cycle. Without it, multiple devices could drive the shared data bus at the same time, or a device could respond to an address that does not belong to it.

Learning Objectives

By the end of this lesson, you should be able to:

  • explain why shared buses need address decoding;
  • split address bits into block-select bits and in-chip address bits;
  • build simple memory maps using upper address lines;
  • read a 3-to-8 decoder truth table for chip-select generation;
  • identify aliasing, incomplete decoding, and bus-contention risks.

The Shared-Bus Problem

Many classic microprocessor systems use a shared address bus and a shared data bus.

flowchart TB CPU["CPU"] --> ABUS["Address bus"] CPU <--> DBUS["Data bus"] ABUS --> ROM["ROM"] ABUS --> RAM["RAM"] ABUS --> IO["I/O device"] ROM <--> DBUS RAM <--> DBUS IO <--> DBUS

The address bus tells all devices what address the CPU wants. Address decoding decides which device is allowed to care.

For a read cycle, the selected chip drives the data bus. Every unselected chip must leave its outputs disabled. For a write cycle, the selected chip stores the CPU's data. Every unselected chip must ignore the write.

Chip Select

Most memory and peripheral devices have enable pins:

  • CS or CE: chip select/chip enable;
  • OE: output enable for reads;
  • WE: write enable for writes;
  • active-low versions such as CS_N, OE_N, or WE_N.

An active-low signal is asserted when it is logic 0. In text, CS_N is clearer than relying on an overbar that may render poorly on mobile.

flowchart LR ADDR["Address bits"] --> DEC["Decoder logic"] RD["Read control"] --> ROM["ROM OE_N"] WR["Write control"] --> RAM["RAM WE_N"] DEC --> CSROM["ROM CS_N"] DEC --> CSRAM["RAM CS_N"] DEC --> CSIO["I/O CS_N"]

Chip select chooses the device. Read/write control chooses what operation happens after that device has been selected.

Splitting Upper and Lower Address Bits

Suppose a CPU has a 16-bit address bus. It can address:

2^16 bytes = 65,536 bytes = 64 KiB

If each memory block is 8 KiB, then each block needs:

8 KiB = 8192 bytes = 2^13 bytes

So 13 lower address bits select a byte inside the selected chip:

A12..A0 = in-chip address

The remaining 3 upper bits select one of eight 8 KiB regions:

A15..A13 = block select

This is why memory maps often use power-of-two boundaries. The address bits split cleanly into "which chip" and "which location inside the chip."

Example Memory Map

Address range A15 A14 A13 Decoder output Device
0x0000 to 0x1FFF 000 Y0_N low ROM
0x2000 to 0x3FFF 001 Y1_N low RAM
0x4000 to 0x5FFF 010 Y2_N low I/O
0x6000 to 0x7FFF 011 Y3_N low reserved
0x8000 to 0xFFFF 100 to 111 Y4_N to Y7_N unused/reserved

For a 3-to-8 active-low decoder, exactly one output goes low for each input combination.

flowchart LR A15["A15"] --> D["3-to-8 decoder"] A14["A14"] --> D A13["A13"] --> D EN["Enable"] --> D D --> Y0["Y0_N: ROM"] D --> Y1["Y1_N: RAM"] D --> Y2["Y2_N: I/O"] D -.-> Y3["Y3_N..Y7_N reserved"]

Classic trainer kits often use parts like the 74HC138 or 74138 because this exact pattern is common: three upper address bits select one of eight active-low chip-select lines.

Worked Example: Which Device Responds?

Use the same 64 KiB map with 8 KiB blocks. Which device responds to address 0x2345?

  1. Convert only the upper region mentally: 0x2345 lies between 0x2000 and 0x3FFF.
  2. Therefore A15..A13 = 001.
  3. Decoder output Y1_N goes low.
  4. RAM is selected.
  5. Lower bits A12..A0 select location 0x0345 inside that 8 KiB RAM block.

The CPU does not need to know the RAM chip's internal row and column details. It simply puts 0x2345 on the address bus. The decoder selects RAM, and the lower address bits select the internal location.

Complete vs Partial Decoding

Complete decoding uses enough address bits so each device appears at exactly one intended address range.

Partial decoding ignores some upper address bits. It saves logic, but the same device may appear at multiple addresses. This is called address aliasing or mirroring.

Example: if a designer decodes only A15..A14 for 16 KiB regions but connects an 8 KiB RAM, that RAM can appear twice within the selected 16 KiB window unless another bit is decoded.

Partial decoding is not always wrong. It may be acceptable in a tiny product where the aliases are documented and unused. It is dangerous when software assumes those addresses are different devices.

Design Rules

  • Decode enough upper address bits to avoid accidental aliasing.
  • Keep chip-select mutually exclusive for devices that share a data bus.
  • Combine chip-select with RD_N or WR_N as the device datasheet requires.
  • Respect setup and hold times between address, chip-select, output-enable, and data.
  • Leave unused decoder outputs inactive or reserve them deliberately.
  • Document active-low signal names with _N or n suffixes.
  • Never let two output-enabled devices drive the same data bus.

Common Mistakes

  • Decoding lower address bits instead of the upper block-select bits.
  • Forgetting that active-low outputs assert at logic 0.
  • Connecting CS_N but ignoring OE_N or WE_N timing.
  • Leaving decoder enable pins floating.
  • Creating unplanned mirrored address ranges through partial decoding.
  • Assuming a decoder alone prevents contention when output-enable logic is wrong.

Summary

Address decoding maps CPU address ranges to chip-select signals. Upper address bits select the device or memory block; lower address bits select the location inside the chosen device. A decoder such as a 3-to-8 active-low part provides mutually exclusive chip-select lines, but the design must also handle read/write controls, timing, and unused or partially decoded regions.

Further Reading

  • Texas Instruments, SN74HC138 3-Line to 8-Line Decoders/Demultiplexers datasheet.
  • Intel, MCS-85 User's Manual, memory and I/O interfacing examples.
  • Microchip, external memory interface documentation for 8-bit and 16-bit microcontrollers.
  • Wakerly, Digital Design, decoders, enables, and bus systems.

Mind Map

mindmap root((Address Decoding)) Core concept Address range to chip select One bus many devices Only selected chip responds Bit split Upper bits choose block Lower bits address inside chip 64 KiB equals 2 power 16 8 KiB block uses 13 bits Hardware Gates Comparator 3 to 8 decoder Active low CS_N Design rules Mutually exclusive selects Decode enough bits Combine with RD_N and WR_N Meet timing Practical checks Memory map table Floating enables Reserved outputs Alias addresses Common mistakes Active low confusion Lower bit decode Partial decode surprise Bus contention risk

-> Tri-State Buses