Skip to content

AMBA APB · Module 13

AHB-to-APB Bridge

The classic SoC bridge — an AHB slave on one side, an APB manager on the other, translating a pipelined high-performance transaction into APB's two-phase transfer. How the bridge captures the AHB address phase, sequences SETUP and ACCESS, holds HREADY low while APB waits, and returns data and response upstream.

So far APB has been a world unto itself — a manager, a bus, slaves. But in a real SoC, APB does not connect to the CPU directly. It hangs off a bridge that translates the high-performance system bus down to the quiet peripheral bus. This module is about those bridges, and the canonical one is the AHB-to-APB bridge. The single idea to carry: the bridge is an AHB slave on its upstream face and an APB manager on its downstream face, and its whole job is to turn one pipelined AHB transaction into one two-phase APB transfer — absorbing the impedance mismatch between a fast, pipelined protocol and a slow, unpipelined one. Every other chapter in this module is a facet of that translation; this one establishes the bridge as a dual-personality block and walks its core sequence.

1. Problem statement

The problem is connecting a high-performance, pipelined system bus (AHB) to the low-power, two-phase peripheral bus (APB) so that a CPU access to a peripheral register completes correctly, even though the two buses have fundamentally different timing, handshakes, and pipelining.

A CPU and its DMA live on AHB (or AXI); the timers, GPIO, and UART config live on APB. Something has to sit between them and reconcile two protocols that disagree on almost everything:

  • AHB is pipelined; APB is not. AHB overlaps the address phase of one transfer with the data phase of the previous one. APB is strictly sequential — SETUP then ACCESS, one transfer at a time, no overlap. The bridge must collapse AHB's pipeline into APB's serial cadence.
  • The handshakes are different signals with different rules. AHB flow-controls with HREADY; APB with PREADY. AHB reports errors as a two-cycle HRESP=ERROR; APB as a single-cycle PSLVERR. The bridge has to translate each handshake faithfully, in both directions.
  • The bridge is two masters' worth of personality in one block. Upstream it must behave as a fully-compliant AHB slave (accept the address phase, drive HREADY/HRDATA/HRESP). Downstream it must behave as a fully-compliant APB manager (drive PSEL/PENABLE/PADDR/PWRITE, sample PREADY/PSLVERR). Getting either personality subtly wrong breaks the whole peripheral subsystem.

So the job is not "wire AHB to APB" — it is to author a block that is simultaneously a correct AHB slave and a correct APB manager, and that maps every element of one transaction onto the other.

2. Why previous knowledge is insufficient

You have a complete picture of the APB side — phases, PREADY (Module 8), PSLVERR (Module 9), slave design (Module 11). What you have not had to reason about is APB as the downstream of another protocol:

  • You have only ever seen APB's manager from the inside. Every prior module assumed "the manager" issues transfers. Here the manager is the bridge, and it does not originate transfers — it relays them from an AHB transaction it is simultaneously servicing as a slave. The manager's behaviour is now driven by an upstream handshake, which no APB-only chapter covered.
  • The impedance mismatch is the new problem. APB's two-phase, unpipelined nature (the baseline) was just "how APB works." From the bridge's seat it is a constraint to absorb: AHB wants to pipeline and move on; APB forces it to wait. Reconciling those is the bridge's reason to exist, and it requires understanding both the AHB pipeline (AHB's two-phase pipeline) and APB's serial transfer at once.
  • Flow control now crosses a protocol boundary. A slow APB peripheral asserting PREADY=0 must somehow stall the AHB master. That cross-protocol back-pressure — APB wait becoming AHB wait via HREADY (AHB wait states) — has no analogue in single-protocol APB and is the subject of its own chapter.

So the model to add is APB-as-subordinate-bus: the bridge that consumes an AHB transaction and re-issues it as APB, translating handshake, error, and timing across the boundary.

3. Mental model

The model: the bridge is a bilingual receptionist between a fast executive (AHB) and a slow records clerk (APB). The executive hands over a request at speed and expects to keep moving; the receptionist takes it, walks it to the records clerk at the clerk's pace, waits at the counter until the clerk finishes, then turns back and reports the result to the executive — making the executive wait the whole time. The receptionist speaks both languages fluently and is, from each side's view, simply a peer: to AHB, a slave; to APB, a manager.

Three refinements make it precise:

  • Capture the AHB address phase, then act. AHB presents HADDR, HWRITE, HSIZE, HTRANS in the address phase. The bridge, as an AHB slave, registers these on the cycle it accepts the transfer, because the AHB address phase will move on (it is pipelined) but APB needs that address held stable across a whole two-phase transfer. The captured request is what drives the APB side.
  • Run one APB transfer per AHB transfer, serially. For each accepted AHB transfer the bridge sequences exactly one APB transfer: PSEL in SETUP, PSEL & PENABLE in ACCESS, then sample PREADY. It cannot start the next APB transfer until this one completes — APB does not pipeline — so the bridge naturally serialises, which is why it must stall AHB.
  • Stall AHB for as long as APB takes. The bridge holds HREADY low on the AHB side from the moment it starts the APB transfer until APB completes (PREADY high). One AHB access therefore costs at least the APB transfer's length (two cycles plus any APB wait states) — the bridge converts APB's latency into AHB wait states, then releases HREADY with the result.
