Skip to content

A bridge bug is never an APB bug or an upstream bug alone — it lives in the translation between them, where the bridge has two personalities and one mistake in either direction corrupts a transfer that both protocols would call legal. You have built the AHB-to-APB bridge and the AXI-to-APB bridge as dual-personality blocks — an upstream slave, a downstream APB manager — and learned the two cross-boundary translations they exist to perform: wait propagation (APB PREADY=0 must stall the upstream master) and error propagation (APB PSLVERR must become the upstream error response). This chapter inverts that into a debugging instrument. It is the catalog of bugs that exist only in the bridge — the failures you cannot find by staring at the APB side alone or the upstream side alone, because each is a break in the mapping between the two. The single idea to carry: when a peripheral access "works in isolation but corrupts under back-to-back traffic," or "the CPU sees OKAY on a failed write," or "the bus hangs only across the bridge," do not debug one protocol — debug the translation, and it is almost certainly one of the six bridge bugs below.

1. Problem statement

The problem is that a bridge sits on a fault line between two protocols that disagree on timing, handshake, error encoding, and pipelining — and every bridge bug is the bridge getting one of those disagreements wrong, in a way neither protocol's own checker can see.

The upstream bus (AHB or AXI) is pipelined, fast, and flow-controls with hready / channel-ready; APB is two-phase, slow, and flow-controls with pready. The upstream reports errors as a multi-cycle hresp=ERROR or an AXI rresp/bresp=SLVERR; APB reports them as a single-beat pslverr. The bridge has to reconcile all of this, and a defect in the reconciliation produces a transfer that is individually legal on each face yet semantically wrong end-to-end. Three structural facts make these bugs distinctive:

  • The bug is in the mapping, not in either protocol. A bridge that releases hready while pready is still low has issued a perfectly legal AHB completion and obeyed APB on its own face — but the translation (APB wait must become AHB wait) is broken, so the CPU completes early on stale data. No single-protocol monitor flags it, because no single protocol was violated.
  • The bug crosses a rate and pipeline boundary, so it hides until the boundary is stressed. A missing address capture is invisible until the upstream pipeline actually overlaps two transfers; a collapsed SETUP gap is invisible until two upstream transfers abut with zero idle. Isolated, zero-wait, error-free accesses pass — the bridge bug needs the boundary exercised to appear.
  • The bug is asymmetric — wrong in one direction. Wait propagation is upstream-stalls-on-downstream; error mapping is downstream-fault-becomes-upstream-fault. A bridge can get the data path perfect and the control translation backwards: the wait that should propagate does not, or the error that should map maps on the wrong beat. The direction of the failure is the diagnostic.

So the job of this chapter is to name the bridge-only failure modes — lost wait propagation, wrong error mapping, dropped/duplicated transfer, collapsed SETUP gap, moving address across the rate change, response phase not aligned — give each a symptom, a root cause in the bridge FSM or the cross-boundary logic, the wrong-versus-right RTL, and the fix that restores the translation.

2. Why previous knowledge is insufficient

This module has taught you the bridge as a correct block and each cross-boundary translation as a mechanism — but it has not assembled the failure taxonomy of the bridge, and the bridge is exactly where the translations break.

  • The AHB-to-APB bridge chapter taught the bridge's structure and one classic defect — the missing address capture. That is one bridge bug, taught in full; here it is one entry in a six-bug catalog, summarised and linked, sitting beside five others (lost wait, wrong error beat, dropped/duplicated transfer, collapsed SETUP gap, response misalignment) that it never enumerated.
  • Wait-state propagation taught how PREADY=0 should become upstream back-pressure. That is the correct mechanism. This chapter is about the cases where the bridge gets it wrong — releases the upstream ready early, or stalls forever, or stalls the wrong channel — which the mechanism chapter assumed away.
  • Error propagation and error-response timing taught that PSLVERR must map to the upstream error response. They taught the correct mapping. This chapter is about the bridge dropping the error (CPU sees OKAY on a failure) or mapping it on the wrong beat (a clean transfer flagged, or the error attributed to the next access) — the failure modes the mapping chapters did not catalog.

