Skip to content

AMBA AHB · Module 16

HREADYOUT Generation

Implementing correct per-slave HREADYOUT timing — the slave output saying 'I can complete the current transfer this cycle' (high) or 'insert a wait state' (low). A zero-wait slave ties it high; a wait slave drives it from a counter/FSM modeling the access latency. Crucially, HREADYOUT (the slave's output) is not HREADY (the shared input — the selected slave's HREADYOUT routed back to all); gate the address-phase capture on HREADY, not your own HREADYOUT, and never drive HREADYOUT high before genuinely ready.

The last three chapters built whole slaves; this chapter zooms in on the single most timing-critical output a slave drives: HREADYOUT. Every AHB slave drives a HREADYOUT that answers one question each cycle — "can I complete the current transfer this cycle?" High means yes, finish now; low means no, insert a wait state (hold the master — chapter 6.2). A zero-wait slave (the simple slave, the register bank) ties HREADYOUT high — it's always ready. A wait-inserting slave (the memory slave, a slow peripheral) drives HREADYOUT from a small counter or FSM that models the access latencylow while the access is in progress, high in the cycle it can genuinely finish. The chapter's other half is a crucial distinction most beginners get wrong: HREADYOUT (the slave's output) is not HREADY (the slave's input). HREADY is the shared bus-ready signal — the interconnect selects the addressed slave's HREADYOUT and routes it back to every slave (and the master), so all slaves know when the current bus transfer actually completes (HREADY vs HREADYOUT). This chapter implements correct HREADYOUT generation — the timing contract at the heart of every slave.

1. What Is It?

HREADYOUT generation is the slave logic that drives the HREADYOUT output — the slave's per-cycle statement of whether it can complete the current transfer. Its parts:

  • The meaningHREADYOUT high = "I can complete the current transfer this cycle"; low = "not ready — insert a wait state" (hold the master).
  • Zero-wait — a slave that always responds in one cycle ties HREADYOUT high (no logic needed).
  • Wait-inserting — a slave with latency drives HREADYOUT from a counter/FSM modeling the access: low while not ready, high when ready.
  • HREADYOUT ≠ HREADYHREADYOUT is the slave's output; HREADY is the shared input (the selected slave's HREADYOUT routed back to all slaves and the master).
HREADYOUT generation: captured context → ready logic (tie-high or counter/FSM) → HREADYOUT output, with HREADY as a separate input.
Figure 1 — generating HREADYOUT. The slave decides, each cycle, whether it can complete the current transfer. A zero-wait slave ties HREADYOUT high. A wait-inserting slave uses a counter/FSM (fed by the captured context — sel_q, the memory-ready condition, access-in-progress) to drive HREADYOUT low while not ready and high in the cycle it can finish. The HREADYOUT output goes to the interconnect, which forms the shared HREADY; the slave also receives HREADY as an input. Drive HREADYOUT high only when the slave can genuinely complete, and qualify wait insertion to a real selected transfer.

So HREADYOUT generation is the slave's timing contract: it tells the bus, every cycle, whether the slave is done (high) or needs more time (low). For a zero-wait slave, this is trivial — tie it high (the slave is always ready, so it never stalls the bus). For a wait-inserting slave, it's the core timing logic — a counter or FSM that models how many cycles the access needs and drives HREADYOUT low for the wait cycles, high in the cycle the access completes. The discipline is twofold: (1) drive HREADYOUT high only in the cycle the slave can genuinely finish (too early → the master samples garbage; chapter 16.3), and (2) don't confuse HREADYOUT (output) with HREADY (input). So HREADYOUT generation is the timing heart of a slave — the signal that paces every transfer. So it's the most timing-critical slave output.

2. Why Does It Exist?

HREADYOUT exists because the bus protocol is fixed-rhythm (one transfer advances per cycle when ready), but slaves have varying speeds — so each slave needs a per-cycle signal to say "ready" or "not ready", and the bus needs to combine these into a single shared pace.

