Skip to content

AMBA AHB · Module 13

Decoder + Arbiter Combination

How decoders and arbiters compose in an AHB bus matrix — decode lives on the master side (each master's address chooses which slave port to route to), arbitration lives on the slave side (each slave port has its own arbiter choosing which master accesses it). Decode routes; arbitrate resolves contention. Independent per-slave arbiters give both concurrency and per-slave-tunable policy.

Chapters 13.3–13.4 established what the matrix does (per-slave arbitration → concurrency) and its payoff (parallel access). This chapter explains how the two control functions — decoding and arbitration — compose in the fabric. The key structural idea: they split by side. Decode lives on the master side: each master's address is decoded to choose which slave port the transfer routes to — decode answers "where does this transfer go?". Arbitration lives on the slave side: each slave port has its own arbiter that chooses which master accesses it when several target the same slave — arbitrate answers "which master, and when?". So decode routes; arbitrate resolves contention — two complementary functions at two ends. Crucially, the per-slave arbiters are independent, which is what gives the matrix both its concurrency (no single global arbiter to serialize everything — chapter 13.3) and the ability to give each slave its own arbitration policy (a latency-critical memory can prioritize the CPU; a peripheral port can use round-robin). This chapter details the decode-then-arbitrate composition and why per-slave-arbiter independence matters.

1. What Is It?

The decoder + arbiter combination is how the matrix's two control functions are arranged: decode on the master side, arbitration on the slave side.

  • Decode (per master, master side) — each master's address is decoded to determine which slave port the transfer should route to (chapter 11.1 applied per master).
  • Arbitrate (per slave, slave side) — each slave port has its own arbiter that selects, among the masters whose decode points at this slave, which one accesses it now (Module 10 applied per slave).
  • Decode routes; arbitrate resolves contention — decode answers where; arbitrate answers which master, when.
Masters with per-master decoders route to slave ports; each slave port has its own arbiter that selects among the masters targeting it.
Figure 1 — decode on the master side, arbitrate on the slave side. Each master's address is decoded (master side) to choose which slave port to route to. Each slave port has its own arbiter (slave side) that picks, among masters targeting it, which one accesses it now. Decode = WHERE (which slave port); arbitrate = WHICH master, WHEN. Decode routes the transfer; arbitrate orders masters contending for the same slave.

So the combination is a two-stage control: first decode (per master) figures out where each transfer is headed (which slave port), then arbitrate (per slave) figures out, at each slave, which of the masters heading there goes now. They're complementary: decode is about routing (an address-to-destination mapping, per master), arbitration is about contention resolution (a fairness/priority decision, per slave). Neither alone suffices — decode without arbitration would let two masters drive the same slave (contention); arbitration without decode wouldn't know which slave a master wants. Together they steer every transfer to its slave and order same-slave access. So the decoder+arbiter combination is the matrix's complete steering-and-ordering control: route by decode, resolve by arbitrate.

2. Why Does It Exist?

The decode-master-side / arbitrate-slave-side split exists because the two questions a transfer raises — "where does it go?" and "who goes when there's contention?" — are naturally answered at different ends: the destination is a property of the master's address (so decode per master), while contention is a property of the slave being shared (so arbitrate per slave).

The destination is a master-address property → decode per master: which slave a transfer targets is determined entirely by the transfer's address — a property the master drives. So the natural place to decide "where does this go?" is at the master, by decoding its address. Each master decodes its own address to know which slave port to route to. So decode is per master because each master's destination depends on its own address. So decode lives on the master side. (This is just the Module 11 decoder, replicated per master in the matrix.)

The contention is a slave property → arbitrate per slave: contention arises when multiple masters want the same slave — a property of the slave (it can serve one at a time). So the natural place to resolve contention is at the slave, by an arbiter that sees all the masters targeting that slave and picks one. So arbitration is per slave because contention is about sharing a slave. So arbitration lives on the slave side. (This is the Module 10 arbiter, replicated per slave in the matrix.) So the split exists because the two control questions belong to different ends: destination ↔ master's address (decode per master), contention ↔ shared slave (arbitrate per slave). It's not arbitrary — it follows from where the relevant information lives.

The reason per-slave arbiter independence is the crucial property is that it delivers two benefits at once. First, concurrency (chapter 13.3): because each slave arbitrates independently (no single global arbiter), accesses to different slaves don't share an arbitration point → they proceed concurrently. A single global arbiter would serialize everything (a shared bus); independent per-slave arbiters localize contention → concurrency. Second, per-slave policy: because each slave's arbiter is independent, each can use a different policy suited to that slave — a latency-critical memory's arbiter can prioritize the CPU (low latency for the critical master), while a peripheral port's arbiter uses round-robin (fairness). A single global arbiter would force one policy for all. So per-slave-arbiter independence gives both concurrency and policy flexibility. So the decoder+arbiter combination exists in this form — decode per master (destination), arbitrate per slave (contention), per-slave arbiters independent — because it places each control function where its information lives and because the independence of the per-slave arbiters simultaneously enables concurrency and per-slave policy tuning. It's the structural arrangement that makes the matrix both parallel and tunable. (The detailed routing this composes with is chapter 13.6; the per-slave HREADY combination is chapter 13.7.)

3. Mental Model

Model the decoder+arbiter combination as a large hospital's patient flow — each patient (transfer) is triaged at intake by which department they need (decode: the address picks the destination — cardiology, radiology, etc.), and then each department has its own scheduling desk (per-slave arbiter) that decides which of the patients routed to it is seen next, using rules suited to that department (the ER prioritizes by severity, the lab uses first-come-first-served) — so intake routes by need, departments schedule independently, and patients for different departments are handled in parallel.

A large hospital handles many patients (transfers). At intake (the master side), each patient is triaged by which department they need — cardiology, radiology, the lab (decode: the address determines the destination slave). Intake doesn't decide when they're seen; it just routes them to the right department. Then each department has its own scheduling desk (the per-slave arbiter): the desk decides which of the patients routed to that department is seen next. Crucially, each department's desk operates independently and with its own rules — the ER desk prioritizes by severity (a critical patient first — like prioritizing a latency-critical master), while the lab desk uses first-come-first-served (fairness — like round-robin). Because the desks are independent, patients headed to different departments are handled in parallel (cardiology and radiology see their patients simultaneously) — there's no single central desk forcing everyone into one queue. The only time patients wait is when several need the same department — then that department's desk sequences them by its rules. So intake routes by need (decode), departments schedule independently with their own rules (per-slave arbiters), and different-department flow is parallel.

This captures the combination: intake triage by department = decode (master side, address → slave port); each department's scheduling desk = per-slave arbiter (slave side); the desk's rules (severity vs FCFS) = per-slave arbitration policy; independent desks → parallel handling = independent per-slave arbiters → concurrency; waiting only for the same department = same-slave contention. Route by need at intake, schedule independently per department — parallel across departments, ordered within one.

Watch decode route two masters and a slave arbiter order same-slave contention:

Decode routes; slave arbiter orders same-slave contention

3 cycles
Cycle 0: CPU decodes to SRAM, DMA decodes to flash — both proceed. Cycle 1: both decode to SRAM — SRAM's arbiter grants the CPU, the DMA waits.Different slaves (decode) → both proceed, no arbitrationDifferent slaves (deco…Same slave (both → SRAM) → SRAM arbiter grants CPU, DMA waitsSame slave (both → SRA…HCLKcpu→ (decode)SRAMSRAMSRAMdma→ (decode)FlashSRAMSRAMSRAM grantCPUCPUDMADMA waitst0t1t2
Figure 2 — decode routes, the slave arbiter orders. Cycle 0: the CPU's decode points at SRAM, the DMA's decode points at flash — different slaves, so both route and proceed (no arbitration needed). Cycle 1: both the CPU's and DMA's decode point at SRAM — same slave, so SRAM's arbiter resolves it (grants CPU, per its priority policy), and the DMA waits. The 'cpu→' and 'dma→' rows show decode's routing; SRAM's arbiter acts only when both target it.

The model's lesson: route by need at intake (decode), schedule independently per department (per-slave arbiter) — parallel across, ordered within. In the waveform, decode routes the masters; SRAM's arbiter acts only when both target SRAM, granting one and stalling the other.

4. Real Hardware Perspective

In hardware, the combination is per-master decode logic feeding per-slave arbiter+mux units — the decoder is replicated per master path, the arbiter+mux is replicated per slave port, and they connect through the routing fabric.

The per-master decode is replicated decode logic: each master's layer has a decoder that examines its address and produces a slave-port-select (which slave port this transfer wants) — essentially the Module 11 decoder, one per master. This select routes the master's transfer toward the chosen slave port (and is a request to that slave's arbiter). So in hardware, there are M decoders (one per master), each producing a routing/request signal. So decode is replicated per master.

Two slave ports, each with its own arbiter and input mux: SRAM port (priority: CPU first) and peripheral port (round-robin).
Figure 3 — one arbiter + input mux per slave port, independent and individually tunable. The SRAM port's arbiter uses a priority policy (CPU first, for low latency); the peripheral port's arbiter uses round-robin (for fairness). Each is independent, which both enables concurrency (no global serialization) and lets each slave use its own policy. The fabric is a collection of per-slave arbiter-plus-mux units, one per slave.

The per-slave arbiter + mux is replicated arbitration: each slave port has an arbiter that receives the requests (from masters whose decode points at this slave) and grants one (per its policy), plus an input mux (controlled by the grant) that connects the granted master's address/control/write-data to the slave. So each slave port is a Module-10-style arbiter driving a mux. There are S such units (one per slave). Because each is independent, they operate concurrently (different slaves' arbiters grant simultaneously) and can be individually configured (different policies). So in hardware, there are S arbiter+mux units, independent and tunable. So the fabric is M decoders + S arbiter+mux units, connected by routing.

The composition and timing: a transfer flows decode (master) → request the target slave's arbiter → arbiter grants → mux connects → slave responds → response routed back. The decode and arbitration are in the address-phase path (the routing/grant must settle so the slave sees the right master's address-phase signals) — so at scale this can be a timing concern (deep decode + arbitration + muxing), managed by pipelining/registering the matrix (chapter 13.6). The key hardware point: because the arbiters are per slave and independent, the fabric parallelizes — M masters can be decoding and S slaves arbitrating simultaneously, enabling the concurrent transfers of chapter 13.4. So in hardware, the combination is replicated decode (per master) + replicated arbiter+mux (per slave), independent and concurrent, composing into the routing fabric — the structural basis of the matrix's parallelism and per-slave tunability.

