Skip to content

A protocol being logically simple does not make it timing-trivial — APB carries real, subtle timing hazards that a low bus frequency hides but never removes. The comfortable belief is that because APB has no pipeline, no bursts, no outstanding transactions, and usually runs on a slow control clock, there is simply nothing for a timing engineer to worry about. That belief is where APB bugs are born. This chapter takes the myth apart: it shows a concrete APB timing hazard — a combinational PREADY glitching off a rippling PADDR decode into the manager's sample window — traces where the belief comes from (low frequency is confused with no constraints), enumerates the four hazards that are actually there, and gives you the interview framing that separates someone who has closed timing on an APB slave from someone who has only read that APB is simple.

1. Problem statement

The problem is that APB's logical simplicity is routinely mistaken for timing triviality, so the four real timing paths in an APB slave — a combinational PREADY, the PRDATA read mux, reset recovery/removal, and any cross-clock term feeding PREADY — go unconstrained and unverified until they fail in silicon.

"Simple protocol" is a statement about the state machine: two phases, one wait bit, no reordering. It says nothing about the physical paths the RTL synthesises into. Every APB slave still has combinational cones that must settle inside a clock period, still has flops whose reset must recover cleanly, and — the moment it talks to logic on another clock — still has clock-domain-crossing arcs that a static-timing tool cannot analyse without help. None of those disappear because the protocol has no bursts. The engineering problem is therefore concrete: identify the paths in a "trivial" APB slave that a timing tool must actually constrain, and stop treating "it runs at 50 MHz" as a proof that they all pass.

The four paths this chapter is about:

  • A combinational PREADY driven off a rippling PADDR decode can pulse into the manager's sample window — a glitch, not a logic error.
  • The PRDATA read-data mux across many registers is a wide combinational path that can be the slave's real critical path (see PRDATA timing).
  • Reset recovery and removal — the recovery/removal checks on the flops that come out of PRESETn — must be met, or reset deassertion is unsafe.
  • Any cross-clock term feeding PREADY (a done from a faster domain, an address that is not APB-clocked) needs a synchroniser, and its arc must be excluded from ordinary STA.

2. Why previous knowledge is insufficient

You have spent this module learning APB as a protocol — phases, handshake, wait states, completion. That knowledge is correct and it is exactly what makes the myth so sticky: everything about the protocol is simple, so it is natural to extrapolate that everything about the implementation is simple too. It is not, and prior chapters, by design, taught the logic and mostly assumed ideal timing.

  • The PREADY timing chapter already broke half of this myth for one signal: it showed that a logically-correct PREADY can be electrically wrong, and that a combinational PREADY off a rippling decode glitches. This chapter generalises that lesson — the glitch is not a PREADY quirk, it is one instance of "APB has physical timing paths" — and adds the three other hazards (PRDATA depth, reset recovery/removal, CDC exclusion) that the single-signal view never reached.
  • The access-phase timing chapter taught when the manager samples — the per-cycle cadence — treating each sampled bit as an ideal value. But "the manager samples PREADY on this edge" is precisely the setup/hold constraint a static-timing tool must be told about; the cadence view names the edge, not the timing arc that has to close on it.
  • The signal-stability requirements chapter taught that PADDR, PWDATA, and control must hold stable through the access. Stability is a protocol rule the manager obeys; it is not the same as the STA fact that the slave's own PRDATA mux or PREADY cone must settle within a PCLK period. Obeying signal stability does not make your combinational depth close timing.

The gap is a level confusion. Prior chapters taught the protocol (logic, cadence, stability) and assumed the physical layer is trivial because the protocol is. This chapter is the physical layer: the actual timing paths, the reset checks, and the CDC exclusions that a "simple" APB slave still has to satisfy.

3. Mental model

The model: APB is logically simple and physically ordinary — it has fewer kinds of timing path than AXI, but each kind it has is a real path a static-timing tool must still constrain, and a slow clock only buys you margin, it does not delete the path.

The myth conflates two independent axes. One axis is protocol complexity — how many phases, how much pipelining, how much reordering. APB is genuinely at the low end. The other axis is physical timing — does the RTL synthesise into cones that must settle, flops that must reset cleanly, and arcs that cross clocks. Every synchronous digital block sits high enough on this second axis to need constraints; APB is no exception. Low protocol complexity does not pull you down the physical axis. A 50 MHz APB slave with a 40-register PRDATA mux has a 20 ns budget and a wide mux — comfortable, but constrained, and it is only comfortable because someone checked. Even the transfer's latency is a budget, not a free lunch (see APB latency anatomy).