A block diagram of an AHB-to-APB bridge: on the left an AHB slave interface to the AHB master with HADDR/HWRITE/HSIZE/HTRANS/HWDATA in and HRDATA/HREADY/HRESP out; a central bridge core with address-capture registers and an IDLE/SETUP/ACCESS FSM; on the right a full APB manager interface to the peripherals with PSEL/PENABLE/PADDR/PWRITE/PWDATA out and PRDATA/PREADY/PSLVERR in; arrows show PREADY-low becoming HREADY-low and PSLVERR becoming HRESP=ERROR.
Figure 1 — the AHB-to-APB bridge as a dual-personality block. On the left, the AHB side: the bridge presents an AHB slave interface (HADDR, HWRITE, HSIZE, HTRANS, HWDATA inputs; HRDATA, HREADY, HRESP outputs) to the AHB master (CPU/DMA). In the centre, the bridge core captures the AHB address-phase request into holding registers and runs a small FSM (IDLE → SETUP → ACCESS) that sequences one APB transfer per AHB transfer. On the right, the APB side: the bridge drives a full APB manager interface (PSEL, PENABLE, PADDR, PWRITE, PWDATA outputs; PRDATA, PREADY, PSLVERR inputs) to one or more APB peripherals. Arrows show the two cross-boundary translations the bridge performs: APB PREADY-low is converted into AHB HREADY-low (the peripheral stalls the CPU), and APB PSLVERR is converted into AHB HRESP=ERROR (the peripheral's failure becomes the CPU's bus fault). The figure frames the bridge as an AHB slave on one face and an APB manager on the other, collapsing a pipelined AHB transaction into APB's serial two-phase transfer.

4. Real SoC implementation

In RTL the bridge is an AHB slave whose accepted transfer drives a three-state APB FSM. The bridge registers the AHB address phase, then walks IDLE → SETUP → ACCESS, holding HREADY low until APB completes.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// AHB-to-APB bridge core: AHB slave upstream, APB manager downstream.
// One APB transfer per accepted AHB transfer; AHB is stalled until APB completes.
typedef enum logic [1:0] {IDLE, SETUP, ACCESS} state_t;
state_t state, nstate;
 
// --- AHB slave: accept a transfer in the address phase and CAPTURE it ---
// A valid AHB transfer is HTRANS=NONSEQ/SEQ while HSEL & HREADY (address phase).
wire ahb_accept = hsel && hready_in && htrans[1];   // htrans[1]=1 => NONSEQ/SEQ
always_ff @(posedge hclk or negedge hresetn)
  if (!hresetn) begin addr_q <= '0; write_q <= 1'b0; end
  else if (ahb_accept && state == IDLE) begin
    addr_q  <= haddr;        // hold the address across the whole APB transfer
    write_q <= hwrite;       // (the AHB address phase will move on; APB needs it stable)
  end
 
always_comb begin
  nstate = state;
  unique case (state)
    IDLE:   if (ahb_accept)        nstate = SETUP;          // got a transfer -> start APB
    SETUP:                          nstate = ACCESS;         // SETUP is always one cycle
    ACCESS: if (pready)             nstate = IDLE;           // hold here until APB completes
  endcase
end
always_ff @(posedge hclk or negedge hresetn)
  if (!hresetn) state <= IDLE; else state <= nstate;
 
// --- APB manager: drive the two-phase transfer from the captured request ---
assign psel    = (state == SETUP) || (state == ACCESS);
assign penable = (state == ACCESS);
assign paddr   = addr_q;
assign pwrite  = write_q;
assign pwdata  = hwdata_q;                       // HWDATA captured in the AHB data phase
 
// --- the two cross-boundary translations ---
// 1) APB wait -> AHB wait: stall the AHB master until the APB transfer completes.
assign hready_out = (state == IDLE) || (state == ACCESS && pready);
// 2) APB error -> AHB error: PSLVERR at completion becomes HRESP=ERROR upstream.
assign hresp      = (state == ACCESS && pready && pslverr) ? HRESP_ERROR : HRESP_OKAY;
assign hrdata     = prdata;                      // read data returned to the AHB master

