Skip to content

The myth is that an APB transfer always completes in one clock cycle. The correction is that APB is defined as a two-phase transfer — a SETUP cycle followed by an ACCESS cycle — so the minimum is two cycles, and because PREADY can hold the ACCESS phase, a transfer extends to any number of cycles. APB is genuinely simple and unpipelined, and that simplicity is exactly what gets mis-remembered as "single-cycle." This chapter takes the belief apart: it states the myth precisely, shows the multi-cycle counterexample the myth cannot survive, traces where the belief comes from, catalogues the real bugs it ships, and hands you the crisp two-sentence argument that settles it in a review or an interview.

1. Problem statement

The problem is that a large number of otherwise-competent engineers carry the belief that "an APB transfer is one clock cycle," and that belief is false in a way that quietly ships real bugs. Stated precisely, the myth is: an APB access asserts its control and data and completes on a single PCLK edge, so a manager can drive one beat per cycle and a subordinate can be modelled as a fixed one-cycle latch. Every clause of that sentence is wrong.

Where does the belief come from? Three roots, and they are worth naming because each points at a different mind that holds it:

  • Confusing "simple / unpipelined" with "single-cycle." APB is the simplest AMBA bus — no pipelining, no bursts, one transfer at a time. The mind hears "simple, one transfer at a time" and compresses it to "one cycle per transfer." But "unpipelined" means transfers do not overlap; it says nothing about how many cycles one transfer takes. The two ideas got fused, and the fused version is the myth.
  • Only ever having seen a zero-wait slave. In a first testbench the subordinate is usually a register file that is always ready — PREADY is tied high — so every transfer happens to take the same small number of cycles and the engineer never watches a wait state form. From that sample of one, "it always takes the same short time" hardens into "it takes one cycle."
  • Collapsing the two phases into one mental cell. SETUP and ACCESS are two distinct cycles with different control-signal values, but on a lazy reading of a waveform — where PSEL is high across both — they blur into a single "the transfer" box. Once the two phases are one box in your head, "the transfer is one cycle" follows naturally.

The engineering stakes are concrete. A manager built on the myth never samples PREADY — it assumes completion after a fixed count — so the first time it meets a real slave that inserts a wait state, it reads before the data is valid or drives the next beat on top of an unfinished one. A subordinate model built on the myth is a fixed one-cycle latch that no real slow peripheral matches, so integration breaks the moment a flash controller, a re-timed CDC bridge, or a clock-divided peripheral needs even one wait cycle. The myth is not a harmless simplification; it is a specification error waiting for a slow peripheral.

2. Why previous knowledge is insufficient

If you have read the earlier chapters of this track, you already know the correct mechanics — but knowing the mechanics is not the same as being inoculated against the myth, because the myth is a framing error, not a mechanics gap.

  • The transfer overview and single-cycle transfer chapters taught the SETUP and ACCESS phases and the zero-wait case. But the very existence of a "single-cycle transfer" chapter is where the myth hides: "single-cycle transfer" is loose shorthand for "single-wait-state-free transfer," which is still two clock cycles (SETUP + ACCESS). Read the phrase without care and it feeds the myth instead of refuting it. This chapter exists to nail down that "no wait states" is not "one cycle."
  • The multi-cycle transfer and multiple wait cycles chapters taught that PREADY extends ACCESS. You can know that mechanism cold and still mentally default to "usually it's one cycle though," because the wait-state case was filed as an exception rather than as proof that the transfer length is variable by design.
  • Why wait states exist and slow-peripheral behaviour explained why a slave stalls. That is the motivation; it does not by itself dislodge the false default count in an engineer's head.

The gap this chapter closes is not a missing fact. It is a mis-set default: the earlier chapters give you the true model as one option among several, and the myth is the habit of treating "one cycle" as the baseline and everything else as a special case. The fix is to invert the default — the baseline is "at least two cycles, extensible" — and to be able to argue it from the spec on demand. That inversion, and the argument, is the content here.

3. Mental model