The per-slave ready signal is the root: the bus advances a transfer when the addressed slave is ready. But slaves differ — a fast SRAM is ready immediately, a slow flash needs cycles, a busy peripheral may stall. So each slave needs a way to say, each cycle, whether it's ready — and that's HREADYOUT. So HREADYOUT exists as the slave's per-cycle ready statement. So the bus can know when this slave is done. So it's the slave's pace signal.

The shared bus pace drives the HREADY distinction: the bus has one master pacing one transfer at a time, but many slaves. Only the addressed slave's readiness matters for the current transfer — yet every slave (and the master) needs to know when the current transfer completes (to advance their own pipelines correctly). So the interconnect selects the addressed slave's HREADYOUT and broadcasts it as the shared HREADY — the one signal that paces the whole bus. So HREADYOUT (per-slave) and HREADY (shared) exist as two signals: each slave drives its HREADYOUT, the interconnect combines them (by selection) into the shared HREADY, and everyone receives HREADY. So the two-signal structure exists to turn many per-slave readinesses into one shared bus pace. So it's per-slave out, shared in. So the distinction is structural.

The correct timing requirement is why generation is delicate: because HREADYOUT paces the transfer, getting its timing right is critical. Drive it high too early (before the data is ready) and the master samples garbage (corruption). Drive it low forever (stuck) and the bus hangs (chapter 18.1). Drive it low on an idle cycle (unqualified) and you stall the bus needlessly. So HREADYOUT generation must be precisely timed — high exactly when ready, low only for genuine waits on real transfers. So the logic (tie-high for zero-wait, counter/FSM for waits) exists to get this timing right. So HREADYOUT exists because: the bus advances on slave readiness (the per-slave ready signal — the why); the bus needs one shared pace from many slaves (the interconnect selects and broadcasts the addressed slave's HREADYOUT as the shared HREADY — the two-signal structure); and the timing must be precise (high exactly when ready, low only for real waits — driving the careful generation logic). So HREADYOUT is the slave's contribution to the bus's pace — the per-cycle "ready/not-ready" that, selected and broadcast as HREADY, paces every transfer on the bus. So generating it correctly is foundational to a working slave. So this chapter gets the pace signal right.

3. Mental Model

Model HREADYOUT as each chef in a kitchen raising or lowering a "dish ready" paddle — paddle up means "this dish is plated, send it out now", paddle down means "still cooking, the waiter must wait". The head waiter (the interconnect) watches only the chef cooking the current order (the addressed slave) and rings a single shared bell (HREADY) when that chef's paddle is up — and everyone in the kitchen hears the bell, so they all know the current order just went out.

A kitchen of chefs (the slaves), each cooking to order. Each chef has a "dish ready" paddle (HREADYOUT). When a chef's dish is plated and ready, they raise the paddle (HREADYOUT high) — "send it out now". When the dish is still cooking, the paddle stays down (HREADYOUT low) — "the waiter must wait". A fast chef (a zero-wait slave) always has the paddle up — their dishes are instant (the paddle is nailed up). A slow chef (a wait-inserting slave) keeps the paddle down while cooking and raises it the moment the dish is done — and they know how long each dish takes (a counter/FSM modeling the latency). Now, the head waiter (the interconnect) is handling one order at a time, and watches only the chef cooking that order (the addressed slave). When that chef's paddle goes up, the head waiter rings a single shared bell (HREADY) — "the current order is ready, it's going out". Crucially, everyone in the kitchen hears the bellall the chefs, and the expediter (the master). They need to hear it: the bell tells them the current order just completed, so they can advance — start prepping the next order, clear the pass, etc. So the paddle is each chef's own signal (raise it when your dish is ready), but the bell is the shared signal (rung from the current chef's paddle, heard by all). A chef must not raise the paddle before the dish is actually ready — sending out a half-cooked dish (the master sampling garbage). And a chef shouldn't keep the paddle down when there's no order for them (stalling the pass needlessly — an unqualified wait on an idle cycle).