Three refinements make it precise:

  • A slow clock is margin, not immunity. At 50 MHz the combinational PREADY glitch may settle well before the sample edge and never bite; push the same RTL onto a 200 MHz always-on domain, or deepen the decode, and the identical logic fails. "It has no timing issue" usually means "it has margin today," which is not a property of the protocol.
  • The dangerous paths are the ones STA cannot see by default. The PRDATA mux is an ordinary intra-clock path a tool constrains automatically. The glitch and the CDC arc are the treacherous ones: a glitch is invisible in zero-delay RTL and needs gate-level; a cross-clock arc is meaningless to STA and must be explicitly synchronised and excluded, or the tool either flags a false failure or, worse, is silently wrong.
  • Reset is a timing path too. PRESETn deassertion has recovery and removal checks exactly like setup and hold (the logic side is slave reset behavior; the timing side is here). "APB reset is just if (!presetn)" is the logic; whether every reset flop meets recovery/removal on deassertion is the timing, and an asynchronous-assert / unsynchronised-deassert reset can violate it and drop a flop into metastability.
A two-column myth-versus-reality figure. The left amber column titled MYTH lists APB as unpipelined, low-frequency, single-wait with a 'nothing to constrain' conclusion. The right column titled REALITY lists four hazard cards: combinational PREADY glitch off a rippling PADDR decode, deep PRDATA read-data mux critical path, reset recovery and removal, and a cross-clock term feeding PREADY needing synchroniser plus STA exclusion.
Figure 1 — the myth versus the reality. On the left, the belief: APB is unpipelined, low-frequency, single-wait, so 'there is nothing to constrain.' On the right, the four real hazards that the belief hides: a combinational PREADY glitch off a rippling PADDR decode landing in the manager's sample window (needs gate-level to see); a deep PRDATA read-data mux that can be the slave's true critical path; reset recovery and removal checks on the flops coming out of PRESETn; and a cross-clock term feeding PREADY that must be synchronised and excluded from ordinary STA. The figure is the chapter's spine: low protocol complexity is not low physical-timing risk — a slow clock is margin, not immunity.

4. Real SoC implementation

The single most instructive hazard is the combinational PREADY glitch, because it is the one that most directly contradicts the myth: it is invisible in RTL, invisible to a quick sim, and it lives in code that looks completely reasonable. Below is the wrong-versus-right pair on real APB signals, followed by a small SDC fragment for the CDC arc that STA must be told to exclude.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ============================================================
// HAZARD 1 — COMBINATIONAL PREADY off a rippling PADDR decode
// ============================================================
// WRONG: PREADY is a combinational function of a multi-level PADDR decode.
// As paddr bits settle at different times, `hit` ripples through spurious
// states; one of them is a high that can land in the manager's sample window.
// In zero-delay RTL this NEVER shows -- every signal settles instantly.
wire hit     = (paddr[15:8] == BASE) & region_decode(paddr[7:2]); // multi-level cone
wire pready  = psel ? (hit & data_ready) : 1'b1;   // glitches as `hit` ripples
 
// RIGHT: register the inputs so PREADY is a shallow, glitch-free function.
// A registered select and a registered data-ready term feed one mux level;
// there is no rippling decode left in the PREADY cone.
logic sel_q, data_ready_q, pready;
always_ff @(posedge pclk or negedge presetn) begin
  if (!presetn) begin
    sel_q        <= 1'b0;
    data_ready_q <= 1'b0;
  end else begin
    sel_q        <= psel & (paddr[15:8] == BASE); // decode settled, then registered
    data_ready_q <= region_ready;                 // ready term settled, then registered
  end
end
assign pready = sel_q ? data_ready_q : 1'b1;       // one mux level off flops -> no glitch
 
// ============================================================
// HAZARD 2 — DEEP PRDATA read-data mux (a wide combinational path)
// ============================================================
// The read mux across many registers is real combinational depth. On a fast
// clock or a wide register file this is the slave's critical path, NOT PREADY.
// Register the mux output so PRDATA is a clean flop and the mux has a full
// cycle to settle (PREADY is then derived from the SAME data-valid term).
logic [31:0] prdata_q;
always_ff @(posedge pclk or negedge presetn) begin
  if (!presetn)             prdata_q <= '0;
  else if (psel & penable)  prdata_q <= rdata_mux; // wide mux settles into a flop