The gap is the one a failure taxonomy fills, the way the wait-state-propagation mechanism is for a single APB slave: prior chapters taught the correct behaviour and individual mechanisms; they did not build the named set of bridge bugs with wrong-versus-right RTL that lets you debug a cross-protocol failure by recognition. Building that set — bound to real upstream and downstream signal names — is this chapter, and the verification that proves a bridge is free of all of them leans on APB assertions plus an upstream protocol checker.

3. Mental model

The model: a bridge bug is a broken arrow in the dual-personality picture — sort it first by which arrow, because each arrow is a different bug family with a different fix. The bridge has exactly four things it must do across the boundary, and every bridge bug is a failure of one of them:

  • The wait arrow (APB pready=0 → upstream ready held). Break it and the upstream completes early: hready releases while pready is still low, the CPU latches stale prdata, and the access "works in isolation but reads garbage under wait states." This is a safety failure on reads (wrong data committed) and a correctness failure on writes (the write reported done before APB accepted it). The opposite break — never releasing — is a liveness failure: the bus hangs across the bridge.
  • The error arrow (APB pslverr → upstream hresp=ERROR / rresp/bresp=SLVERR). Break it by dropping the error and the CPU sees OKAY on a failed access — a silent fault, the worst escape. Break it by mapping on the wrong beat and a clean transfer is flagged as an error, or the error is attributed to the next access. Error bugs are about fidelity and alignment, not presence.
  • The sequencing arrow (one upstream transfer → exactly one APB SETUP+ACCESS). Break it and the bridge drops a transfer (the second of a back-to-back pair never reaches APB), duplicates one (a single upstream transfer runs two APB transfers), or collapses the SETUP gap (two APB transfers abut with no penable=0 cycle between them, violating the two-phase rule). This is the FSM getting the transfer count or the phase boundary wrong.
  • The capture arrow (upstream address/data held stable across the slower APB transfer). Break it and the APB request moves mid-transferpaddr follows the live upstream address as the pipeline advances, so the in-flight APB transfer completes against the next access's address. This is the rate-change bug: the fast side moves on while the slow side is still working.

Three refinements sharpen the model:

  • Bin by direction first. "CPU finished early / read garbage under waits" is the wait arrow; "CPU saw OKAY on a known-bad access" is the error arrow; "a transfer went missing or doubled / two APB accesses touched with no gap" is the sequencing arrow; "wrong register hit only under back-to-back" is the capture arrow. The symptom names the arrow before you open the RTL.
  • The control translation can be backwards while the data path is perfect. The nastiest bridge bugs leave prdata/pwdata flawless and get hready or hresp timing wrong — so chasing the data path first is the classic time sink. Check the handshake and response alignment before the data.
  • Most bridge bugs need the boundary stressed to appear. Wait bugs need a peripheral that actually inserts waits; capture/sequencing bugs need back-to-back upstream traffic; error bugs need a failing access. A clean isolated-access regression proves nothing about the bridge.
