Skip to content

AMBA AHB · Module 18

Arbitration Bug

Diagnosing lost grants, starvation, or bad handover in a multi-master AHB system — the arbiter grants the bus via HBUSREQ/HGRANT (HMASTER = owner). A lost grant: a master requests but is never granted (or the grant is dropped before use), so its transfer never happens. Starvation: a low-priority master is never granted because higher-priority masters keep the bus (a fairness failure). A bad handover: ownership switches mid-transfer/mid-burst/mid-lock, interrupting a transfer or letting two masters drive the bus. Diagnose by watching HBUSREQ/HGRANT/HMASTER together — request must eventually be granted, no master should starve, handover must land only on a legal boundary, and locked sequences must hold the grant. Full-AHB only; AHB-Lite is single-master with no arbitration.

The previous chapters debugged single-transfer and burst bugs; this chapter moves to the multi-master domain — an arbitration bug. In a multi-master AHB system (full AHB — not AHB-Lite, which is single-master with no arbitration — chapters 12.2/12.3), the arbiter decides which master owns the bus, using request and grant signals (HBUSREQ/HGRANT) with HMASTER indicating the current owner (chapter 10). Arbitration bugs come in three kinds. A lost grant: a master requests the bus but is never granted (or the grant is dropped before the master uses it) — so its transfer never happens. Starvation: a low-priority master is never granted because higher-priority masters keep the bus — a fairness failure (not a single lost grant). A bad handover: ownership switches at the wrong timemid-transfer, mid-burst, or during a locked sequence that should be atomic — so a transfer is interrupted, or two masters drive the bus around the switch. The diagnosis is to watch the request, grant, and HMASTER signals together: check that a request eventually leads to a grant, that a low-priority master is eventually granted (no starvation), that handover happens only at a legal point (the end of a transfer/burst, bus idle-ready), and that locked sequences hold the grant. The cause is in the arbiter or the handover logic. This chapter builds the diagnosis.

1. What Is It?

An arbitration bug is a multi-master bus-ownership failure; debugging it means watching request/grant/owner together. Its parts:

  • The signals — the arbiter grants the bus via HBUSREQ/HGRANT; HMASTER = the current owner.
  • Lost grant — a master requests but is never granted (or the grant is dropped before use) → the transfer never happens.
  • Starvation — a low-priority master is never granted (higher-priority masters keep the bus) → a fairness failure.
  • Bad handover — ownership switches at the wrong time (mid-transfer/burst/lock) → interrupted transfer or two masters driving.
The three arbitration failure modes (lost grant, starvation, bad handover), the request/grant/owner diagnosis, and the arbiter/handover cause.
Figure 1 — diagnosing arbitration bugs. Multi-master: the arbiter grants the bus (HBUSREQ → HGRANT; HMASTER = owner). Lost grant: a master requests but is never granted, or the grant is dropped before it's used → the transfer never happens (fix: correct grant-hold timing). Starvation: a low-priority master is NEVER granted (higher-priority keep the bus) → a fairness failure, not a lost grant (fix: round-robin/fairness policy). Bad handover: ownership switches at the WRONG time (mid-transfer/mid-burst/mid-lock) → interrupted xfer / two masters drive (fix: handover only at legal boundaries). Diagnosis: watch HBUSREQ, HGRANT, HMASTER together — request → eventually a grant? low-priority ever granted? handover only at a legal point (end of transfer/burst, bus idle-ready)? locked sequences HOLD the grant? The cause is in the arbiter or the handover logic. Arbitration is multi-master (full AHB) — AHB-Lite has a single master and no arbitration.