5. System Architecture Perspective

At the system level, the decode/arbitrate split and per-slave-arbiter independence are what make the matrix both high-bandwidth and QoS-tunable — and understanding the split clarifies how to configure a matrix for a system's needs.

The concurrency from independence (recap + system framing): the per-slave-arbiter independence is the structural source of the matrix's concurrency (chapter 13.3). At the system level, this means the matrix's bandwidth comes specifically from having distributed (per-slave) arbitration rather than centralized (one arbiter). So a system architect choosing a matrix is choosing distributed arbitration — and the more slaves (arbitration points), the more potential concurrency. So the decode/arbitrate split's arbitrate-per-slave half is the bandwidth enabler. So at the system level, the combination's structure is the bandwidth mechanism.

The QoS via per-slave policy is the powerful system lever: because each slave's arbiter is independent and individually configurable, the system can implement per-slave quality-of-service. A latency-critical slave (e.g. the memory holding real-time data) can have its arbiter prioritize the latency-sensitive master (the CPU, or a real-time core) — guaranteeing that master low-latency access to that slave. A bandwidth-shared slave (e.g. a peripheral block) can use round-robin for fairness. A slave with a dominant user can use fixed priority for that user. So the architect tunes each slave's arbitration policy to that slave's role — a per-slave QoS knob. A single global arbiter couldn't do this (one policy for all). So at the system level, per-slave-arbiter independence gives per-slave QoS configuration — a key tool for meeting mixed latency/bandwidth requirements. So the matrix isn't just "more bandwidth"; it's tunable bandwidth/latency per slave.