The model to install, replacing "one cycle," has two moving parts and one hard floor:

  • Part one — the mandatory two phases. Per AMBA APB (IHI 0024C) §3.1, every transfer is a SETUP cycle followed by an ACCESS cycle. In SETUP the manager asserts PSEL and drives PADDR, PWRITE, and (for a write) PWDATA, with PENABLE low. On the next edge it enters ACCESS by raising PENABLE. These are two distinct clock cycles with different control values — they cannot be collapsed. This alone makes the hard floor two cycles: there is no legal way to complete a transfer in one PCLK cycle, ever.
  • Part two — the extensible ACCESS phase. The ACCESS phase is not one cycle wide by definition; it is held for as long as the subordinate keeps PREADY low. Each cycle the manager sits in ACCESS with PREADY sampled low is one wait state. When the subordinate finally drives PREADY high, that cycle is the completing cycle — the manager samples PRDATA (on a read) and the transfer ends. So the ACCESS phase is one-or-more cycles.

Put the two parts together and the transfer length is:

length = 1 (SETUP) + 1 (first ACCESS) + N (wait states) = 2 + N cycles, N ≥ 0.

The floor is 2 (a zero-wait slave), and there is no ceiling in the protocol — the count is set by the subordinate, not fixed by the bus. Three refinements sharpen the model:

  • "Simple" governs concurrency, not duration. APB's simplicity is that it is unpipelined — only one transfer is ever in flight. That says the next transfer waits for this one; it says nothing about how many cycles this one takes. Duration is a PREADY question, entirely separate from the pipelining question.
  • The manager's obligation is a sample, not a count. A correct manager does not "wait a fixed number of cycles"; it samples PREADY at every ACCESS edge and only completes when it reads high. The moment you model completion as a count you have re-introduced the myth.
  • Zero-wait is a slave choice, not a protocol guarantee. A slave may tie PREADY high and give you the 2-cycle minimum on every access — but nothing in the protocol promises the slave you actually integrate against will do so. Designing for the minimum is designing for a slave you might not get.
Two-column comparison. The left red column titled MYTH shows a one-cycle waveform marked WRONG, a list of where the belief comes from, and the bugs it causes. The right green column titled REALITY shows a SETUP-plus-ACCESS-plus-waits waveform, the two-phase rule from the spec, and the cycle counts: minimum two cycles, 2 + N with N wait states.
Figure 1 — the single-cycle myth (left, red) versus the true two-phase, wait-state-extensible reality (right, green). The myth column shows the false one-cycle mental model — control and data collapsed into a single PCLK cycle — with where the belief comes from (confusing simple and unpipelined with single-cycle, only ever seeing zero-wait slaves, collapsing SETUP and ACCESS into one cell) and the bugs it ships (a manager that never samples PREADY, a fixed one-cycle slave model that breaks on a real slow peripheral, data captured in the wrong phase). The reality column shows the mandatory SETUP-then-ACCESS structure — minimum two cycles — with the ACCESS phase held while PREADY is low, giving a transfer length of 2 + N cycles bounded only by the slave. The figure is the chapter's spine: replace the fixed count with a two-phase floor plus a PREADY-governed extension.

4. Real SoC implementation

The fastest way to kill the myth is a counterexample it cannot survive: one real read that is unambiguously more than one cycle. Take a subordinate that needs time to fetch — a flash-shadow register, a clock-divided peripheral, a CDC bridge — and inserts two wait states. The read is then SETUP + ACCESS + 2 waits = 4 cycles.

Here is a compact subordinate that produces exactly that, using the real APB signals, followed by the cycle-by-cycle numbers.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// A subordinate that needs two wait states before its read data is valid.
// One read through this block is SETUP + ACCESS + 2 waits = 4 PCLK cycles.
module apb_slow_read_slave #(parameter int WAITS = 2) (
  input  logic        pclk,
  input  logic        presetn,
  input  logic        psel,
  input  logic        penable,
  input  logic        pwrite,
  input  logic [11:0] paddr,
  input  logic [31:0] pwdata,
  output logic [31:0] prdata,
  output logic        pready,
  output logic        pslverr
);
  logic [3:0] cnt;          // counts wait cycles inside the ACCESS phase
  logic [31:0] mem [0:1023];
 
  // ACCESS phase = psel && penable. Hold PREADY low for WAITS cycles, then complete.
  always_ff @(posedge pclk or negedge presetn) begin
    if (!presetn) begin
      cnt    <= '0;
      pready <= 1'b0;
      prdata <= '0;
    end else if (psel && penable) begin      // we are in the ACCESS phase
      if (cnt == WAITS) begin
        pready <= 1'b1;                       // completing cycle: data is now valid
        prdata <= mem[paddr[11:2]];           // present read data on the SAME edge PREADY rises
      end else begin
        cnt    <= cnt + 1'b1;                 // still fetching: insert one more wait state
        pready <= 1'b0;                       // PREADY low => ACCESS is held one more cycle
      end
    end else begin                            // SETUP or idle: not in ACCESS, not ready
      cnt    <= '0;
      pready <= 1'b0;
    end
  end
 
  assign pslverr = 1'b0;                       // no error path in this minimal example