A block diagram of an AHB/AXI-to-APB bridge with three columns. The left upstream slave face lists the AHB inputs and outputs and AXI channels; the centre bridge FSM core shows holding registers and an IDLE/SETUP/ACCESS state machine with a wait gate and an error gate; the right APB manager face lists psel/penable/paddr/pwrite/pwdata out and prdata/pready/pslverr in. An amber arrow path traces PREADY=0 becoming a held upstream ready, and a red dashed arrow path traces PSLVERR becoming HRESP=ERROR or RRESP/BRESP=SLVERR.
Figure 1 — the AHB/AXI-to-APB bridge as a dual-personality block, drawn to expose the two paths bridge bugs break. On the left the upstream slave face accepts the system-bus transfer (haddr, hwrite, htrans, hsel, hready_in, hwdata in; hrdata, hready, hresp out — or the AXI ar/aw/w channels in and r/b out). In the centre the bridge FSM (IDLE to SETUP to ACCESS) captures the upstream request into holding registers (addr_q/write_q/wdata_q) and runs exactly one APB transfer per upstream transfer, staying in ACCESS until pready=1. On the right the APB manager face drives psel, penable, paddr, pwrite, pwdata and samples prdata, pready, pslverr. Two highlighted arrows carry the cross-boundary translations every bridge bug attacks: the amber wait-propagation path (APB PREADY=0 must hold the upstream ready — HREADY low, or AXI rvalid/bvalid withheld — so the CPU stalls the whole APB wait) and the red error-map path (APB PSLVERR on the completing beat must become HRESP=ERROR or RRESP/BRESP=SLVERR). The figure frames every bridge bug as a failure of one of these two paths or of the FSM that drives them — lost stall, wrong-beat error map, dropped or duplicated transfer, collapsed SETUP gap, or a moving address across the rate change.

4. Real SoC implementation

In RTL the two highest-frequency bridge bugs — lost wait propagation and wrong error mapping — are each one or two lines, and each looks reasonable on its own face. Here are the wrong-versus-right pairs, with real signal names on both sides of the boundary (an AHB-to-APB bridge; the AXI-Lite variant is noted inline).

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// =====================================================================
// BUG 1 — LOST WAIT PROPAGATION: upstream ready released while PREADY=0
// =====================================================================
// WRONG: hready_out is driven from the FSM entering ACCESS, NOT from the
// APB completing. The bridge tells AHB "done" the cycle APB ACCESS starts,
// a full APB wait state (or more) BEFORE pready -> the AHB master latches
// hrdata while prdata is still stale/undefined -> early-complete, bad read.
assign hready_out = (state == IDLE) || (state == ACCESS);   // BUG: ignores pready
assign hrdata     = prdata;                                  // sampled too early upstream
// (AXI-Lite form of the same bug: assign rvalid = (state==ACCESS); -- rvalid asserted
//  before pready, so the master accepts R before the peripheral has driven rdata.)
 
// CORRECT: the upstream ready must track the APB completion, never lead it.
// hready stays LOW for the entire time PREADY is low; it rises only on the
// beat APB actually completes, which is the same beat prdata is valid.
assign hready_out = (state == IDLE) || (state == ACCESS && pready);
assign hrdata     = prdata;            // now sampled on the pready edge = valid data
// (AXI-Lite: assign rvalid = (state==ACCESS && pready);  rdata = prdata; -- R handshake
//  completes only when the APB beat completes, so rready/rvalid never lead pready.)
 
// =====================================================================
// BUG 2 — WRONG ERROR MAPPING: PSLVERR dropped, or mapped on the wrong beat
// =====================================================================
// WRONG (a) — DROPPED: hresp is hardwired OKAY; PSLVERR never reaches AHB.
// The peripheral signalled a failed access; the CPU is told the bus was fine.
assign hresp = HRESP_OKAY;                                   // BUG: silent fault
 
// WRONG (b) — WRONG BEAT: pslverr sampled combinationally every cycle, so it
// is read in a WAIT cycle (where it is not yet meaningful) instead of on the
// completing beat -> a clean transfer can be flagged, or the error misaligned.
assign hresp = pslverr ? HRESP_ERROR : HRESP_OKAY;          // BUG: not gated on completion
 
// CORRECT: PSLVERR is only valid on the completing beat (pready=1), and the
// upstream error response must be asserted for THAT transfer, aligned to the
// same edge hready releases. Capture it on completion; present it with hready.
logic err_q;
always_ff @(posedge hclk or negedge hresetn)
  if (!hresetn)                                err_q <= 1'b0;
  else if (state == ACCESS && pready)          err_q <= pslverr;  // latch on the completing beat