So an arbitration bug is a bus-ownership failure — the arbiter (the logic that decides who owns the bus) or the handover (the transition of ownership) misbehaving. The key to debugging it is watching the three ownership signals together: HBUSREQ (who wants the bus), HGRANT (who's granted it), and HMASTER (who owns it). The three failure modes are distinct patterns in these signals: a lost grant (a HBUSREQ never followed by an HGRANT, or an HGRANT dropped before use), starvation (a HBUSREQ persistently un-granted while others are granted — a fairness issue), and a bad handover (an HMASTER change at an illegal point — mid-transfer/burst/lock). So you read the patterns in HBUSREQ/HGRANT/HMASTER to classify and diagnose. The cause is in the arbiter (the grant decision — priority, fairness, timing) or the handover logic (the when of the switch). So an arbitration bug is the bus-ownership failure debugged by watching request/grant/owner. So it's a multi-master coordination bug.

2. Why Does It Exist?

Arbitration bugs exist because multiple masters share one bus, so the arbiter must decide ownership (a policy — who wins) and sequence handover (a timing — when to switch) correctly — and each of these is error-prone: the grant decision can lose a request or be unfair (starvation), and the handover can switch at the wrong time (interrupting transfers).

The shared bus needs an arbiter is the root: in a multi-master system, multiple masters want the one bus — but only one can own it at a time. So an arbiter must decide which master gets it (when multiple request). This decision (the grant) is a policy — and the handover (the transition) is a sequence. So the arbiter introduces two error-prone functions: deciding (the grant) and sequencing (the handover). So arbitration bugs exist because a shared bus needs an arbiter — which can err in either function. So it's a shared-resource problem. So sharing needs arbitration.

The the grant decision can err drives lost-grant/starvation: the grant decision must eventually grant every requesting master (liveness — no lost grant) and fairly (no starvation). A bug in the decision — a dropped request, a priority that always favors one master, a missing fairness mechanism — causes a lost grant (a request never granted) or starvation (a low-priority master never granted). So arbitration bugs exist because the grant decision can fail liveness/fairness. So it's a decision bug. So the policy can err.

The the handover can err drives bad-handover: the handover (the transition of ownership) must happen only at a legal point — the end of a transfer/burst, not mid-flight, and never during a locked sequence. A bug in the handover timing — switching mid-transfer, or preempting a lockinterrupts a transfer or breaks atomicity (or causes contention). So arbitration bugs exist because the handover timing can be wrong. So it's a sequencing bug. So the handover can err. So arbitration bugs exist because: a shared bus needs an arbiter (introducing the decide and sequence functions — the why); the grant decision can fail liveness/fairness (lost grant / starvation — the decision bugs); and the handover timing can be wrong (bad handover — the sequencing bug). So arbitration bugs are the multi-master coordination failures — in the arbiter's grant decision (lost grant/starvation) or the handover logic (bad handover) — debugged by watching request/grant/owner and checking liveness, fairness, and legal handover. So this chapter teaches the request/grant/owner trace. So watch the ownership signals and check the policy and timing.

3. Mental Model

Model debugging an arbitration bug as finding why a shared meeting room is mismanaged by its booking system — you watch the requests, the bookings, and who's actually in the room. Three failure modes: someone books but never gets the room (lost grant — their request was dropped); the junior team never gets it because the senior team always wins (starvation — unfair priority); or someone is kicked out mid-meeting, or two teams are double-booked into the room at once (bad handover — the switch happened at the wrong time). To debug, you watch the request log, the booking grants, and the actual occupant together, and check: do requests eventually get a booking, does everyone get a turn, and do handovers happen only at the end of a meeting, never mid-session or during a do-not-disturb hold?

A shared meeting room (the bus) managed by a booking system (the arbiter). Teams (masters) request the room (HBUSREQ), the system grants a booking (HGRANT), and a sign on the door shows the current occupant (HMASTER). The system's job: fairly and correctly allocate the one room among competing teams, and transition occupancy cleanly. Three ways it fails. Lost booking (lost grant): a team submits a request but never gets a booking — their request was dropped or ignored, so they wait forever for a room that never comes (and their meeting never happens). The junior team never gets the room (starvation): the senior team (higher priority) always books it, and the junior team (low priority), though constantly requesting, is never granted — the system works (it grants someone), but unfairly (one team is starved). Mid-meeting eviction or double-booking (bad handover): the system switches the occupant at the wrong timekicking a team out mid-meeting (mid-transfer — the meeting is cut off), or during a "do not disturb" hold (a locked sequence — breaking the atomicity), or double-booking two teams into the room at once (two masters drivingcontention). To debug, you watch three things together: the request log (who asked), the booking grants (who got a booking), and the door sign (who's actually in the room). And you check: do requests eventually get a booking (else a lost booking)? Does every team eventually get a turn (else starvation)? Do handovers happen only at the end of a meeting, with the room empty and readynever mid-session and never during a do-not-disturb hold (else a bad handover)? The fault is in the booking system (the arbiter — its grant logic) or the handover procedure (the when of the switch).