This captures HREADYOUT: each chef's paddle = each slave's HREADYOUT output; paddle up = HREADYOUT high (ready, complete now); paddle down = HREADYOUT low (wait state); the always-up paddle = a zero-wait slave (tie high); the slow chef raising it when done, knowing the cook time = a wait slave's counter/FSM; the head waiter watching only the current chef = the interconnect selecting the addressed slave's HREADYOUT; the single shared bell heard by all = the shared HREADY broadcast to every slave and the master; not raising the paddle on a half-cooked dish = not driving HREADYOUT high before ready (no garbage); not holding the paddle down with no order = qualifying waits to a real selected transfer. Each chef's own paddle, one shared bell rung from the current chef's.

Watch a zero-wait slave and a wait-inserting slave drive HREADYOUT, and the shared HREADY follow the selected one:

Per-slave HREADYOUT and the shared HREADY

5 cycles
Slave A is zero-wait (HREADYOUT_A always high). Slave B inserts one wait (HREADYOUT_B low in cycle 3, high in cycle 4). The shared HREADY follows the selected slave: high while A is addressed, then low in cycle 3 and high in cycle 4 while B is addressed.A addressed, zero-wait — HREADY high (completes)A addressed, zero-wait…B addressed, inserts a wait — HREADY low (selected B's HREADYOUT)B addressed, inserts a…B ready — HREADY high (completes)B ready — HREADY high …HCLKaddressed slaveAABBBHREADYOUT_AHREADYOUT_BHREADY (shared)t0t1t2t3t4
Figure 2 — two slaves' HREADYOUT, and the shared HREADY following the selected one. Cycles 0-1: the master addresses Slave A (a zero-wait slave) — HREADYOUT_A is high throughout, so when A is selected, the shared HREADY is high (A's transfer completes in one cycle). Cycles 2-4: the master addresses Slave B (a wait-inserting slave) — HREADYOUT_B goes low in cycle 3 (B inserts a wait), then high in cycle 4; so the shared HREADY (now following B, the selected slave) is low in cycle 3 and high in cycle 4. HREADY always mirrors the currently-addressed slave's HREADYOUT. (HREADYOUT_A stays high even while B is selected — but it's ignored, because A isn't addressed.)

The model's lesson: each slave drives its own HREADYOUT paddle; the shared HREADY is rung from the currently-addressed slave's paddle and heard by all. In the waveform, the shared HREADY follows whichever slave is addressed — high for zero-wait A, then low-then-high for wait-inserting B.

4. Real Hardware Perspective

In hardware, HREADYOUT is a single output wire driven either by a constant (zero-wait) or by a small counter/FSM (wait-inserting); the interconnect builds the shared HREADY by muxing the addressed slave's HREADYOUT; and the slave consumes HREADY to pace its own pipeline.