assign hready_out = (state == IDLE) || (state == ACCESS && pready);
assign hresp      = (state == ACCESS && pready && pslverr) ? HRESP_ERROR : HRESP_OKAY;
// hresp=ERROR is presented on the SAME beat hready releases -> the AHB master
// attributes the error to the right transfer.
// (AXI-Lite: rresp/bresp = (pready && pslverr) ? SLVERR : OKAY, driven with rvalid/bvalid.)

Two facts drive these fixes. First, a wait-propagation fix is a causality fix: the upstream ready must be derived from the APB completion (state==ACCESS && pready), never from a proxy for "should be done by now" like the FSM merely entering ACCESS. The bridge converts APB latency into upstream wait states only if hready (or AXI rvalid/bvalid) is held low for exactly as long as pready is low; the moment the upstream ready leads pready, the master completes on data the peripheral has not yet driven. Second, an error-mapping fix is an alignment fix: pslverr is meaningful only on the completing beat, and the upstream error response must be presented on the same beat the upstream ready releases. Drop the error and the CPU sees OKAY on a failure (a silent fault); sample it off the completing beat and you either flag a clean transfer or pin the error on the wrong access. The discipline is identical to the APB wait/error mechanics: the response phase must be aligned, not merely generated.

5. Engineering tradeoffs

The catalog is the deliverable: one row per bridge bug, the symptom you actually see end-to-end, the root cause in the bridge FSM or the cross-boundary logic, and the fix. Memorise the shape — binned by which arrow broke, with a causality, alignment, or sequencing fix — and you can debug most cross-protocol failures by recognition.

Bridge bugSymptom (end-to-end)Root cause in the bridgeFix
Lost wait propagationUpstream completes early; read returns stale/undefined data, or a write reports done before APB accepted it — only under APB wait statesUpstream ready (hready/AXI rvalid/bvalid) derived from entering ACCESS, not from pready — it leads the completionDerive the upstream ready from state==ACCESS && pready; hold it low for the whole pready-low span — see wait propagation
Stall never releasedBus hangs only across the bridge; the APB peripheral is fine standaloneThe bridge waits on a pready term that can't resolve (FSM with no ACCESS exit, or an unsynchronised cross-clock pready)Guarantee an ACCESS exit on pready; synchronise a cross-clock pready before it gates the FSM — relates to multiple wait cycles
Error droppedCPU/DMA sees OKAY (no fault) on a known-bad peripheral access — a silent faulthresp/rresp/bresp hardwired to OKAY; pslverr never mapped upstreamMap pslverr on the completing beat to hresp=ERROR / rresp/bresp=SLVERR — see error propagation
Error on the wrong beatA clean transfer is flagged as an error, or the error is pinned on the next accesspslverr sampled in a wait cycle or a cycle off the completion, not gated on preadyGate the error map on state==ACCESS && pready; present hresp=ERROR on the same beat the upstream ready releases — see error-response timing
Dropped / duplicated transferOne of a back-to-back pair never reaches APB, or a single upstream transfer runs two APB transfersFSM mis-counts: re-enters ACCESS without a new accept, or returns to IDLE without launching the queued transferOne accept → exactly one SETUP+ACCESS; gate re-entry on a fresh upstream accept, not on residual state — see bridge FSM design
Collapsed SETUP gapTwo APB transfers abut with no penable=0 cycle between them; the peripheral merges them or misses the secondBack-to-back upstream transfers drive the APB side without re-inserting the SETUP phase; penable stays high across the boundaryRe-sequence the two-phase transfer every time: penable=0 in SETUP, 1 in ACCESS — never carry penable high into the next transfer
Moving address (rate change)Wrong register hit only under back-to-back upstream traffic; isolated access workspaddr/pwrite wired from the live upstream address; the pipeline advances it mid-APB-transferCapture haddr/hwrite/hwdata on accept; drive APB from the holding registers — the classic capture bug