endmodule

Now the numbers for one read, the counterexample in full. PADDR is stable across all four cycles; PSEL is high throughout.

| Cycle | Phase | PSEL | PENABLE | PREADY | PRDATA | What happens | | --- | --- | --- | --- | --- | --- | | C1 | SETUP | 1 | 0 | 0 | — | Manager drives PADDR/PWRITE; PENABLE still low. | | C2 | ACCESS (wait 1) | 1 | 1 | 0 | invalid | Manager raises PENABLE, samples PREADY — low, so it stays in ACCESS. | | C3 | ACCESS (wait 2) | 1 | 1 | 0 | invalid | Second wait state; PREADY still low, ACCESS held again. | | C4 | ACCESS (complete) | 1 | 1 | 1 | valid | Slave drives valid PRDATA and raises PREADY; manager samples the data and completes. |

That read is four cycles. Set WAITS = 0 and the same module gives you a two-cycle read (SETUP + a single ACCESS that is immediately ready) — still not one cycle. There is no parameter value, no address, no configuration of this legal subordinate that produces a one-cycle transfer, because the SETUP phase is unconditional. The myth predicts one cycle; the spec-compliant hardware produces two-or-more. The counterexample stands, and one counterexample is all it takes to falsify a universal claim.

5. Engineering tradeoffs

If the transfer is never one cycle, the real design question is how many cycles, and that is a genuine tradeoff surface — the myth's damage is that it hides this surface entirely.

  • Minimum-latency (zero-wait) slaves vs. area/timing. A subordinate can tie PREADY high and answer in the 2-cycle minimum, but only if its read-data path closes timing combinationally within one ACCESS cycle. A large register file, a memory macro, or anything behind a CDC boundary usually cannot, so it chooses wait states to buy setup time. The tradeoff is latency (more wait states) versus timing closure and area (a faster, wider, more pipelined data path). The myth erases this choice by pretending latency is fixed at one.
  • Fixed-count managers vs. PREADY-sampling managers. A manager that assumes a fixed cycle count is smaller and simpler — no PREADY input to route or sample. But it is only correct against the exact slave it was tuned to, and it breaks silently against any other. A PREADY-sampling manager costs one extra sampled input and a tiny bit of FSM logic and is correct against every legal slave. The correct trade is always to sample; the "saving" from not sampling is a latent integration bug, not a real saving.
  • Modelling a slave as a one-cycle latch vs. a wait-capable model. In early architecture models it is tempting to stub every peripheral as a one-cycle latch for speed. That is fine as an abstraction only if the surrounding manager still samples a (constant-high) ready; the moment the stub's fixed latency leaks into the manager's assumptions, you have baked the myth into the model and it will diverge from silicon.

The throughline: APB gives you a latency dial (wait states), not a latency constant. Every real design sits somewhere on that dial for good timing/area reasons, and every correct manager must tolerate the whole dial. The myth's cost is that it convinces you the dial does not exist.

6. Common RTL mistakes

7. Debugging scenario