The configuration clarity view: understanding the split tells the architect what to configure. Decode (master side) is configured by the address map (which addresses route to which slave — chapter 11.4); it's about connectivity (which masters can reach which slaves, possibly sparse — chapter 13.3). Arbitration (slave side) is configured per slave by policy (priority/round-robin/QoS for that slave); it's about contention resolution. So configuring a matrix is two distinct tasks: set the routing/address-map/connectivity (decode) and set the per-slave arbitration policies (arbitrate). Keeping them separate (they're at different ends) clarifies the design. So at the system level, the decode/arbitrate combination makes the matrix high-bandwidth (distributed per-slave arbitration → concurrency) and QoS-tunable (per-slave independent policies), and it clarifies matrix configuration as two tasks — routing/connectivity (decode, from the address map) and per-slave arbitration policy (arbitrate, for QoS). So the combination is the conceptual key to both using and configuring the matrix: route by decode (set the connectivity), resolve by arbitrate (set the per-slave QoS). It's where the matrix's structure meets the system's connectivity and QoS requirements.

6. Engineering Tradeoffs

The decoder+arbiter combination embodies the split-control, independent-per-slave design.

  • Decode per master vs centralized. Per-master decode (each master decodes its own address to route) is natural (destination is a master-address property) and enables independent routing; a centralized decode would bottleneck. Decode is per master.
  • Arbitrate per slave vs global. Per-slave (distributed) arbitration localizes contention → concurrency and enables per-slave policy, at the cost of S arbiters; a single global arbiter is cheaper but serializes everything (a shared bus) and forces one policy. The matrix uses per-slave arbiters.
  • Per-slave policy vs uniform. Independent per-slave arbiters allow per-slave QoS (priority for critical slaves, round-robin for fair ones) at the cost of configuring each; a uniform policy is simpler but can't meet mixed requirements. Per-slave policy is a matrix advantage.
  • Sparse routing vs full. Decode/routing can be sparse (a master reaches only the slaves it needs — chapter 13.3), cutting decode/mux cost; full connectivity (every master to every slave) is flexible but costlier. Sparse where possible.

The throughline: the matrix splits its control — decode on the master side (each master's address → which slave port: routing, answering where) and arbitration on the slave side (each slave port's own arbiter → which master accesses it: contention resolution, answering which/when). Decode routes; arbitrate resolves contention. The per-slave arbiters are independent, giving the matrix both its concurrency (distributed, not global, arbitration → different-slave accesses don't compete) and per-slave QoS tunability (each slave's policy suits its role). Configuring a matrix is two tasks: routing/connectivity (decode, from the address map) and per-slave arbitration policy (arbitrate, for QoS).

7. Industry Example

Trace decode and arbitration through a matrix transaction.

A system has a CPU and a DMA, accessing SRAM (latency-critical) and a peripheral block, via a matrix.

  • Decode routes the CPU. The CPU issues a transfer to an SRAM address. Its (master-side) decoder examines the address and routes the transfer to the SRAM port — a request to SRAM's arbiter. Decode answered where: SRAM.
  • Decode routes the DMA. Simultaneously, the DMA issues a transfer to a peripheral address. Its decoder routes it to the peripheral port. Different slave → no contention with the CPU. Both proceed in parallel (chapter 13.4).
  • Same-slave contention. Later, both the CPU and DMA target SRAM at once. Both decoders route to the SRAM port, so SRAM's arbiter sees two requests. It applies its policy.
  • Per-slave QoS policy. SRAM is latency-critical, so its arbiter is configured priority: CPU first. So it grants the CPU (low-latency access for the critical master) and the DMA waits. Meanwhile, the peripheral port's arbiter (configured round-robin for fairness) handles its own contention independently — unaffected by SRAM's decision.
  • Independence in action. The two arbiters (SRAM's, peripheral's) operate independently and concurrently — SRAM granting the CPU doesn't stall peripheral access by another master. This independence is both why the accesses are concurrent and why each slave's policy is its own.
  • Configuration. The architect configured two things: the address map / routing (which addresses → SRAM vs peripheral — decode side) and the per-slave policies (SRAM = priority CPU, peripheral = round-robin — arbitrate side). Two distinct configuration tasks at two ends.

The example shows the combination: decode (master side) routes each transfer to its slave port; per-slave arbiters (slave side) resolve contention, each with its own QoS policy; and the arbiters' independence gives both concurrency and per-slave tuning. Configuring the matrix meant setting routing (decode) and per-slave policies (arbitrate) separately. This is the decoder+arbiter combination in real use.

8. Common Mistakes

9. Interview Insight

The decoder+arbiter combination is a structural interview topic — the decode-master-side/arbitrate-slave-side split and the per-slave-independence-gives-both-concurrency-and-QoS insight are the signals.

A summary card on the decoder+arbiter combination: decode per master (where), arbitrate per slave (which/when), independence → concurrency + QoS.
Figure 4 — a strong answer in one card: decode (per master) maps address → which slave port (WHERE); arbitrate (per slave) picks which master accesses this slave (WHICH/WHEN); independent per-slave arbiters give both concurrency (no global serialization) and per-slave policy tuning. The senior point: decode routes per master, arbitrate resolves contention per slave, and independence gives concurrency + tunable policy.

The answer that lands gives the split and the independence insight: "In a bus matrix, the decoder and arbiter split by side. Decode lives on the master side: each master's address is decoded to choose which slave port the transfer routes to — decode answers 'where does this go?'. Arbitration lives on the slave side: each slave port has its own arbiter that, when several masters target that slave, picks which one accesses it now — arbitrate answers 'which master, and when?'. So decode routes and arbitrate resolves contention; they're complementary functions at two ends. The reason they're placed there is that the destination is a property of the master's address (so decode per master) while contention is a property of the shared slave (so arbitrate per slave). The crucial point is that the per-slave arbiters are independent, and that independence delivers two things at once. It gives concurrency: because each slave arbitrates on its own, accesses to different slaves go through different arbitration points and run in parallel — a single global arbiter would serialize everything, which is just a shared bus. And it gives per-slave QoS: each slave's arbiter can use its own policy — priority for a latency-critical memory, round-robin for a fair peripheral. So configuring a matrix is two tasks: the routing/address-map on the decode side, and the per-slave arbitration policies on the arbitrate side." The decode/arbitrate split, the where-it-lives reasoning, and the independence-gives-both insight are the senior signals.

10. Practice Challenge

Reason from the decoder+arbiter combination.

  1. The split. State which function (decode/arbitrate) lives on which side and what each answers.
  2. Why there. Explain why decode is per master and arbitration is per slave (where the information lives).
  3. Read the waveform. From Figure 2, explain how decode routes the masters and when SRAM's arbiter acts.
  4. Independence. Explain how per-slave-arbiter independence gives both concurrency and per-slave QoS.
  5. Configuration. State the two configuration tasks and which side each is on.

11. Key Takeaways

  • Decode and arbitrate split by sidedecode on the master side (each master's address → which slave port: routing, where); arbitrate on the slave side (each slave port's own arbiter → which master accesses it: contention resolution, which/when).
  • They're placed where their information lives — destination is a master-address property (decode per master); contention is a shared-slave property (arbitrate per slave).
  • Decode routes; arbitrate resolves contention — both required: decode without arbitration risks same-slave contention; arbitration without decode doesn't know the destination.
  • Per-slave arbiters are independent — and that independence delivers both the matrix's concurrency (distributed, not global, arbitration → different-slave accesses don't compete) and per-slave QoS (each slave's arbiter runs its own policy).
  • A single global arbiter would lose both — it would serialize everything (shared bus, no concurrency) and force one policy (no per-slave QoS). Distributed independence is essential.
  • Configuring a matrix is two tasks — routing/connectivity (decode side, from the address map, possibly sparse) and per-slave arbitration policy (arbitrate side, for QoS).

12. What Comes Next

You now understand how decode and arbitration compose in the matrix. The next chapters detail routing and response handling:

  • Interconnect Routing (next) — how transfers route from master port to slave port (and responses back), end-to-end.
  • HREADY Aggregation — how per-slave HREADYOUT is combined into each master's HREADY.
  • Bus Matrix Performance — relating matrix topology to achievable system bandwidth.

To revisit the foundations this composes, see Address Decoding (decode) and Why Arbitration Exists (arbitrate); for the matrix structure, see The Bus Matrix Concept.