Two facts make this the canonical pattern. First, the bridge must hold the AHB request stable for the whole APB transfer — AHB's address phase is pipelined and will present the next transfer's address while this one is still in APB ACCESS, so the bridge captures HADDR/HWRITE (and HWDATA when its data phase arrives) into holding registers; failing to capture is the classic bridge bug. Second, the two handshake translations are the bridge's essence: PREADY=0 becomes HREADY=0 (wait propagation) so a slow peripheral stalls the CPU, and PSLVERR becomes HRESP=ERROR (error propagation) so a peripheral fault becomes a CPU bus fault. Everything else — burst handling, multi-slave fan-out, address decode — layers on top of this core.

5. Engineering tradeoffs

A bridge's design choices trade latency, area, and how faithfully it preserves each protocol's semantics.

DecisionOption AOption BWhen to choose which
APB address captureRegister HADDR/HWRITE on acceptPass AHB signals straight throughAlways register — AHB's pipeline moves the address on; pass-through corrupts the APB transfer
Write-data timingCapture HWDATA in the AHB data phase, then drive PWDATAAssume HWDATA stable into APBCapture — AHB data phase is one cycle; APB needs it held across SETUP+ACCESS+waits
AHB stall granularityHold HREADY low for the whole APB transferTry to release earlyHold for the whole transfer — APB has no early-complete; releasing early loses the result
Burst handlingSerialise an AHB burst into N APB transfersReject/forbid bursts to APB spaceSerialise for a transparent bridge; many designs restrict peripheral space to single transfers
Bridge clockingSingle clock (AHB and APB on same clock)Separate APB clock (CDC in the bridge)Same clock is simplest; a divided/separate APB clock needs CDC and is a bigger design

The throughline: a faithful AHB-to-APB bridge registers the upstream request, serialises onto APB, and stalls AHB for exactly as long as APB takes — trading the CPU's cycles (wait states) for protocol correctness. The temptations that cause bugs are all attempts to avoid the stall or skip the capture; both break the contract.

6. Common RTL mistakes

7. Debugging scenario

The signature AHB-to-APB bridge bug is a corrupted peripheral access caused by not capturing the AHB address phase — the bridge lets AHB's pipeline move the address out from under the in-flight APB transfer.

  • Observed symptom: back-to-back CPU accesses to peripherals intermittently hit the wrong register — a write meant for peripheral A lands in peripheral B, or a read returns the next access's target. It only happens when AHB transfers are pipelined back-to-back (no idle cycle between them); a single isolated access always works.
  • Waveform clue: on the AHB side, HADDR advances to the second transfer's address while the bridge is still in APB ACCESS for the first. On the APB side, PADDR — wired through from HADDR instead of a captured register — changes mid-transfer, so the APB peripheral sees the first transfer's PSEL/PENABLE but the second transfer's address on the completing edge.
  • Root cause: the bridge drove PADDR (and PWRITE) directly from the live AHB address-phase signals instead of from registers captured when the transfer was accepted. Because AHB pipelines the address phase, those signals belong to the next transfer by the time APB reaches ACCESS — so the in-flight APB transfer completes against a moving address.
  • Correct RTL: capture the AHB request on accept and drive APB from the capture — if (ahb_accept && state==IDLE) begin addr_q <= haddr; write_q <= hwrite; end then assign paddr = addr_q; — so the APB address is frozen for the whole two-phase transfer regardless of what the AHB pipeline does next.
  • Verification assertion: assert that the APB address is stable across the entire APB transfer — assert property (@(posedge hclk) disable iff(!hresetn) (psel && !(penable && pready)) |=> $stable(paddr) && $stable(pwrite)); — and a higher-level scoreboard check that each AHB transfer's address/data reaches the APB peripheral it targeted.
  • Debug habit: when a pipelined bus bridge corrupts transfers only under back-to-back traffic, suspect a capture failure first — check whether the downstream (APB) request signals are driven from registers or straight from the live upstream (AHB) phase. A bridge between a pipelined and an unpipelined protocol must register the upstream request; a wired-through address is the classic defect, invisible until the pipeline actually overlaps two transfers.
Two stacked timing diagrams over two back-to-back AHB transfers: the top correct case captures HADDR into addr_q so PADDR stays frozen across the APB transfer in green; the bottom buggy case wires PADDR from live HADDR, so when the AHB address phase advances to the next transfer PADDR changes mid-APB-transfer and the access hits the wrong address, drawn in red.
Figure 2 — the address-capture bug, on two back-to-back AHB transfers. Top (correct, green): the bridge captures HADDR into addr_q when it accepts transfer 1, and drives PADDR from addr_q; even though the AHB address phase advances to transfer 2's address during APB ACCESS, PADDR stays frozen on transfer 1's address and the APB transfer completes against the right register. Bottom (bug, red): the bridge wires PADDR straight from the live HADDR; when AHB pipelines transfer 2's address into the address phase while APB is still in ACCESS for transfer 1, PADDR changes mid-transfer, so transfer 1 completes against transfer 2's address — the access lands on the wrong peripheral. The figure shows the defect is a missing capture register at the pipelined-to-unpipelined boundary, and that it only manifests when AHB transfers overlap back-to-back.