The myth ships a specific, recognisable field bug. Here is the canonical one.

  • Observed symptom: a driver that has worked for months against an on-chip register block starts reading garbage — and occasionally hanging — the moment it is pointed at a newly added peripheral (say, a flash-configuration block or a sensor bridge behind a clock divider). Reads from the old block are still fine. The bus shows no protocol error flagged.
  • Waveform clue: on the new peripheral's transfers, PRDATA is being sampled while PREADY is still low. The manager raises PENABLE, and one cycle later — without checking PREADY — it latches PRDATA and moves on. The new slave, however, holds PREADY low for one or two cycles because its data path is slower, so at the manager's sampling edge PRDATA is not yet valid. The old register block tied PREADY high, so the manager's premature sample happened to always land on valid data and the bug stayed invisible for months.
  • Root cause: the manager was written on the myth. Its FSM treats ACCESS as exactly one cycle — SETUP -> ACCESS -> DONE, unconditional — and it never samples PREADY. Against a zero-wait slave that fixed timing is accidentally correct; against a wait-inserting slave it completes early, reads the pre-fetch value, and (if the manager also asserts the next SETUP on top of the still-active ACCESS) can wedge the bus.
  • Correct RTL: make ACCESS conditional on PREADY — hold until it is sampled high, then complete.
    Azvya Education Pvt. Ltd.VLSI Mentor
    Snippet
    // Manager FSM: ACCESS is HELD until PREADY is sampled high. No fixed count.
    always_ff @(posedge pclk or negedge presetn) begin
      if (!presetn) state <= IDLE;
      else case (state)
        IDLE:   if (start)            state <= SETUP;
        SETUP:                        state <= ACCESS;    // one SETUP cycle, always
        ACCESS: if (pready)           state <= DONE;      // complete only when READY high
                // else: stay in ACCESS -> this IS the wait state
        DONE:                         state <= IDLE;
      endcase
    end
    // Sample read data on the completing edge only:
    assign capture_rdata = (state == ACCESS) && pready && !pwrite;
  • Debug habit: when a driver works on one peripheral and fails on a newly integrated one, do not start in the data path — check whether the manager is sampling PREADY at all. Overlay PENABLE, PREADY, and the manager's data-capture strobe on one capture. If the capture strobe fires on a cycle where PREADY is low, you have found a myth-based manager, and the fix is to gate completion (and the read-data sample) on PREADY, not on a fixed cycle count.
An APB read waveform spanning four PCLK cycles with signals PCLK, PSEL, PENABLE, PADDR, PRDATA and PREADY. PSEL is high throughout, PENABLE is low in cycle one then high, PADDR is stable, PRDATA becomes valid only in cycle four, and PREADY is low through cycles two and three then rises in cycle four where a marked completing edge shows the manager sampling data. A banner reads SETUP plus ACCESS plus two wait states equals four cycles, not one cycle.
Figure 2 — the multi-cycle counterexample as a waveform: one APB read that is four cycles wide. C1 is SETUP (PSEL high, PENABLE low). C2 enters ACCESS (PENABLE high) but the slave holds PREADY low — wait state one. C3 is wait state two, still PREADY low, ACCESS held. C4 is the completing cycle: the slave drives valid PRDATA and raises PREADY, so the manager samples the data on the marked completing edge and the transfer ends. PADDR is stable across all four cycles. The banner states SETUP + ACCESS + 2 wait states = 4 cycles — not one cycle — and notes the same read is 2 cycles with zero waits and 2 + N with N waits, the count being set by the slave, never fixed at 1.

8. Verification perspective