This captures arbitration-bug debug: the shared meeting room = the bus; the booking system = the arbiter; teams requesting = masters asserting HBUSREQ; granting a booking = HGRANT; the door sign / occupant = HMASTER; a request never getting a booking = a lost grant; the junior team never granted = starvation; mid-meeting eviction = a mid-transfer handover; the do-not-disturb hold = a locked sequence; double-booking = two masters contending; watching request log + bookings + door sign together = watching HBUSREQ/HGRANT/HMASTER; requests eventually booked / every team gets a turn / handover at meeting-end = liveness/fairness/legal-handover checks. Watch requests, bookings, and the occupant together, and check liveness, fairness, and clean handover.

Watch a bad handover on the waveform — ownership switching mid-burst:

Bad handover: ownership switches mid-burst

4 cycles
Master 0 owns the bus and runs a burst (beats 0-3). A higher-priority Master 1 requests, and a buggy arbiter switches HMASTER from M0 to M1 at beat 2, mid-burst, interrupting M0's burst — beats 2-3 are lost and the masters may contend. The legal handover would be after beat 3. The HMASTER change lands mid-burst, not at a boundary — the bug.M1 requests; M0 is mid-burst → arbiter should wait for the burst's endM1 requests; M0 is mid…Buggy: HMASTER switches to M1 MID-burst → M0's burst interrupted (beats 2-3 lost)Buggy: HMASTER switche…M0 burst beat012 (cut!)M1 HBUSREQHMASTERM0M0M1!M1handover legal?00NO (mid-burst)NO (mid-burst)t0t1t2t3
Figure 2 — a bad handover: ownership switching mid-burst. Master 0 (M0) owns the bus and is running a burst (beats 0-3). The arbiter should let M0 finish its burst before handing over. But a higher-priority Master 1 (M1) requests, and a buggy arbiter switches HMASTER from M0 to M1 mid-burst (at beat 2), interrupting M0's burst. The 'HMASTER' row shows M0, M0, then M1 (mid-burst). M0's burst is cut off after beat 1 — beats 2-3 never happen (lost) — and around the switch, M0 and M1 may both drive briefly (contention). The legal handover would be after beat 3 (the burst's end). The diagnosis: the HMASTER change at beat 2 coincides with the MIDDLE of M0's burst, not a boundary — that's the bug.

The model's lesson: watch requests, bookings, and the occupant together, and check liveness, fairness, and clean handover. In the waveform, the HMASTER change at beat 2 lands mid-burst (M0's burst is cut off) — a bad handover. The legal switch is after beat 3 (the burst's end). The diagnosis: the ownership change coincides with the middle of a burst, not a boundary.

4. Real Hardware Perspective

In debug, you trace the request/grant/owner signals, classify the failure (lost grant / starvation / bad handover), and trace to the arbiter's grant logic (priority/fairness/liveness) or the handover logic (boundary/lock timing).

The trace request/grant/owner: on the waveform, trace HBUSREQ[i] (each master's request), HGRANT[i] (each master's grant), and HMASTER (the current owner). Align them: for each master, does a request lead to a grant and then ownership? Does ownership change at legal points? This joint view is the basis of the diagnosis. So in debug, trace the three signals together. So it's the joint trace. So that's step one.

A handover FSM showing legal handover only at a transfer/burst boundary (keeping the bus mid-transfer/locked) versus a bad mid-transfer switch.
Figure 3 — legal bus-ownership handover versus a bad handover. The handover FSM: GRANTED (the master owns the bus) → OWNING/TRANSFERRING (runs its transfers/burst; mid-transfer or locked → KEEP, self-loop) → BOUNDARY (transfer/burst done, bus ready) → if another master is requesting and the current owner is not locked, HAND OVER (legal) back to GRANTED for the new master. A bad handover violates this: it switches ownership mid-transfer or mid-lock, so the transfer is cut off or the lock's atomicity is broken, with possible contention around the switch. Diagnose: every HMASTER change must coincide with a legal boundary (the previous owner's transfer/burst completing, bus ready); a switch landing mid-transfer (or mid-lock) is the bug.