end
assign prdata = prdata_q;
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
# ============================================================
# HAZARD 4 — CDC term feeding PREADY: synchronise, then EXCLUDE from STA
# ============================================================
# `done_fast` is generated in a faster clock domain and is brought into the
# APB (pclk) domain by a 2-flop synchroniser before it may gate PREADY.
# The crossing arc is asynchronous: STA cannot meaningfully time it, so the
# path from the source flop into the first synchroniser flop is excluded.
set_false_path -from [get_clocks fast_clk] -to [get_clocks pclk]
 
# (Preferred, tighter than a blanket false path: constrain the crossing as a
#  max-delay / set_clock_groups -asynchronous so real skew is still bounded.)
set_clock_groups -asynchronous -group {pclk} -group {fast_clk}

Two facts drive these fixes. First, the glitch is a timing hazard, not a logic error, and the fix is structural: shrink the PREADY cone until it cannot ripple. Registering sel and the ready term leaves a single mux level between flops and PREADY, so there is no multi-level decode to produce a spurious high — the combinational form is kept (it can still be high the cycle those flops present ready) with the integrity of a registered signal. Per the AMBA APB spec (IHI 0024C) §3.1, the manager samples the completion of a transfer on the PCLK rising edge in the access phase with PENABLE high; that edge is the setup/hold constraint the PREADY value must satisfy, and a glitch inside its window is sampled as a real completion. Second, the CDC arc is not a normal timing path at all — it must be synchronised in RTL and excluded in SDC. A two-flop synchroniser makes the term metastability-resolved in the pclk domain; the set_false_path / set_clock_groups tells STA not to try to time an arc that has no meaningful setup relationship, so the tool neither reports a false violation nor silently mis-times it.

5. Engineering tradeoffs

The deliverable is the map from "APB feels simple" to "here is what a timing engineer actually constrains." Each row is a real path, why the myth hides it, and what closing it costs.

HazardWhy the myth hides itWhat it costs to closeSTA / verification level
Combinational PREADY glitchInvisible in zero-delay RTL; a slow clock gives margin so it never bites in the labRegister PREADY or its inputs — one cycle of latency, or a shallower coneGate-level / delay-annotated sim; a glitch guard-band check
Deep PRDATA read mux"It's just a mux" — but across 30–40 registers it is wide combinational depthRegister the mux output (one cycle) or pipeline the decodeOrdinary intra-pclk STA setup path — automatic, but real
Reset recovery / removal"Reset is just if (!presetn)" — treated as logic, not a timing checkSynchronise reset deassertion (async assert, sync deassert)STA recovery/removal checks on PRESETn flops
CDC term into PREADYOn a single-clock slave it does not exist, so it is assumed never to existA 2-flop synchroniser (level) or req/ack handshake (pulse)Must be excluded from STA; checked by CDC/lint, not setup timing
"Slow clock, so no constraints"The frequency is low, which feels like proof(nothing — this is the trap)Never a substitute for constraining the paths above

The throughline: APB has fewer kinds of timing path than a pipelined bus, but each kind it has is a real path a tool must constrain — and two of them (the glitch and the CDC arc) are exactly the paths STA does not handle by default. The PRDATA mux is the honest, automatic one; the glitch needs a different level (gate-level) to even appear; the CDC arc needs a different treatment (synchronise plus exclude) because STA cannot time it; reset needs its own check class (recovery/removal). "Slow clock" buys margin on exactly one of these — the intra-clock combinational depth — and buys nothing on the glitch, the reset checks, or the CDC exclusion.

6. Common RTL mistakes

7. Debugging scenario