The throughline: every row binds to one of the four arrows — wait, error, sequencing, capture — and every fix is causality (ready follows completion), alignment (error on the completing beat), one-to-one sequencing (one accept, one transfer, with the SETUP gap), or capture (freeze the request across the rate change). The tradeoff dimension is stress: most rows are invisible without the boundary exercised — wait bugs need an actual wait state, capture/sequencing bugs need back-to-back upstream traffic, error bugs need a failing access — which is why a bridge that passes only isolated, zero-wait, error-free accesses has a coverage hole exactly where it breaks.

6. Common RTL mistakes

7. Debugging scenario

Pick lost wait propagation, because it is the most deceptive bridge bug: the bridge is a legal AHB slave and a legal APB manager, every isolated test passes, and the failure only surfaces when a peripheral actually inserts a wait state — which directed bring-up tests, run against fast model peripherals, rarely do.

  • Observed symptom: a peripheral that returns correct data when read in isolation intermittently returns stale or undefined data when read in a tight loop, or right after the system clock is raised. Slower peripherals (a UART status register behind a clock divider) are worse. The AHB side shows a clean, complete access — no error, no hang, no protocol violation — so the failure looks like a software or peripheral bug, not a bridge bug.
  • Waveform clue: in a capture across the bridge boundary (Figure 2), hready on the AHB side rises one cycle before pready on the APB side — the bridge releases the AHB master while the APB peripheral is still in its wait state with prdata not yet valid. The AHB master samples hrdata (wired from prdata) on the edge it completes, and captures the peripheral's previous read value or undefined bits. When the peripheral happens to insert zero wait states, hready and pready coincide and the bug is invisible — which is exactly why fast model peripherals never show it.
  • Root cause: hready_out was derived from the FSM entering ACCESS (state==ACCESS) instead of from the APB transfer completing (state==ACCESS && pready). The upstream ready therefore leads the APB completion by the full APB wait length. The bridge converts APB latency into AHB wait states only if hready is held low for as long as pready is low; deriving it from a proxy for "ACCESS has started" breaks that the moment the peripheral inserts a single wait state.
  • Correct RTL: derive the upstream ready from the APB completion, so it never leads pready:
    Azvya Education Pvt. Ltd.VLSI Mentor
    Snippet
    // upstream ready must FOLLOW the APB completion, not lead it
    assign hready_out = (state == IDLE) || (state == ACCESS && pready);
    assign hrdata     = prdata;   // sampled on the pready edge, where prdata is valid
    // AXI-Lite: assign rvalid = (state==ACCESS && pready);  rdata = prdata;
  • Verification assertion: prove the upstream ready never releases while APB is still waiting — bind this across the boundary, where no single-protocol checker looks:
    Azvya Education Pvt. Ltd.VLSI Mentor
    Snippet
    // wait must propagate: while APB is in ACCESS with PREADY low, the upstream
    // ready must stay deasserted -- the bridge may not complete the access early.
    assert property (@(posedge hclk) disable iff (!hresetn)
      (state == ACCESS && !pready) |-> !hready_out
    );
  • Debug habit: when a peripheral reads correctly in isolation but returns stale data under load or after a clock change, do not chase the peripheral or the data path — chase the alignment of the upstream ready and pready across the bridge. Capture both faces in one trace and check whether hready (or AXI rvalid) ever rises while pready is still low. A one-cycle lead under wait states is the lost-wait-propagation signature, and it is a bridge bug, not a peripheral bug.