The classify the failure: classify by the pattern: a request never granted (or dropped before use) → a lost grant (a liveness failure in the grant decision); a low-priority request persistently un-granted while others winstarvation (a fairness failure); an HMASTER change at an illegal point (mid-transfer/burst/lock) → a bad handover (a timing failure in the handover). So in debug, classify by the request/grant/owner pattern. So it's classification. So that points to the cause.

The trace to the arbiter or handover logic: with the failure classified, trace: a lost grant → the arbiter's grant logic (is the request seen? is the grant held until taken? — a grant-hold-timing bug); starvation → the arbiter's policy (is there a fairness mechanism? — fix with round-robin/fairness — 10.6/10.7); a bad handover → the handover logic (does it wait for the transfer/burst boundary? does it respect the lock? — fix the boundary/lock timing — 10.9). The fix is in the arbiter (decision) or the handover (timing). An assertion helps: request → eventual grant (liveness — no lost grant), no-starvation (bounded wait — fairness), handover-at-boundary and lock-held (legal handover). So in debug, an arbitration bug is a request/grant/owner trace (trace the three signals → classify lost-grant/starvation/bad-handover → trace to the arbiter's grant logic or the handover logic → fix). So in debug, watch the ownership signals and check policy + timing. So that's the method.

5. System Architecture Perspective

At the system level, arbitration bugs are fairness and liveness failures of the shared bus — affecting system-level properties (a starved master stalls its subsystem; a lost grant hangs a master; a bad handover corrupts a transfer) — and they're only in full-AHB multi-master systems (a reason AHB-Lite, which removes arbitration, is simpler).

The fairness/liveness system properties: arbitration governs system-level properties — liveness (every master eventually gets the bus — no hang) and fairness (no master starves). A lost grant breaks liveness (a master hangs, stalling its subsystem — e.g. a DMA that never gets the bus stalls the data transfer it serves). Starvation breaks fairness (a low-priority master — e.g. a display refreshnever gets the bus, failing its real-time deadline). So at the system level, arbitration bugs fail the liveness/fairness the system depends on. So they're system-property failures. So arbitration matters for the whole system.

The bad handover corrupts: a bad handover (mid-transfer/lock switch) corrupts a transfer (cut off) or breaks atomicity (a locked read-modify-write interrupted → a race) or causes contention (two masters driving). So it's a correctness (not just fairness) failure — data corruption or broken atomicity. So at the system level, a bad handover is a correctness bug. So handover correctness matters.

The only in multi-master systems: arbitration only exists in full-AHB multi-master systems (multiple masters sharing the bus). AHB-Lite is single-master — it removed arbitration (12.3) for simplicity. So arbitration bugs are specific to the multi-master case (and a reason AHB-Lite is simpler and more common for peripheral subsystems). So at the system level, arbitration bugs are fairness/liveness failures of the shared bus (a starved master fails its real-time deadline; a lost grant hangs a subsystem; a bad handover corrupts a transfer or breaks atomicity — system-property and correctness failures), specific to full-AHB multi-master systems (AHB-Lite removed arbitration for simplicity — 12.3). So arbitration bugs are where the multi-master sharing of the bus — the coordination that AHB-Lite avoids — can fail its fairness, liveness, and atomicity guarantees, making the arbiter and handover a critical (and full-AHB-specific) correctness point. So in multi-master systems, get the arbiter and handover right. So arbitration is the multi-master crux.

6. Engineering Tradeoffs

Debugging an arbitration bug embodies the watch-the-signals, classify, trace-the-policy-or-timing approach.

  • Joint trace vs single signal. Watching HBUSREQ/HGRANT/HMASTER together reveals the ownership flow (request → grant → owner → handover); a single signal misses the relationship. Trace them jointly.
  • Classify the three modes. Lost grant (liveness), starvation (fairness), bad handover (timing) are distinct — the classification points to the arbiter's grant logic, policy, or handover logic. Classify first.
  • Fairness policy vs strict priority. Round-robin/fairness (10.6) prevents starvation (every master gets a turn) at some priority cost; strict priority (10.5) is simple but starves low-priority masters. Use fairness where starvation matters.
  • Handover at boundaries vs preempt. Handover only at transfer/burst/lock boundaries preserves transfer integrity; preempting mid-flight corrupts. Respect the boundaries (and locks).

The throughline: an arbitration bug is a multi-master bus-ownership failure — lost grant (a request never granted or dropped before use → the transfer never happens), starvation (a low-priority master never granted → a fairness failure), or bad handover (ownership switching mid-transfer/burst/lock → an interrupted transfer or two masters driving). Diagnose by watching HBUSREQ/HGRANT/HMASTER together and checking liveness (request → grant), fairness (no starvation), legal handover (only at a transfer/burst boundary, bus idle-ready), and lock-held (locked sequences hold the grant). The cause is in the arbiter's grant logic (lost grant — grant-hold timing; starvation — fairness policy) or the handover logic (bad handover — boundary/lock timing). Fixes: round-robin/fairness (10.6), correct grant-hold, and respecting transfer/lock boundaries (10.9). It's a full-AHB multi-master bug — AHB-Lite removed arbitration (single-master — 12.3).

7. Industry Example

Debug three arbitration bugs in a multi-master SoC (CPU, DMA, display controller).

A multi-master AHB has a CPU (high priority), a DMA, and a display controller (low priority). Three issues: the display flickers (misses deadlines), the DMA occasionally hangs, and a locked CPU operation corrupts.

  • Bug 1 — starvation (display). The display controller (low priority) flickers — it misses its refresh deadlines. On the waveform, the display's HBUSREQ is persistently asserted but never granted — the CPU and DMA (higher priority) keep winning. This is starvation (a fairness failure). The arbiter uses strict priority (10.5) with no fairness. The fix: a fairness mechanism (round-robin among same-priority, or a guaranteed minimum bandwidth for the display — 10.6/10.7).
  • Bug 2 — lost grant (DMA). The DMA occasionally hangs — a transfer never happens. On the waveform, the DMA asserts HBUSREQ, the arbiter asserts HGRANT — but then drops it (before the DMA takes the bus, due to a timing bug). The DMA waits forever for an ownership that was granted then withdrawn. This is a lost grant (a liveness failure in the grant-hold timing). The fix: hold the grant until the master takes the bus (correct grant-hold timing).
  • Bug 3 — bad handover (locked CPU op). A CPU locked operation (a read-modify-write on a semaphore, HLOCK asserted) corrupts — the atomicity is broken. On the waveform, the HMASTER switches away from the CPU mid-lock (the arbiter preempted the locked sequence) — so another master interleaved an access, breaking the atomic RMW. This is a bad handover (a lock-preemption timing failure). The fix: the handover logic must respect HLOCKnever preempt a locked sequence (hold the grant until the lock releases).
  • The joint trace. All three were found by watching HBUSREQ/HGRANT/HMASTER together: starvation (request never granted while others win), lost grant (granted then dropped), bad handover (switched mid-lock). The classification (fairness/liveness/timing) pointed each to the right fix (policy/grant-hold/lock-respect).
  • Add assertions. You add liveness (request → eventual grant), bounded-wait (no starvation), handover-at-boundary, and lock-held assertions — catching all three classes automatically.

The example shows the three arbitration failure modes and the joint-signal method: starvation (display — fairness → round-robin), lost grant (DMA — liveness → grant-hold), bad handover (CPU lock — timing → respect HLOCK). Watching the three signals together and classifying sent each to the right fix. This is how you debug a multi-master bus. This is fair, live, atomic arbitration.

8. Common Mistakes

9. Interview Insight

Arbitration bugs are a solid debug interview topic — the joint-signal trace, the three-mode classification, and the handover-boundary/lock discipline are the signals.

A summary card on debugging arbitration bugs: the joint trace, the three modes, the checks, and the full-AHB scope.
Figure 4 — a strong answer in one card: watch HBUSREQ/HGRANT/HMASTER together; three modes — lost grant (request never granted/dropped), starvation (low-priority never granted), bad handover (mid-transfer/lock); checks — request→grant? no starvation? handover only at a legal boundary? locked sequence holds the grant?; the cause is in the arbiter / handover logic; full-AHB only (AHB-Lite is single-master). The senior point: watch request/grant/owner together — requests eventually granted, no starvation, handover only on a legal boundary.

The answer that lands gives the joint trace and the three-mode classification: "Arbitration is multi-master — full AHB, not AHB-Lite, which is single-master with no arbitration. The arbiter grants bus ownership using HBUSREQ and HGRANT, and HMASTER shows the current owner. To debug an arbitration bug, I watch those three signals together — request, grant, and owner — because arbitration is about the relationship between them: a master requests, the arbiter grants, the master takes ownership, runs its transfers, and hands over at a boundary. There are three failure modes. A lost grant: a master asserts HBUSREQ but is never granted, or the grant is dropped before the master takes the bus, so its transfer never happens — that's a liveness failure in the grant logic, often a grant-hold timing bug, and the fix is to hold the grant until the master takes the bus. Starvation: a low-priority master persistently requests but is never granted because higher-priority masters keep winning — that's a fairness failure in the policy, and the fix is a fairness mechanism like round-robin or a guaranteed minimum bandwidth. It's important not to confuse a lost grant with starvation: a lost grant is one specific request never completing, a grant-logic bug; starvation is a master systematically losing, a policy bug. The third is a bad handover: ownership switches at the wrong time — mid-transfer, mid-burst, or during a locked sequence — so a transfer is cut off, or a locked read-modify-write loses its atomicity, or two masters drive the bus around the switch. The fix is that handover must happen only at a legal boundary — the end of a transfer or burst with the bus ready — and must never preempt a locked sequence. So I check: does every request eventually lead to a grant, does every master eventually get a turn so none starves, does every HMASTER change coincide with a legal boundary, and do locked sequences hold the grant. The cause is always in the arbiter's grant logic or the handover logic." The joint-signal trace, the three-mode classification, and the handover-boundary/lock discipline are the senior signals.

10. Practice Challenge

Build and reason from debugging an arbitration bug.

  1. The three modes. Describe lost grant, starvation, and bad handover, and the signals you watch (HBUSREQ/HGRANT/HMASTER).
  2. Lost grant vs starvation. Explain the difference (liveness/grant-logic vs fairness/policy) and why it matters for the fix.
  3. Read the waveform. From Figure 2, explain how the HMASTER switch mid-burst is a bad handover and where the legal switch would be.
  4. Handover boundaries. Explain why handover must respect transfer/burst/lock boundaries and the consequence (especially mid-lock atomicity) of not.
  5. Multi-master scope. Explain why arbitration bugs are full-AHB-only and how AHB-Lite (single-master) relates.

11. Key Takeaways

  • An arbitration bug is a multi-master bus-ownership failurelost grant, starvation, or bad handover. The arbiter grants the bus via HBUSREQ/HGRANT; HMASTER = the owner.
  • Watch the three signals togetherHBUSREQ/HGRANT/HMASTER — and follow the ownership flow (request → grant → owner → handover); a break classifies the bug.
  • Lost grant ≠ starvationlost grant = a specific request never granted (liveness, grant-logic bug → grant-hold timing); starvation = a master persistently loses (fairness, policy bug → round-robin/fairness). Different fixes.
  • Bad handover must respect boundaries — handover only at a transfer/burst boundary (bus idle-ready), and never preempt a locked sequence. A mid-transfer switch cuts off the transfer; a mid-lock switch breaks atomicity (a race in a RMW).
  • The cause is the arbiter or handover logic — the grant decision (lost grant/starvation) or the handover timing (bad handover). Fixes: fairness policy, grant-hold, respect transfer/lock boundaries.
  • It's full-AHB multi-master onlyAHB-Lite is single-master with no arbitration (12.3 — a key simplification). Arbitration governs liveness, fairness, and atomicity — system-level properties.

12. What Comes Next

You now can debug a multi-master arbitration bug. The next chapters cover the hardest debug and the general method:

  • Bridge Deadlock (next) — find and break an AHB-to-APB bridge deadlock (the module's hardest debug).
  • Waveform-Based Debug Methodology — the general, repeatable method for debugging any AHB waveform.

To revisit arbitration, see HBUSREQ & HGRANT, Fixed-Priority Arbitration, Round-Robin Arbitration, Starvation, and Bus Ownership Handover; for locks, see Locked Transfers (HLOCK).