8. Verification perspective

A bridge is verified as two protocol-compliant interfaces plus the mapping between them — and the highest-value checks live exactly at the boundary where the two protocols' assumptions collide.

  • Bind a protocol checker to each face. Run a full AHB slave protocol monitor on the upstream side and a full APB manager protocol monitor on the downstream side, simultaneously. The bridge must be independently legal as an AHB slave and as an APB manager; a VIP on each face catches a malformed handshake on either side before you even reason about the translation.
  • Assert the cross-boundary mappings hold every transfer. The two translations are the bridge's contract: assert PREADY=0 keeps HREADY=0 (the AHB master is stalled for the whole APB wait), and assert PSLVERR at APB completion produces HRESP=ERROR upstream (and that a clean APB completion never does). Add the capture/stability property — the APB request is $stable across its transfer — because that is the defect a pure per-protocol check misses.
  • Cover the pipeline-collision and corner cases. Functional coverage must include back-to-back AHB transfers (the pipeline actually overlapping, which exposes capture bugs), an APB transfer with zero and with N wait states (the stall length varying), a PSLVERR on read and on write, and — if bursts are allowed — an AHB burst serialised into multiple APB transfers. A bridge that is only ever tested with isolated, zero-wait, error-free accesses has a coverage hole exactly where bridges break.

The point: verify the bridge as two compliant interfaces and the handshake/error/stability mappings between them, and cover the pipeline overlap and wait/error corners — the per-protocol monitors alone will pass a bridge that still corrupts transfers at the boundary.

9. Interview discussion

"Walk me through an AHB-to-APB bridge" is a staple SoC-integration question, and the strong answer leads with the dual personality and the impedance mismatch, not a signal list.

Frame it as an AHB slave on one face and an APB manager on the other, collapsing a pipelined transaction into a two-phase transfer. State the core sequence: the bridge captures the AHB address phase (because AHB pipelines and the address moves on, while APB needs it held), runs one APB transfer (SETUP then ACCESS), and holds HREADY low to stall the AHB master until PREADY completes the APB transfer. Then deliver the depth that separates senior answers: the two cross-boundary translationsPREADY=0 → HREADY=0 (a slow peripheral stalls the CPU) and PSLVERR → HRESP=ERROR (a peripheral fault becomes a bus fault) — and the capture requirement (driving APB straight from live AHB signals corrupts back-to-back transfers because the pipeline advances the address mid-transfer). Mentioning that one AHB access costs the whole APB transfer (two cycles plus APB waits), surfaced as AHB wait states, shows you understand the bridge converts latency into stalls. Closing with "the AHB-to-APB and AXI-to-APB bridges differ mostly in the upstream handshake — five independent AXI channels versus AHB's pipeline — but the APB side is identical" signals breadth.

10. Practice

  1. Name the personalities. State which protocol the bridge is a slave of and which it is a manager of, and list the signals it drives versus samples on each face.
  2. Sequence one transfer. For a single AHB read to a peripheral, walk the bridge through IDLE → SETUP → ACCESS, marking when HREADY goes low and when it is released.
  3. Map the handshakes. State what PREADY=0 becomes on the AHB side, and what PSLVERR becomes, and why each translation is mandatory.
  4. Justify the capture. Explain why the bridge must register HADDR/HWRITE on accept rather than wire them through, in terms of AHB's pipeline.
  5. Cost the access. For an APB transfer with two wait states, count the AHB wait states the bridge inserts for one access, and explain where they come from.

11. Q&A

12. Key takeaways

  • The bridge is dual-personality: an AHB slave upstream and an APB manager downstream, collapsing one pipelined AHB transaction into one two-phase APB transfer.
  • Capture the AHB address phase. AHB pipelines and advances the address to the next transfer; the bridge must register HADDR/HWRITE/HWDATA on accept and drive APB from the capture, or back-to-back transfers corrupt each other.
  • Serialise and stall. The bridge runs one APB transfer per AHB transfer and holds HREADY low for the whole thing — converting APB's latency (two cycles plus wait states) into AHB wait states.
  • Two cross-boundary translations are the bridge's essence: PREADY=0 → HREADY=0 (a slow peripheral stalls the CPU) and PSLVERR → HRESP=ERROR (a peripheral fault becomes a bus fault).
  • The classic bug is a missing capture — wiring PADDR from live HADDR — which only manifests when the AHB pipeline overlaps back-to-back transfers and the APB address moves mid-transfer.
  • Verify it as two compliant interfaces plus the mapping — an AHB slave monitor and an APB manager monitor, the wait/error/stability assertions, and coverage of pipeline overlap and wait/error corners.