Verifying against the myth means proving two things: that the DUT never assumes a one-cycle transfer, and that it tolerates the full range of legal transfer lengths. That is an assertion job plus a coverage job.

  • The core safety property: never complete or sample without PREADY. A manager must not treat a transfer as done — and must not latch read data — on a cycle where PREADY is low. Write it as a PREADY-gated completion assertion:
    Azvya Education Pvt. Ltd.VLSI Mentor
    Snippet
    // A manager must not complete an access until PREADY is sampled high.
    // If we are in ACCESS (psel && penable) and PREADY is low, we must remain in ACCESS.
    property p_no_complete_without_pready;
      @(posedge pclk) disable iff (!presetn)
        (psel && penable && !pready) |=> (psel && penable);
    endproperty
    a_no_complete_without_pready: assert property (p_no_complete_without_pready);
     
    // And read data must only be captured on the completing (PREADY-high) ACCESS edge.
    a_rdata_sampled_ready: assert property (
      @(posedge pclk) disable iff (!presetn)
        (capture_rdata && !pwrite) |-> (psel && penable && pready)
    );
  • The floor property: no transfer is ever one cycle. Assert that PENABLE is always preceded by a SETUP cycle — i.e. the ACCESS phase can never be entered in the same cycle a fresh PSEL rises — which is the structural guarantee that the minimum is two cycles: (!psel ##1 psel) |-> !penable on the newly-selected cycle.
  • The coverage side: hit the whole latency dial. A PREADY-gated assertion proves correctness under waits, but you only trust it if the stimulus actually produces waits. Cover 0, 1, 2, and a "many" bucket of wait states per transfer, and cover back-to-back transfers of different latencies (a zero-wait access abutting a multi-wait one) — the mixed-latency case is where a myth-based manager that "usually works" finally exposes itself. A responder VIP that randomises PREADY delay is the standard way to sweep the dial; a responder that only ever ties PREADY high will hide every myth bug, exactly as the buggy silicon did.

The point: one PREADY-gated completion assertion catches the entire class of myth bugs, but it is only as good as stimulus that inserts real, varied wait states — so the verification plan is "gate completion on PREADY, then randomise the wait count so the gate actually gets tested."

9. Interview discussion

"Is an APB transfer single-cycle?" is a deceptively good screening question, because the confident-but-wrong "yes, APB is single-cycle, it's the simple one" answer instantly separates spec-readers from people who have watched real APB waveforms.

The strong answer is two sentences and a counterexample. First, state the correction from the spec: APB (IHI 0024C §3.1) defines every transfer as a two-phase SETUP-then-ACCESS sequence, so the minimum is two clock cycles, and there is no legal one-cycle transfer because the SETUP phase is unconditional. Second, give the extension: the ACCESS phase is held while PREADY is low, so a transfer is 2 + N cycles for N wait states, bounded only by the subordinate — a slow peripheral behind a clock divider or a CDC bridge routinely inserts waits. Then land the counterexample: "a read from a two-wait-state slave is four cycles — SETUP, ACCESS, wait, complete — and the same read is two cycles against a zero-wait slave, so the length is a slave choice, not a fixed constant." If asked where the myth comes from, name the confusion: "unpipelined" governs concurrency, not duration — people hear "simple, one transfer at a time" and wrongly compress it to "one cycle per transfer." Closing with "so a correct manager samples PREADY at every ACCESS edge rather than counting cycles, and that's the bug I look for first when a driver works on one peripheral and fails on a new one" signals you have debugged this in silicon, not just read the diagram.

10. Practice

  1. Falsify the claim. In two sentences, refute "an APB transfer is one cycle" using the spec's two-phase definition, and state the exact minimum cycle count with a one-line justification.
  2. Count the cycles. A subordinate inserts three wait states on a read. Write the transfer length as a formula in terms of the wait count N, evaluate it for this case, and label each cycle by phase (SETUP / ACCESS / wait / complete).
  3. Trace the myth to a bug. A manager FSM is SETUP -> ACCESS -> DONE with an unconditional ACCESS -> DONE edge. Explain precisely what goes wrong when this manager talks to a two-wait-state slave, and name which cycle the read data is (wrongly) sampled.
  4. Fix the manager. Rewrite the FSM edge from practice 3 so ACCESS is held until PREADY is sampled high, and write the one condition under which read data may be captured.
  5. Explain the propagation. Explain why the phrase "single-cycle transfer" is a cause of the myth even though the transfer it names is actually two cycles, and state the wait-state count that phrase really refers to.

11. Q&A

12. Key takeaways

  • An APB transfer is never one clock cycle. It is a mandatory two-phase sequence — SETUP then ACCESS (IHI 0024C §3.1) — so the minimum is two cycles, and the SETUP phase is unconditional, meaning no legal transfer completes in one cycle.
  • Transfer length is 2 + N, bounded only by the slave. The ACCESS phase is held while PREADY is low; each held cycle is one wait state. A zero-wait slave gives the two-cycle floor; a slow peripheral gives 2 + N. The count is a slave choice, not a protocol constant.
  • The myth comes from three confusions: treating "simple / unpipelined" as "single-cycle" (unpipelined governs concurrency, not duration), only ever seeing zero-wait slaves, and collapsing the two phases into one mental cell. The loose phrase "single-cycle transfer" (which really means zero wait states) propagates it.
  • The myth ships real bugs: a manager that never samples PREADY and completes on a fixed count, and a fixed one-cycle slave model that breaks against any real slow peripheral (flash, CDC bridge, clock-divided block). The correct manager samples PREADY at every ACCESS edge and captures read data only on the completing edge.
  • Verify it with one PREADY-gated completion assertion plus wait-state coverage. Prove the manager cannot complete or sample read data while PREADY is low, then randomise the wait count (0, 1, 2, many, and mixed-latency back-to-back) so the gate is actually exercised — a responder that only ties PREADY high hides every myth bug.