Two stacked timing diagrams of the same bridged APB read with one wait state. The top correct case shows HREADY held low while PREADY is low and rising only when PREADY rises and PRDATA is valid. The bottom buggy case, in red, shows HREADY released a cycle early while PREADY is still low and PRDATA is not yet valid, so the AHB master samples stale read data at the early completion edge.
Figure 2 — lost wait propagation versus the correct held stall, on the same bridged read with one APB wait state. Both panels show PCLK, the downstream APB signals (PSEL, PENABLE, PREADY, PRDATA) and the upstream HREADY that flow-controls the CPU. Top (correct, green): the bridge holds HREADY low for the entire time PREADY is low, so the AHB master stalls and only samples HRDATA on the edge PREADY rises and PRDATA is valid — the read returns correct data. Bottom (bug, red): the bridge releases HREADY one cycle early, while PREADY is still low and PRDATA is not yet valid, so the AHB master completes its access and latches stale or undefined read data at the early sample edge. The figure marks the early-release instant and notes the signature: the bug only appears when the peripheral actually inserts a wait state, which is why it survives isolated bring-up against fast model peripherals and surfaces under load or after the system clock is raised.

8. Verification perspective

A bridge is verified as two protocol-compliant faces plus the mappings between them, and the bridge bugs split cleanly into the four arrows — so the plan is a per-face protocol monitor, a cross-boundary assertion per arrow, and coverage that forces the boundary stress each bug needs to appear.

  • Bind a protocol monitor to each face and a cross-boundary assertion per arrow. An AHB slave monitor upstream and an APB manager monitor downstream catch a malformed handshake on either side — but neither catches a broken translation, so add the arrow assertions: wait(state==ACCESS && !pready) |-> !hready_out (the upstream ready may not lead pready); error map(state==ACCESS && pready && pslverr) |-> hresp==HRESP_ERROR and the converse (state==ACCESS && pready && !pslverr) |-> hresp==HRESP_OKAY (the error maps on the completing beat, and a clean beat never does); capture(psel && !(penable && pready)) |=> $stable(paddr) && $stable(pwrite) (the APB request is frozen across its transfer); sequencingpenable must drop to 0 between any two APB transfers (the SETUP gap is re-inserted).
  • Hang corners need a bounded-completion watchdog at the bridge. The stall-never-released bug fails by the absence of an event — hready never rises — so a liveness property (state==ACCESS) |-> ##[1:MAX_WAIT] (pready && hready_out) converts a silent across-bridge hang into a located assertion failure, the bridge-level counterpart to the manager-side timeout of multiple wait cycles.
  • Coverage must force the boundary stress, because every bridge bug hides until it is exercised. Cover an APB transfer with zero and with N wait states (so wait propagation is actually tested, not just the zero-wait coincidence); a pslverr on both a read and a write (so error mapping is exercised in both directions and on the right beat); back-to-back upstream transfers with zero idle (so capture and SETUP-gap bugs surface when the pipeline overlaps); and — for AXI — the read and write error responses (rresp/bresp=SLVERR) separately, since they map on different channels. A bridge tested only with isolated, zero-wait, error-free accesses has a coverage hole exactly where bridges break, and "100% closed" on that model is silent about every bug in this catalog.

The point: each bridge bug binds to one arrow, each arrow has a named cross-boundary assertion the per-face monitors cannot supply, the hang corner needs a bridge-level watchdog, and coverage must deliberately stress the wait/error/back-to-back boundary — verifying the bridge as two compliant interfaces plus the four mappings between them.

9. Interview discussion

"What bugs are specific to a bus bridge?" is a strong SoC-integration screening question, because a weak answer names a generic protocol bug while a strong answer reveals that bridge bugs live in the translation — and enumerates them by the arrow they break, with the fix for each.