The zero-wait tie-high: for a slave that always completes in one cycle (the simple slave 16.1, the register bank 16.2 — combinational read, single-cycle write), HREADYOUT is tied high (assign HREADYOUT = 1'b1;). No logic, no flop — the slave is always ready. So in hardware, a zero-wait slave's HREADYOUT is a constant. So it costs nothing. So zero-wait is the cheap case.

HREADYOUT per-slave outputs feeding an interconnect mux that forms the shared HREADY broadcast back to all slaves and the master.
Figure 3 — HREADYOUT (output) vs HREADY (input). Each slave drives its own HREADYOUT (Slave A drives HREADYOUT_A, Slave B drives HREADYOUT_B). The interconnect selects the addressed slave's HREADYOUT and routes it back as the shared HREADY, broadcast to all slaves and the master. So HREADYOUT is per-slave (this slave's readiness); HREADY is shared (the selected slave's readiness, seen by everyone). A slave drives HREADYOUT to control its own transfers and consumes HREADY to know when the current bus transfer completes.

The wait-inserting counter/FSM: for a slave with latency (the memory slave 16.3, a slow peripheral), HREADYOUT is driven by a small counter or FSM. When a real access starts (sel_q and a transfer in the data phase), the slave drives HREADYOUT low and counts the access latency; while counting, HREADYOUT stays low (wait states); when the count expires (the access can complete), HREADYOUT goes high for one cycle (completing the transfer), then the slave is ready for the next. The FSM ensures HREADYOUT is low exactly for the wait cycles and high exactly when ready. So in hardware, a wait slave's HREADYOUT is sequential logic modeling the latency. So it's a counter/FSM. So waits cost a little logic.

The interconnect mux and the HREADY input: the interconnect forms the shared HREADY by selecting the addressed slave's HREADYOUTHREADY = HREADYOUT[selected_slave] (a mux driven by the address decode — chapter 13.7, HREADY aggregation). This HREADY is broadcast to all slaves and the master. Each slave consumes HREADY as an input — it tells the slave when the current bus transfer completes, which the slave needs to advance its own address-phase capture correctly (recall 16.1: the slave captures the address-phase context gated on HREADY high — because the address phase is only valid to capture when the previous transfer is completing). So in hardware, HREADY is a separate input the slave uses to pace its capture — distinct from the HREADYOUT it drives. So in hardware, HREADYOUT generation is a constant (zero-wait) or a counter/FSM (wait), the interconnect muxes the addressed HREADYOUT into the shared HREADY, and the slave consumes HREADY to pace its capture. The two signals — HREADYOUT out, HREADY in — are physically distinct wires with distinct roles. So in hardware, keep them separate. So the wiring distinguishes them.

5. System Architecture Perspective

At the system level, HREADYOUT/HREADY is the bus's flow-control mechanism — the way the single shared bus paces itself to the speed of whichever slave is currently addressed — and its correctness is foundational: a single mistimed or stuck HREADYOUT can corrupt data or hang the entire bus.

The bus flow control: HREADYOUT/HREADY is the flow-control signal of AHB — it's how the bus adapts its pace to the current slave. When a fast slave is addressed, HREADY is high and transfers fly by (one per cycle); when a slow slave is addressed, HREADY drops (wait states) and the bus slows to match. So at the system level, HREADYOUT/HREADY is the throttle — the mechanism that paces the bus to the addressed slave. So it's how the bus handles heterogeneous slave speeds. So it's the flow-control backbone.

The single-point criticality: because HREADY is shared and paces the whole bus, a single slave's HREADYOUT bug has system-wide consequences. If one slave drives HREADYOUT high too early, the master samples garbage on that slave's transfers (data corruption). If one slave gets stuck with HREADYOUT low (a hung FSM, a missed completion), the shared HREADY (when that slave is addressed) is stuck low — and the entire bus hangs (the master waits forever — chapter 18.1, stuck HREADY). So at the system level, every slave's HREADYOUT must be correct — a single faulty slave can break the whole bus. So HREADYOUT correctness is a system property, not a local one. So it's a single point of failure. So get every slave's HREADYOUT right.

The timeout protection: because a stuck HREADYOUT hangs the bus, systems often add a timeout/watchdog — if HREADY stays low too long (a slave that never completes), a bus watchdog triggers an error/recovery (rather than hanging forever). So at the system level, the risk of a stuck HREADYOUT is mitigated by timeout logic. So robust systems guard against the single-point failure. So at the system level, HREADYOUT/HREADY is the bus's flow-control mechanism (the throttle pacing the bus to the addressed slave — adapting to heterogeneous speeds), its correctness is a system property (a single mistimed HREADYOUT corrupts data; a single stuck one hangs the whole bus — chapter 18.1), and robust systems add timeout/watchdog protection against stuck-ready hangs. So HREADYOUT is where a local slave decision becomes a global bus behavior — making its correct generation one of the most consequential pieces of slave RTL. So pace correctly, never stick, and guard with timeouts.

6. Engineering Tradeoffs

HREADYOUT generation embodies the ready/not-ready, per-slave-vs-shared, precisely-timed design.

  • Tie-high (zero-wait) vs counter/FSM (wait). Tie-high is free and fast (no logic) but requires the slave to truly be single-cycle; a counter/FSM handles latency at the cost of sequential logic. Tie high only if genuinely zero-wait.
  • Combinational vs registered HREADYOUT. A combinational HREADYOUT (derived from current state) can respond fast but may create long paths / timing pressure; a registered HREADYOUT eases timing but must be planned a cycle ahead. Choose by timing closure.
  • Drive high exactly when ready vs conservatively late. Driving HREADYOUT high exactly when ready maximizes performance but demands precise latency modeling; an extra wait (conservative) is safe but slower. Be precise, but never early.
  • Per-slave correctness vs system robustness. Relying on every slave's HREADYOUT being correct is the ideal but fragile (one bug hangs the bus); adding a bus timeout/watchdog costs logic but contains the failure. Add a timeout in robust systems.

The throughline: HREADYOUT is the slave's per-cycle output stating whether it can complete the current transfer — high to finish now, low to insert a wait state (hold the master — chapter 6.2). A zero-wait slave ties it high; a wait-inserting slave drives it from a counter/FSM modeling the access latency (low while not ready, high when ready). It must be driven high only when the slave can genuinely finish (too early → garbage; chapter 16.3) and never stick low (hangs the bus; chapter 18.1). Critically, HREADYOUT (the slave's output) is not HREADY (the shared input — the interconnect selects the addressed slave's HREADYOUT and broadcasts it to all slaves and the master). Qualify wait insertion to a real selected transfer. It's the bus's flow-control signal — local correctness with system-wide consequence.

7. Industry Example

Trace HREADYOUT across a fast SRAM, a slow flash, and the interconnect that combines them.

A system has a zero-wait SRAM (Slave A) and a 4-cycle flash (Slave B) on the bus.

  • SRAM (Slave A) — tie-high. The SRAM is single-cycle, so HREADYOUT_A = 1 always (tied high). When the master addresses A, the interconnect selects HREADYOUT_A as the shared HREADY — which is high — so A's transfers complete one per cycle. No wait logic.
  • Flash (Slave B) — counter FSM. The flash needs 4 cycles. When the master addresses B with a real read (sel_q and a transfer), B's FSM drives HREADYOUT_B low and loads a 3-count; for 3 cycles HREADYOUT_B stays low (3 wait states); on the 4th cycle (data ready), HREADYOUT_B goes high, completing the read. The FSM models the flash's latency exactly.
  • The interconnect — select and broadcast. The interconnect forms the shared HREADY by selecting the addressed slave's HREADYOUT: when A is addressed, HREADY = HREADYOUT_A; when B is addressed, HREADY = HREADYOUT_B. The shared HREADY is broadcast to A, B, and the master. So HREADY is high during A's transfers and low-for-3-then-high during B's.
  • The slaves consume HREADY. Both A and B use the shared HREADY (not their own HREADYOUT) to gate their address-phase capture — they sample the next address phase only when HREADY is high (the current transfer completing). So even Slave A, while B is mid-wait and B is addressed, paces its pipeline by the shared HREADY.
  • A stuck-ready guard. A bus watchdog watches HREADY: if it stays low for, say, 256 cycles (a slave that never completes — a flash fault), the watchdog triggers an error, preventing a permanent hang.

The example shows HREADYOUT across the speed spectrum and the per-slave/shared distinction: the SRAM ties it high (zero-wait), the flash drives it from a counter FSM (4-cycle latency), the interconnect selects and broadcasts the addressed slave's HREADYOUT as the shared HREADY, the slaves consume HREADY (not HREADYOUT) to pace their capture, and a watchdog guards against a stuck-ready hang. This is HREADYOUT generation in a real multi-slave system. This is the bus's flow control.

8. Common Mistakes

9. Interview Insight

HREADYOUT generation is a sharp RTL interview topic — the high/low meaning, the zero-wait-vs-counter distinction, and especially the HREADYOUT-vs-HREADY separation are the signals.

A summary card on HREADYOUT generation: meaning, zero-wait vs counter/FSM, the HREADY distinction, and the timing rules.
Figure 4 — a strong answer in one card: HREADYOUT is the slave's output (high = can finish this cycle, low = insert a wait); zero-wait ties it high, a wait slave drives it from a counter/FSM modeling latency; don't confuse it with HREADY (the shared input = selected slave's HREADYOUT routed back to all); qualify waits to a real transfer, and never drive high before ready. The senior point: HREADYOUT high means 'I can finish this cycle', low inserts a wait, and HREADY is the shared bus version fed back to everyone.

The answer that lands gives the meaning and the distinction: "HREADYOUT is the slave's output that says, each cycle, whether it can complete the current transfer — high means I can finish this cycle, low means insert a wait state and hold the master. A zero-wait slave, like a simple register slave, just ties HREADYOUT high — it's always ready. A slave with latency, like a memory slave on a slow flash, drives HREADYOUT from a small counter or FSM that models the access latency: low while the access is in progress, high in the cycle it can genuinely complete. Two things are critical. First, you drive HREADYOUT high only when you're truly ready — if you drive it high before the data is ready, the master samples garbage, a data-corruption bug. And you must never get stuck low, because that hangs the whole bus. Second — and this is the one people get wrong — HREADYOUT is not HREADY. HREADYOUT is this slave's output, its own readiness. HREADY is the shared bus-ready input: the interconnect selects the currently-addressed slave's HREADYOUT and routes it back to every slave and the master. A slave drives HREADYOUT to control its own transfers, but consumes HREADY to know when the current bus transfer completes — and it gates its address-phase capture on HREADY, the bus's pace, not on its own HREADYOUT. If you mix them up and gate on HREADYOUT, you mis-time the slave's pipeline — a subtle bug that hides in a single-slave testbench and surfaces in a real multi-slave system. So: output your readiness as HREADYOUT, input the bus pace as HREADY." The high/low meaning, the zero-wait-vs-FSM, and the HREADYOUT/HREADY separation are the senior signals.

10. Practice Challenge

Build and reason from HREADYOUT generation.

  1. The meaning. State what HREADYOUT high and low mean, and how a zero-wait slave vs a wait-inserting slave drives it.
  2. HREADYOUT vs HREADY. Explain the difference (output vs input), how the interconnect forms HREADY, and who receives it.
  3. Read the waveform. From Figure 2, explain how the shared HREADY follows the addressed slave (zero-wait A, then wait-inserting B).
  4. Gate on HREADY. Explain why a slave gates its address-phase capture on HREADY, not its own HREADYOUT, and the bug otherwise.
  5. Timing failures. Explain the consequences of driving HREADYOUT high too early, stuck low, and too late.

11. Key Takeaways

  • HREADYOUT is the slave's per-cycle output stating whether it can complete the current transfer — high = finish now; low = insert a wait state (hold the master — chapter 6.2).
  • Zero-wait slaves tie HREADYOUT high; wait-inserting slaves drive it from a counter/FSM modeling the access latency (low while not ready, high when ready).
  • HREADYOUT (output) ≠ HREADY (input)HREADYOUT is this slave's own readiness; HREADY is the shared signal (the interconnect selects the addressed slave's HREADYOUT and broadcasts it to all slaves and the master).
  • Gate address-phase capture on HREADY, not HREADYOUT — the slave's pipeline must advance with the bus's pace; using HREADYOUT mis-times capture (a subtle multi-slave bug).
  • Drive HREADYOUT high only when genuinely ready (too early → garbage — chapter 16.3) and never stick low (hangs the bus — chapter 18.1); qualify waits to a real selected transfer.
  • It's the bus's flow-control signal — a local slave decision with system-wide consequence; robust systems add a timeout/watchdog against stuck-ready hangs.

12. What Comes Next

You now can generate HREADYOUT correctly. The next chapters complete the slave's output paths:

  • HRDATA Muxing (next) — build the read-data return path and the slave read mux.
  • HRESP Generation, Address / Control Capture, and the FSMs — the rest of the slave RTL.

To revisit the wait-state mechanism HREADYOUT implements, see Slave-Inserted Wait States and HREADY vs HREADYOUT; for the slave this paces, see A Simple AHB-Lite Slave.