Take the combinational-PREADY glitch on a reused IP, because it is the exact scenario the myth sets you up for: a slave that was "obviously fine" at its original frequency ships broken after a clock bump that no one flagged as a timing risk.

  • Observed symptom: an APB slave that ran flawlessly for years at 25 MHz is dropped, unchanged, into a new SoC where its PCLK is now 150 MHz on an always-on domain. In directed sim it passes. In gate-level and in bring-up, some reads intermittently complete a cycle early and capture garbage, and the rate rises with temperature and with address patterns that toggle many PADDR bits at once. The RTL was never touched, so "it's a timing thing" is dismissed at first — "APB is simple, it has no timing issues."
  • Waveform clue: in a delay-annotated capture (Figure 2), PREADY is combinational off the PADDR decode and glitches high mid-cycle as the address bits settle at different times; at 25 MHz that transient died long before the sample edge, but at 150 MHz the cycle is short enough that the spurious high still overlaps the manager's sample window, so the manager samples a premature 1 and completes before PRDATA is valid.
  • Root cause: the PREADY cone contains a multi-level PADDR decode. The glitch was always present in the gates; only the margin changed. The original slow clock hid a real timing hazard, and the myth ("APB has no timing challenges") is exactly why no one re-timed the block when the frequency was raised.
  • Correct RTL: shrink the cone — register the select and the ready term so PREADY is one mux level off flops with no rippling decode behind it, or register PREADY outright and accept one cycle of latency:
    Azvya Education Pvt. Ltd.VLSI Mentor
    Snippet
    always_ff @(posedge pclk or negedge presetn)
      if (!presetn) begin sel_q <= 1'b0; data_ready_q <= 1'b0; end
      else          begin sel_q <= psel & addr_hit; data_ready_q <= region_ready; end
    assign pready = sel_q ? data_ready_q : 1'b1;   // glitch-free at the sample edge
  • Verification assertion: prove PREADY is never unknown while selected, and — in gate-level — that it does not transition inside a guard-band before the sampling edge:
    Azvya Education Pvt. Ltd.VLSI Mentor
    Snippet
    // never-X while selected (runs in RTL)
    assert property (@(posedge pclk) disable iff (!presetn)
      (psel && penable) |-> !$isunknown(pready));
    // completion must not precede a genuine data-valid term (catches early-complete)
    assert property (@(posedge pclk) disable iff (!presetn)
      (psel && penable && pready) |-> data_ready_q);
  • Debug habit: when a "simple" block breaks only after a frequency bump or only in gate-level, do not re-read the logic — the logic did not change. Ask which combinational cone got tighter relative to the new period, run a delay-annotated sim, and watch PREADY across the sample window for a transient. The signature "worked slow, fails fast, RTL untouched" is the myth's fingerprint: a real timing hazard that a slow clock was silently masking. This glitch is one entry in the broader PREADY common design bugs catalog — here it is the case study that debunks the "no timing" claim.
Two stacked APB read timing diagrams of the same access at a fast clock. The top correct case shows a registered PREADY rising cleanly at the sample edge as PRDATA becomes valid, with the manager sampling correct data. The bottom buggy case, in red, shows a combinational PREADY glitching high mid-cycle off a rippling PADDR decode, the glitch overlapping the highlighted manager sample window, and the manager capturing stale data before PRDATA is valid.
Figure 2 — the concrete APB timing issue, on the same read at a fast clock. Top (correct, green): a registered PREADY is a clean flop output — low through the wait, high exactly at the sample edge PRDATA becomes valid, rock-steady across the sample window, so the manager captures correct data. Bottom (bug, red): a combinational PREADY driven off a rippling PADDR decode glitches high mid-cycle as the address bits settle; at the fast clock the spurious high still overlaps the manager's sample window, so the manager samples a premature completion and captures stale data before PRDATA is valid. The figure annotates the sample window and shows that the glitch is invisible in zero-delay RTL — it only lands in the window once the cycle is short enough, which is why a slow clock hid it and the frequency bump exposed it.

8. Verification perspective

Because the myth is fundamentally a level error — assuming the protocol layer is the only layer — the verification plan must be explicit about which check runs at which level, and in particular must not treat a clean RTL run as proof. The four hazards live at four different levels, and a plan that only exercises one of them has a hole exactly where the myth says there is none.

  • The glitch is a gate-level fact, not an RTL one. In zero-delay RTL every signal settles instantly, so a combinational PREADY off a rippling decode never forms a transient — the glitch is literally invisible until real or annotated delays are present. The plan must therefore include a delay-annotated or gate-level pass with a guard-band check that PREADY does not transition within a setup window before each PCLK rising edge, plus the RTL-level never-X and ready-before-complete assertions above. State the level for each: never-X and ready-before-complete run in RTL; the glitch guard-band needs delays.
  • Reset recovery/removal and the CDC arc are checked by different tools, not by functional sim. Recovery/removal on the PRESETn flops is an STA check, and reset-deassertion metastability is a CDC/lint concern — a functional testbench will not see either. The cross-clock arc into PREADY must be flagged by a CDC tool (is every crossing synchronised?) and excluded in SDC (set_false_path / set_clock_groups); an SVA that no raw cross-domain signal feeds the PREADY cone complements, but does not replace, the structural CDC check.
  • Cover the frequency and address corners the myth skips. Functional coverage should include a fast-clock configuration (not only the nominal slow one) and read addresses that toggle many PADDR bits at once — the exact stimulus that maximises decode ripple. A suite that only ever runs the slow, benign address patterns will pass the very block that fails on the fast domain, reproducing the debugging scenario in the field instead of the lab.