Frame it as four arrows the bridge must get right, and every bridge bug breaks one: the wait arrow (APB pready=0 → upstream ready held), the error arrow (pslverrhresp=ERROR / rresp/bresp=SLVERR), the sequencing arrow (one upstream transfer → one APB SETUP+ACCESS), and the capture arrow (freeze the request across the rate change). Then land each failure crisply: lost wait propagation — the upstream ready released while pready is low, so the CPU completes early on stale data (the "works in isolation, garbage under waits" bug); dropped errorpslverr never mapped, so the CPU sees OKAY on a failed access (a silent fault, the worst escape); error on the wrong beatpslverr sampled off the completing beat, so a clean transfer is flagged or the error is pinned on the next access; dropped/duplicated transfer — an FSM that mis-counts back-to-back transfers; collapsed SETUP gappenable carried high across the boundary so two APB transfers merge; and the moving addresspaddr wired from the live upstream address, corrupting back-to-back transfers when the pipeline advances mid-APB-transfer. The depth flourishes are three: the fix for a wait bug is causality (the upstream ready must follow pready, never a proxy for "ACCESS started"); the fix for an error bug is alignment (map on the completing beat, present hresp=ERROR on the same beat the upstream ready releases); and per-face protocol checkers cannot catch any of these — each bug is legal on both faces and only a cross-boundary assertion sees it. Closing with "and almost every one hides until the boundary is stressed — a real wait state, back-to-back traffic, or a failing access — which is why a bridge that passes isolated bring-up can still ship every bug in the catalog" signals real integration experience, not spec reading.

10. Practice

  1. Bin by the arrow. Given three reports — "the CPU reads garbage from a slow peripheral only under load," "a failed write returns OKAY to the CPU," and "back-to-back accesses hit the wrong register" — assign each to the wait, error, sequencing, or capture arrow and name the specific bridge bug.
  2. Fix the wait. Given assign hready_out = (state==IDLE) || (state==ACCESS);, explain why the AHB master completes early under a wait state and write the corrected expression, then the AXI-Lite rvalid equivalent.
  3. Align the error. Write the cross-boundary assertion that proves pslverr on the completing beat maps to hresp=ERROR and a clean completing beat maps to hresp=OKAY, and state which two error bugs each half catches.
  4. Re-insert the gap. Draw the APB waveform for two upstream transfers arriving back-to-back, mark where penable must drop to 0, and write the assertion that catches a collapsed SETUP gap.
  5. Pick the stress. For each of lost wait propagation, dropped error, moving address, and collapsed SETUP gap, state the boundary stress (wait state, failing access, back-to-back traffic) a test must apply for the bug to appear, and why an isolated zero-wait access cannot catch it.

11. Q&A

12. Key takeaways

  • A bridge bug lives in the translation, not in either protocol — each is legal on both faces yet wrong end-to-end, so no single-protocol checker catches it; only a cross-boundary assertion does. Per the AMBA APB spec (IHI 0024C) §2.1 PSLVERR and the AHB error response, the bridge owns the mapping between APB PSLVERR and AHB HRESP=ERROR / AXI RRESP/BRESP=SLVERR.
  • Bin every bridge bug by the arrow it breaks: the wait arrow (pready=0 → upstream ready held), the error arrow (pslverr → upstream error response), the sequencing arrow (one upstream transfer → one APB SETUP+ACCESS), and the capture arrow (freeze the request across the rate change).
  • The wait fix is causality: the upstream ready (hready / AXI rvalid/bvalid) must follow pready — derived from state==ACCESS && pready, never from a proxy for "ACCESS has started" — or the CPU completes early on stale data. See wait-state propagation.
  • The error fix is alignment: pslverr is meaningful only on the completing beat; map it to the upstream error response on the same beat the upstream ready releases. Dropping it is a silent fault (the worst escape); mapping it off-beat flags a clean transfer or pins the error on the next access. See error propagation and error-response timing.
  • The sequencing and capture bugs need back-to-back upstream traffic to appear — a dropped/duplicated transfer, a collapsed SETUP gap (penable carried high), or a moving address (paddr from the live upstream phase) are all invisible until the upstream pipeline overlaps two transfers.
  • Verify the bridge as two compliant faces plus four cross-boundary mappings: per-face protocol monitors, an arrow assertion each ((state==ACCESS && !pready) |-> !hready_out for wait; the completing-beat error map for hresp/rresp/bresp), a bridge-level watchdog for the across-bridge hang, and coverage that forces wait states, failing accesses, and back-to-back traffic — the stress under which every bug in this catalog hides.