An APB-slave RTL interview is not testing whether you have read the spec — it is testing whether you can write the seven-piece slave on a whiteboard without dropping the one term that makes a write fire once instead of twice. Module 17 has walked the register bank, the address decoder, the read-data mux, the write logic, PREADY generation, and reset behaviour. This chapter is the question bank that turns that knowledge into code under pressure — the questions a senior RTL lead actually asks, each answered with short, correct, synthesizable SystemVerilog using the real signal names. The single idea to carry: almost every APB-slave RTL question resolves to one of three disciplines — gate every committing action on the full completion term psel && penable && pwrite && pready, derive PREADY from a registered, reset-known state, and give every combinational output a defined default so no latch infers. Hold those three and the bank below collapses into restatements.
1. What this chapter covers
This is the code-heavy interview tier: the APB-slave RTL questions where a verbal answer is not enough and the interviewer hands you a marker. It covers the PREADY-generation FSM (combinational versus registered, and how to insert N wait states); the golden write-enable term wr_en = psel && penable && pwrite && pready and why dropping pready makes a wait-extended write fire on every wait cycle; the read-data mux and registered PRDATA; address decode and one-hot select; the register-bank patterns — RW, RO, WO, and W1C; reset strategy (synchronous versus asynchronous, and guaranteeing a known PREADY out of reset); latch avoidance in combinational decode; and parameterised register maps.
Every answer here is anchored to one APB fact from the spec: a transfer completes on the cycle where PSEL, PENABLE, and PREADY are all high (APB IHI 0024C §2.1) — and that conjunction is the qualifier on which every write commit, every read return, and every status update depends.
2. Why this matters now
You have built each slave piece in isolation and each is correct on its own. But an interview never asks you to recite a piece — it asks you to write it, fast, and the failure mode is never the piece, it is the integration term you drop while writing under time pressure. The classic example: you know the write commits in the access phase, so you write if (psel && penable && pwrite) reg <= pwdata; — clean, readable, and wrong, because on a wait-extended access PENABLE stays high for every wait cycle and your register is written on each of them. The bug is invisible in a zero-wait directed test and ships.
The interview tests exactly this gap between knowing the piece and writing the composed circuit correctly. Three things separate a strong candidate:
- They reach for the full completion term reflexively. Every committing action — write, W1C clear, WO strobe — carries
pready, because completion ispsel && penable && pready, never a subset. They never writepenable-alone gates. - They drive
PREADYfrom a known, registered state. They can say whatPREADYis the cycle after reset deasserts, because an undriven or XPREADYout of reset is a hang waiting to happen. - They give every combinational block a default. A read mux or a decode without a default infers a latch, and a lead asks "where's the latch?" precisely to see if you anticipated it.
So the skill to add is not another piece — it is writing the composition correctly the first time, with the qualifier, the reset-known PREADY, and the no-latch default baked in by habit.
3. Mental model
The model: answer every APB-slave RTL question by asking which of three disciplines it tests, then write the smallest correct snippet that honours it. The three disciplines are the spine of the whole bank.
- Gate every commit on the completion conjunction. Completion is
psel && penable && pready(APB IHI 0024C §2.1). Any action that changes state — a register write, a W1C clear, a WO pulse, a side-effect-on-read — must be qualified by that term (pluspwritefor writes), so it happens on exactly the one completing cycle and never during a wait. The golden form iswr_en = psel && penable && pwrite && pready. - Derive
PREADYfrom a registered, reset-known state.PREADYis the bit the manager samples to decide completion, so it must be glitch-free at the sampling edge and defined the instant reset deasserts. A registeredPREADYthat resets to a known value (high for an always-ready slave, or low-then-rising for a wait-capable FSM) is the safe default; a combinationalPREADYoff a rippling decode is the classic glitch hazard. - Default every combinational output. A read mux, a decode, or any
always_combthat does not assign its output on every path infers a latch. GivePRDATAa'0default, useunique casewith adefault, and the design is latch-free by construction.
Three refinements sharpen the model:
- The write-enable term is the single most-tested line in the whole bank. If you remember nothing else, remember that the commit qualifier is the four-way conjunction
psel && penable && pwrite && pready, and that droppingpreadyis what fires the write twice. - Reads have no side effects by default, but
PRDATAmust still be valid the cyclePREADYis high. A registeredPRDATAwith a tied-highPREADYships stale reads; keep the two phase-aligned (combinationalPRDATAwith always-readyPREADY, or both registered together). - Reset is a property of every flop in the slave, and
PREADYis the one flop whose reset value is load-bearing. A slave that powers up withPREADYundriven can hang the very first access; reset it explicitly on the correct polarity.
4. Real SoC / hardware context
These are not academic snippets — each maps to a peripheral that ships in real silicon. Consider a GPIO block with a control register (RW), a pin-state register (RO, hardware-owned), an interrupt-flag register (W1C), and a command-strobe register (WO). Every one of those four kinds has a distinct RTL pattern, and an interviewer probes whether you know them apart: a candidate who writes the W1C flag as a plain RW register ships a peripheral whose interrupt can never be cleared without clobbering a flag the hardware set on the same cycle.
The write-enable term is the most expensive thing to get wrong in practice. A timer peripheral whose reload register is written on penable alone — without the pready qualifier — writes the reload value on every wait cycle of a wait-extended access; on a slow APB segment that means the same value is written two or three times, which is harmless until the day someone makes that register a counter that increments on write, and now it increments once per wait state instead of once per access. The bug surfaced in a write-corruption lab exactly this way: a register that "counted writes" counted wait cycles instead, because the commit was gated on penable and not on the completion term. The fix in every case is the same one line: gate the commit on psel && penable && pwrite && pready so it fires on the single completing edge.
PREADY out of reset is the other silicon-grade trap. A subordinate whose PREADY flop is left undriven on the reset path comes up X in gate-level simulation and can hang the first access after reset deasserts — a bug that a zero-delay RTL run hides because X propagates differently there. The discipline that prevents it is structural: reset PREADY to a known value on the correct polarity, every time.
5. Weak vs strong answers
This is the interview-grading table: each row is an APB-slave RTL question, the weak answer a junior gives, the strong answer a senior gives, and the RTL reason that decides it. Read it as the spine of the bank.
| RTL question | Weak answer | Strong answer | RTL reason |
|---|---|---|---|
| "What qualifies a register write?" | "psel && penable && pwrite — it's the write access phase." | "psel && penable && pwrite && pready — the completing cycle, not just the access phase." | On a wait-extended access penable is high for every wait cycle; without pready the write commits on each one. |
"How do you build PREADY for N wait states?" | "Tie a counter to pready combinationally." | "A registered FSM/counter: load on access start, count down, assert pready on the last cycle, drop after completion." | A combinational PREADY off a rippling counter glitches into the sample window; registered PREADY is glitch-free at the edge. |
"What is PREADY the cycle after reset?" | "Whatever the logic settles to." | "A known reset value — 1'b1 for always-ready, 1'b0 for a wait FSM — driven on the reset path." | An undriven/X PREADY out of reset can hang the first access; reset every flop on the correct polarity. |
| "How do you avoid a latch in the read mux?" | "Assign prdata in each case branch." | "Default prdata = '0 first, then unique case with a default branch." | A combinational block that misses a path infers a latch; a leading default covers every unlisted select. |
| "How do you implement a W1C status bit?" | "Make it RW and let software clear it." | "Hardware-set wins; software write-1 clears only the bits it targets, on the completing edge." | W1C has joint ownership — a plain RW lets a software clear and a hardware set on the same cycle race and lose the event. |
"Should PRDATA be registered or combinational?" | "Register it — registered outputs are always safer." | "Either, but PREADY and PRDATA must agree on the completing cycle." | A registered PRDATA with a tied-high PREADY asserts ready a cycle before data is valid — stale reads. |
The throughline: every weak answer drops a condition — the pready qualifier, the register on PREADY, the reset value, the latch default, the ownership rule, or the phase alignment — and the strong answer restores the full term. The interview is, in every row, a test of whether you compose the pieces with all their conditions intact.
6. Common RTL mistakes / red flags
7. Interview framing
APB-slave RTL is the most code-heavy APB topic, and the questions are deliberately open: "design a single-register slave," "make PREADY for N wait states," "why does your write fire twice." A weak candidate describes the answer in prose; a strong one writes the snippet, names the qualifier or default that makes it correct, and points to the failure mode of the wrong version.
The framing that lands every time is write the snippet, then name the term that makes it correct, then state the bug the wrong version ships. When asked for the write-enable, do not just write the line — write it and say "the pready term is load-bearing: drop it and a wait-extended write fires once per wait cycle, which is the double-write bug." When asked for PREADY, write the registered FSM and say "it resets to a known value on presetn, so the first access can't hang on an X." When asked for the read mux, write the '0 default first and say "this is what keeps it latch-free." The strongest single move is to volunteer the unifying point: every APB-slave RTL bug is either a missing completion qualifier, an unknown/glitchy PREADY, or a missing combinational default — and you fix all three by habit, not by debugging. If you can also sketch the datapath of Figure 1 from memory and the double-write of Figure 2, the interviewer knows you have built slaves, not just read about them.
8. Q&A
9. Practice
- Write the single-register slave. From a blank page, write the §8
apb_single_regfrom memory — the four-waywr_en, the reset-knownPREADY, and the defaulted read mux — without looking. Then state the bug each of the three lines prevents. - Build PREADY for N=3. Write the registered wait-state FSM/counter that inserts exactly three wait cycles, asserting
PREADYon the completing cycle and dropping after. ConfirmPREADYis known out of reset and never combinationally glitches. - Spot the double-write. From Figure 2, name the missing qualifier, predict the exact waveform of
wr_enon a two-wait-state write, and write the one-line fix. Then explain why a zero-wait directed test would never catch it. - Implement the four register kinds. Write the RTL for one RW, one RO (hardware-owned), one W1C (hardware-set wins), and one WO (one-cycle strobe, reads 0) register, each sharing the same
wr_en. State what each reads back. - Fix the stale read. Given a slave with a registered
PRDATAandpready = 1'b1, predict the waveform on a back-to-back read of two different registers, write the SVAassert propertythat catches a completing read returning the wrong register, and write the corrected phase-aligned RTL.
10. Key takeaways
- Gate every committing action on
psel && penable && pwrite && pready. Completion ispsel && penable && pready(APB IHI 0024C §2.1); dropping thepreadyqualifier makes a wait-extended write fire on every wait cycle — the double-write that is the single most-tested red flag in the bank. - Derive
PREADYfrom a registered, reset-known state. A registeredPREADYis glitch-free at the sampling edge, and an explicit reset value (high for always-ready, low for a wait FSM) means the first access after reset never hangs on anX. - Default every combinational output. Lead the read-mux
always_combwithprdata = '0, useunique casewith adefault, and decode only whenpselis high — so no latch infers and an unmapped read returns0. - Know the four register kinds apart. RW commits on
wr_en; RO follows a hardware source and ignoreswr_en; W1C clears only written bits with a same-cycle hardware set winning; WO pulses one cycle and reads back0. - Keep
PREADYandPRDATAphase-aligned. CombinationalPRDATAwith always-readyPREADY, or both registered on the same edge — never a floppedPRDATAwith a tied-highPREADY, which ships stale reads. - Every APB-slave RTL bug is one of three: a missing completion qualifier, an unknown or glitchy
PREADY, or a missing combinational default. Write the snippet, name the term that makes it correct, and state the bug the wrong version ships.