The point: the myth's damage is a verification hole, and the fix is a leveled plan — RTL assertions for value and causality, gate-level for the glitch, STA for reset recovery/removal and the intra-clock PRDATA path, and a CDC tool plus SDC exclusion for the cross-clock arc. No single level clears an APB slave.

9. Interview discussion

"APB is a simple protocol — does it have any timing challenges?" is a deceptively sharp senior question, because the tempting answer ("no, it's slow and unpipelined") is exactly the wrong one, and how quickly you reject it reveals whether you have ever closed timing on an APB slave or only studied the handshake.

Frame it as protocol simplicity is not physical-timing triviality: APB has fewer kinds of timing path than AXI, but every kind it has is real. Then enumerate the four crisply: a combinational PREADY off a rippling PADDR decode can glitch into the manager's sample window — invisible in zero-delay RTL, only visible in gate-level, and the classic "worked slow, fails fast" bug; the PRDATA read mux across many registers is genuine combinational depth and is often the slave's actual critical path; reset recovery and removal are timing checks on PRESETn deassertion, so reset must be asserted asynchronously and deasserted synchronously or a flop goes metastable; and any cross-clock term feeding PREADY needs a two-flop synchroniser (or a req/ack handshake for a pulse) and an STA exclusion (set_false_path / set_clock_groups), because a static-timing tool cannot meaningfully time an asynchronous crossing. Land the depth points: a slow clock is margin, not immunity — the same RTL fails when the clock rises or the decode deepens; the dangerous paths are the ones STA does not handle by default — the glitch needs a different level and the CDC arc needs a different treatment; and cite that per AMBA APB (IHI 0024C) §3.1 the manager samples completion on the PCLK access edge, which is the setup/hold constraint the PREADY value must meet. Closing with "so I never treat 'it runs at 50 MHz' as timing sign-off — I still constrain the PRDATA mux, register or shrink the PREADY cone, check reset recovery/removal, and exclude the CDC arc" signals real silicon experience, not spec reading.

10. Practice

  1. Reject the premise. Given "APB is unpipelined and runs at 40 MHz, so there's nothing to time," list the four real timing paths that statement ignores and, for each, one condition under which its margin disappears.
  2. Find the glitch. Given a combinational pready = decode(paddr) & data_ready, explain why a zero-delay RTL sim cannot show the glitch, what stimulus (clock rate, address pattern) makes it land in the sample window, and the two-line fix.
  3. Size the mux. For a slave with a 40-register read path on a 200 MHz PCLK, argue why PRDATA — not PREADY — is the likely critical path, and give two ways to close it.
  4. Handle reset as timing. Explain the recovery and removal checks on a PRESETn flop, why an asynchronously-deasserted reset can violate removal, and the "assert async, deassert sync" fix.
  5. Constrain the crossing. A done from a 300 MHz domain gates PREADY in a 50 MHz APB slave. Write the RTL structure that makes it safe and the SDC line that keeps STA from mis-timing it, and state which tool actually verifies the crossing.

11. Q&A

12. Key takeaways

  • Protocol simplicity is not physical-timing triviality. APB has fewer kinds of timing path than a pipelined bus, but each kind it has — a PREADY cone, the PRDATA mux, reset flops, and any cross-clock arc — is a real path a tool must constrain. "Simple protocol" describes the state machine, not the gates.
  • A slow clock is margin, not immunity. Low frequency only relaxes the intra-clock combinational paths, and only today — the same RTL fails when the clock rises or the decode deepens, while the reset checks and the CDC exclusion were never about frequency at all.
  • The combinational PREADY glitch is the flagship hazard: off a rippling PADDR decode it pulses into the manager's sample window (AMBA APB IHI 0024C §3.1 defines that sampling edge), it is invisible in zero-delay RTL, and it only appears in gate-level — the classic "worked slow, fails fast, RTL untouched" bug. Fix it by registering PREADY or shrinking its cone.
  • The dangerous paths are the ones STA does not handle by default: the glitch needs a different level (gate-level), and a cross-clock term needs a different treatment — synchronise in RTL and exclude in SDC (set_false_path / set_clock_groups), then prove it with a CDC tool.
  • Reset and PRDATA are timing too. PRESETn deassertion has recovery/removal checks — assert async, deassert sync — and the PRDATA read mux across many registers is frequently the slave's actual critical path, not PREADY.
  • Sign-off is leveled, never single-source. RTL assertions for value and causality, gate-level for the glitch, STA for reset recovery/removal and the PRDATA path, and a CDC tool plus SDC exclusion for the crossing — carried into the same discipline as the rest of the APB timing checklist.