Skip to content
VLSI Mentor

Wishbone · Module 5

The Wishbone Handshake

The smallest correct conversation between a Wishbone master and slave: a master presents a transfer and holds it, a slave terminates it, and the transaction exists across an interval rather than at an instant.

Module 4 gave every signal in the Classic interface a meaning, an owner, and a qualifying condition. It deliberately stopped before the question those twelve definitions exist to answer.

What is the smallest correct conversation between a Wishbone master and slave?

1. A Transaction Is an Interval, Not an Event

This is the single idea the rest of the module rests on.

It is tempting to think of a transfer as happening at a moment — the master "sends" a request, the slave "sends" a reply. That model is wrong in a way that produces real bugs, because Wishbone Classic has no messages and nothing is ever sent.

What actually happens is that the master drives a set of levels and holds them. The transfer is presented, continuously, for as many cycles as it takes. The slave sees those levels at every rising edge. When the slave is ready, it drives its termination, and the master — sampling at the same edges — observes it.

Three consequences follow immediately, and each is a chapter later in this module.

The request must persist. A master that presents a transfer and changes its mind next cycle has not performed a transfer; it has produced two partial ones. Chapter 5.5 is about what must be latched and held.

The termination must be attributed. A termination means this outstanding transfer completed. A master that sees ACK_I without knowing which of its own requests it belongs to cannot use it. Chapter 5.6 is about the completion edge.

The duration is not fixed and not knowable in advance. A slave answers when it can. Chapter 5.4 covers what that means for the master.

2. Who Owns Which Transition

Every edge in a Wishbone waveform is driven by exactly one side. Confusing ownership is the root of an entire class of debugging dead ends, so it is worth tabulating before any waveform appears.

TransitionOwnerGoverned by
CYC_O risesmasterRULE 3.25 — no later than the edge qualifying STB_O
STB_O risesmasterpresents the transfer
ADR/DAT/WE/SEL become meaningfulmasterRULE 3.60 — qualified by STB_O
ACK_O risesslaveRULE 3.35 — in response to CYC_I & STB_I
DAT_O becomes meaningful (read)slaveRULE 3.65 — qualified by its termination
STB_O fallsmasterafter observing the termination
ACK_O fallsslaveRULE 3.50 — in response to STB_I negating
CYC_O fallsmasterwhen the cycle is over

Read the last three rows together. The master drops STB_O because it saw ACK_O; the slave drops ACK_O because it saw STB_O drop. That is a loop, and OBSERVATION 3.10 describes the slave half of it as automatic: "SLAVE interfaces automatically negate [ACK_O], [ERR_O] and [RTY_O] when their [STB_I] is negated."

The loop is not a race, because both sides sample at the same rising edge and Wishbone is synchronous throughout — but it is why Chapter 5.7 has to separate what a signal does in simulation time from what is observed at an edge.

3. The Canonical Handshake

CYC, STB, ACK: one transfer, one termination

6 cycles
Six clock cycles showing a single Wishbone read transfer. In cycle one nothing is asserted and the bus is idle. In cycle two the master asserts both the cycle and strobe signals together and drives a meaningful address; the slave is busy and does not acknowledge. In cycle three the request is still presented unchanged, and the slave still does not acknowledge. In cycle four the slave asserts its acknowledge and drives valid read data in the same cycle; this is the termination edge. In cycle five the master has observed the acknowledge and has negated both the cycle and strobe signals, and the slave has correspondingly negated its acknowledge and stopped driving read data. Cycle six is idle again. The essential observation is that the request occupied three cycles and terminated in exactly one.request presentedrequest presentedTERMINATION edgeTERMINATION edgereleasedreleasedCLK_ICYC_OSTB_OADR_O----0x4000x4000x400--------WE_OACK_IDAT_I------------0xA5--------t0t1t2t3t4t5
Figure 1 — the minimal single-transfer handshake. The master's claim persists; the slave's answer terminates it.

Narrate it edge by edge — this is the habit the whole module is training.

Before edge 2: the master drives CYC_O, STB_O and a meaningful ADR_O. Nothing has been observed yet.

At edge 2: the slave samples CYC_I & STB_I true. It now has a request. The master samples ACK_I low — no termination, so its transfer is still outstanding.

Between edges 2 and 3: everything the master drives must stay exactly as it is. This is RULE 3.60's qualification read as an obligation across a multi-cycle presentation.

At edge 3: same again. The slave is still working; the master still waits.

Before edge 4: the slave has driven ACK_O and valid read data.

At edge 4 — the termination edge: the master samples ACK_I high. This is the only edge at which the transfer completes, and it is the one edge at which DAT_I is meaningful, per RULE 3.65.

After edge 4: the master may negate CYC_O and STB_O. The slave, seeing STB_I negate, drops ACK_O and stops driving read data.

Count the cycles. The request was presented for three; the termination occupied one. A learner who can produce that narration from a waveform has the core skill this module teaches.

4. RTL — The Running Example

Module 5 uses one system throughout, extended as chapters require, rather than a new toy per chapter:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
client request  →  wb_hs_master  →  Wishbone Classic  →  wb_hs_slave  →  registers

Conventions, inherited from Module 4 unchanged. AW = 30 word addresses on a 32-bit bus — Chapter 4.3 explained why the two byte-offset bits are not on the bus. DW = 32. SW = DW/8 = 4 byte lanes, per Chapter 4.7. Synchronous active-high reset per RULES 2.30 and 3.00. The qualified-transfer term is always xfer = cyc_i & stb_i.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// wb_hs_master — the minimal correct single-transfer master.
//
// PURPOSE. Show the smallest master that performs a complete, correct
// handshake. Every later chapter's master is this one with a specific
// weakness repaired, so it is worth reading closely.
//
// INTERFACE. A local client presents a request with req_i; the master
// reports completion with done_o. The client side is NOT Wishbone and is
// deliberately shaped differently so the two are never confused.
//
// CYC/STB. Driven from ONE register here. That is not laziness and it is
// not universally correct — it is explicitly permitted:
//
//   PERMISSION 3.40 — "If a MASTER doesn't generate wait states, then
//   [STB_O] and [CYC_O] MAY be assigned the same signal."
//
// This master never negates STB_O mid-transfer, so the permission applies.
// Chapter 5.2 shows the case where it does not.
//
// Reset: SYNCHRONOUS, ACTIVE HIGH (RULES 2.30, 3.00, 3.20).
// ─────────────────────────────────────────────────────────────────────────
module wb_hs_master #(
  parameter int unsigned AW = 30,
  parameter int unsigned DW = 32
) (
  input  logic            clk_i,
  input  logic            rst_i,

  // ── local client side (not Wishbone) ────────────────────────────────
  input  logic            req_i,        // pulse: start a transfer
  input  logic            req_we_i,
  input  logic [AW-1:0]   req_adr_i,
  input  logic [DW-1:0]   req_dat_i,
  input  logic [DW/8-1:0] req_sel_i,
  output logic            busy_o,
  output logic            done_o,       // one-cycle pulse
  output logic [DW-1:0]   done_dat_o,   // read result, held after done_o

  // ── Wishbone MASTER interface ───────────────────────────────────────
  output logic            cyc_o,
  output logic            stb_o,
  output logic            we_o,
  output logic [AW-1:0]   adr_o,
  output logic [DW-1:0]   dat_o,
  output logic [DW/8-1:0] sel_o,
  input  logic [DW-1:0]   dat_i,
  input  logic            ack_i,
  input  logic            err_i,
  input  logic            rty_i
);
  // ── STATE ─────────────────────────────────────────────────────────────
  // active_q is the whole state machine: the transfer is either outstanding
  // or it is not. The metadata registers are what make the request PERSIST,
  // which Section 1 identified as the first obligation of an interval-based
  // protocol. Driving adr_o straight from req_adr_i would work only if the
  // client happened to hold it — Chapter 5.5 makes that failure concrete.
  logic            active_q;
  logic            we_q;
  logic [AW-1:0]   adr_q;
  logic [DW-1:0]   dat_q;
  logic [DW/8-1:0] sel_q;

  // ── COMBINATIONAL ─────────────────────────────────────────────────────
  // Both qualifiers come from active_q (PERMISSION 3.40). Everything else
  // comes from the latched metadata, so it is stable for exactly as long as
  // the strobe is asserted — RULE 3.60's qualification met structurally
  // rather than by a promise in a comment.
  assign cyc_o  = active_q;
  assign stb_o  = active_q;
  assign we_o   = we_q;
  assign adr_o  = adr_q;
  assign dat_o  = dat_q;
  assign sel_o  = sel_q;
  assign busy_o = active_q;

  // Any of the three terminations ends the transfer. Chapters 4.11 and 4.12
  // covered what ERR and RTY additionally oblige; here they end it.
  logic terminated;
  assign terminated = ack_i | err_i | rty_i;

  // ── SEQUENTIAL ────────────────────────────────────────────────────────
  always_ff @(posedge clk_i) begin
    if (rst_i) begin
      // RULE 3.20: STB_O and CYC_O negated at the rising edge following the
      // assertion of RST_I, and held negated. active_q drives both.
      active_q   <= 1'b0;
      we_q       <= 1'b0;
      adr_q      <= '0;
      dat_q      <= '0;
      sel_q      <= '0;
      done_o     <= 1'b0;
      done_dat_o <= '0;
    end else begin
      done_o <= 1'b0;                    // default: done_o is a pulse

      if (!active_q) begin
        // ── REQUEST START ───────────────────────────────────────────────
        // The metadata is captured HERE, once. From the next edge onward
        // the client may do whatever it likes with its inputs.
        if (req_i) begin
          active_q <= 1'b1;
          we_q     <= req_we_i;
          adr_q    <= req_adr_i;
          dat_q    <= req_dat_i;
          sel_q    <= req_sel_i;
        end
      end else if (terminated) begin
        // ── TERMINATION ─────────────────────────────────────────────────
        // Sampled as a LEVEL in the cycle the transfer is presented, never
        // as an edge. Chapter 5.4 explains why an edge would be wrong.
        active_q <= 1'b0;
        done_o   <= 1'b1;
        // Read data is captured on a SUCCESSFUL READ only: there is no
        // defined read value on ERR or RTY (Chapter 4.5), and a write has
        // no read data at all.
        if (ack_i && !we_q) done_dat_o <= dat_i;
      end
    end
  end
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// wb_hs_slave — the minimal correct register-bank slave.
//
// PURPOSE. Answer every qualified transfer, in the cycle it is presented.
//
// TERMINATION TIMING. ack_o is combinational from the qualified transfer.
// That is not a shortcut; it is the form the specification anticipates:
//
//   PERMISSION 3.30 — "The assertion of [ACK_O], [ERR_O], and [RTY_O] MAY
//   be asynchronous to the [CLK_I] signal (i.e. there is a combinatorial
//   logic path between [STB_I] and [ACK_O])."
//
//   OBSERVATION 3.40 — "The asynchronous assertion ... assures that the
//   interface can accomplish one data transfer per clock cycle."
//
// Chapter 5.7 weighs that against OBSERVATION 3.50's loopback delay.
//
// Reset: SYNCHRONOUS, ACTIVE HIGH (RULES 2.30, 3.00).
// ─────────────────────────────────────────────────────────────────────────
module wb_hs_slave #(
  parameter int unsigned OFF_AW = 4,             // 16 local registers
  parameter int unsigned DW     = 32
) (
  input  logic              clk_i,
  input  logic              rst_i,
  input  logic              cyc_i,
  input  logic              stb_i,
  input  logic              we_i,
  input  logic [OFF_AW-1:0] adr_i,               // LOCAL offset
  input  logic [DW-1:0]     dat_i,
  input  logic [DW/8-1:0]   sel_i,
  output logic [DW-1:0]     dat_o,
  output logic              ack_o,
  output logic [DW-1:0]     reg0_o               // observable state
);
  localparam int unsigned NL = DW/8;

  localparam logic [OFF_AW-1:0] R_CTRL  = 'd0;
  localparam logic [OFF_AW-1:0] R_SCRAT = 'd1;
  localparam logic [OFF_AW-1:0] R_ID    = 'd2;   // read-only constant

  logic [DW-1:0] ctrl_q, scrat_q;
  assign reg0_o = ctrl_q;

  // ── THE QUALIFIED TRANSFER ────────────────────────────────────────────
  // RULE 3.30 forbids responding to any slave signal while CYC_I is negated.
  // RULE 3.35 requires the termination to be generated from the AND of
  // CYC_I and STB_I. One term, used everywhere.
  logic xfer;
  assign xfer = cyc_i & stb_i;

  // This slave keeps pace and does not use ERR_O or RTY_O, so it is exactly
  // the case PERMISSION 3.10 describes: ACK_O tied to the AND of STB_I and
  // CYC_I. Adding an error output would move it under PERMISSION 3.15.
  assign ack_o = xfer;

  // ── WRITE ACCEPTANCE ──────────────────────────────────────────────────
  // Gated on ack_o, NOT merely on xfer. Here they are identical because
  // this slave never waits — but writing it this way makes the rule
  // explicit, and Chapter 5.3's delayed slave depends on the distinction:
  // a request PRESENTED for four cycles must still be ACCEPTED once.
  logic write_ok;
  assign write_ok = xfer & we_i & ack_o & (adr_i != R_ID);

  always_ff @(posedge clk_i) begin
    if (rst_i) begin
      ctrl_q  <= '0;
      scrat_q <= '0;
    end else if (write_ok) begin
      for (int unsigned n = 0; n < NL; n++) begin
        if (sel_i[n]) begin
          unique case (adr_i)
            R_CTRL:  ctrl_q [n*8 +: 8] <= dat_i[n*8 +: 8];
            R_SCRAT: scrat_q[n*8 +: 8] <= dat_i[n*8 +: 8];
            default: ;
          endcase
        end
      end
    end
  end

  // ── READ PATH ─────────────────────────────────────────────────────────
  // RULE 3.65: a slave qualifies its DAT_O with its termination. Driving
  // zero otherwise also keeps a merged return path clean (Chapter 3.5).
  always_comb begin
    dat_o = '0;
    if (xfer && !we_i && ack_o) begin
      unique case (adr_i)
        R_CTRL:  dat_o = ctrl_q;
        R_SCRAT: dat_o = scrat_q;
        R_ID:    dat_o = 32'h5742_0001;          // "WB", revision 1
        default: dat_o = '0;
      endcase
    end
  end
endmodule

Reading the pair

Purpose. Together these are a complete, correct Wishbone Classic path. Everything in Module 5 after this chapter is a refinement of one of them.

Interface. The client side (req_i / done_o / busy_o) is deliberately not Wishbone-shaped. Keeping the two vocabularies visibly different is what stops a reader assuming the client protocol and the bus protocol have the same rules — they do not, and Chapter 5.5 turns that into a design obligation.

State. The master holds one flag plus the request metadata. The slave holds two registers. The metadata registers are the interesting part: they exist solely so the request persists across edges the client knows nothing about.

Combinational behaviour. Master: both qualifiers and all four detail outputs, straight from state. Slave: the qualified-transfer term, the acknowledge, the write-acceptance term, and the read multiplexer.

Sequential behaviour. Master: capture on req_i, release on termination. Slave: one lane-gated register update.

Request start. CYC_O and STB_O both rise at the edge following req_i, satisfying RULE 3.25's "no later than" trivially by rising together.

Waiting. Everything the master drives comes from registers that are written only at the start edge, so stability across the wait is structural.

Termination. The master samples ack_i/err_i/rty_i as levels while active_q is set.

Read data. Captured only on ack_i && !we_q.

Write data. dat_o is driven from dat_q for the whole transfer, including reads — legal, because RULE 3.60 qualifies DAT_O with STB_O and not with WE_O. Chapter 4.6 showed why a slave must therefore check WE_I.

Reset. Synchronous, active high; active_q <= 0 negates both qualifiers per RULE 3.20.

Failure modes. Section 6, and every subsequent chapter.

Simplifications. One outstanding transfer. No ERR_O/RTY_O in the slave. No wait states — added in 5.3. No interconnect; the slave's adr_i is assumed already decoded to a local offset, as Chapter 3.5 described.

5. The Debugging Path

When a Wishbone transfer misbehaves, there are four places to look and they are always the same four. Establishing the order here means later chapters can refer to it instead of repeating it.

A horizontal block diagram with four probe points across a Wishbone path. On the left is the master, with probe point one on its outgoing cycle and strobe signals. An arrow labelled forward path leads to the interconnect, then to the slave, where probe point two observes the cycle and strobe arriving. Inside the slave, probe point three observes the locally generated acknowledge. An arrow labelled return path leads back through the interconnect to the master, where probe point four observes the acknowledge actually arriving. Beneath the diagram a note explains that the first probe point at which the expected signal is missing identifies which stage is at fault.MASTERP1: CYC_O / STB_O driven?INTERCONforward pathSLAVEP2: CYC_I / STB_I seen?SLAVE LOGICP3: ACK_O generated?RETURN PATHP4: ACK_I at the master?12
Figure 2 — the four probe points. Where the handshake stops being visible names the guilty stage.

Probe in order, and stop at the first surprise.

P1 — does the master drive CYC_O and STB_O at all? If not, the fault is in the master's own state machine or its client interface, and nothing downstream matters.

P2 — do they arrive at the intended slave? If P1 is fine and P2 is empty, the fault is address decode or forward routing in the interconnect. The slave is innocent.

P3 — does the slave generate ACK_O locally? If P2 is fine and P3 is empty, the fault is inside the slave. If ACK_O appears at a different slave than intended, it is a decode problem masquerading as a slave problem.

P4 — does ACK_I reach the master? If P3 is fine and P4 is empty, the fault is the return path — the response multiplexer, or a master that does not implement the termination the slave produced. OBSERVATION 3.35 names the second case explicitly: "If the SLAVE supports the [ERR_O] or [RTY_O] signals, but the MASTER does not support these signals, deadlock may occur."

Why this ordering matters more than it looks. All four failures produce the same symptom at the master — a strobe held forever with no termination. Chapter 4.8 called that the signature of an unanswered transfer, and it is, but it does not say who failed to answer. The probe sequence is what converts one symptom into one location.

6. Failure Modes and Discriminating Evidence

Symptom: the master hangs with STB_O asserted and no termination.

Candidate causes. Any of the four stages in Section 5.

Discriminating evidence. Walk P1→P4. The first probe where the expected signal is absent names the stage. This is the only systematic way to tell the four apart, because the master-side waveform is identical for all of them.

Likely RTL location. Determined by the probe, not guessed.

Property. A bounded-completion check — see Chapter 5.8 for why that is local policy rather than a protocol rule, and RECOMMENDATION 3.10 for what the specification suggests instead.

Symptom: the master completes immediately, always, regardless of address.

Candidate causes. A slave with ACK_O tied high rather than tied to the qualified transfer.

Discriminating evidence. Check ACK_O while CYC_I and STB_I are both low. Asserted is conclusive and is a direct RULE 3.35 violation.

Likely RTL location. The slave's ack_o assignment.

Symptom: read data is wrong but the transfer completes normally.

Candidate causes. The master captures outside the termination cycle, or the slave drives data outside its termination.

Discriminating evidence. Compare the slave's DAT_O in the acknowledged cycle against what the master stored. Correct at the slave and wrong at the master isolates the capture; wrong at both isolates the slave and is a RULE 3.65 violation.

Likely RTL location. The master's capture condition, or the slave's read-path gating.

Symptom: the transfer works once and the second one never starts.

Candidate causes. The master never returned to idle — active_q was not cleared, usually because the termination branch is unreachable.

Discriminating evidence. busy_o stuck high with no STB_O, or STB_O never dropping after an observed ACK_I.

Likely RTL location. The master's termination branch.

7. Verification

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// wb_hs_checker — the module-wide handshake invariants, in one place.
//
// These four are re-used and extended by every later chapter in Module 5.
// Each is labelled SPECIFICATION or LOCAL POLICY, because the distinction
// changes what a failure means and who has to fix it.
// ─────────────────────────────────────────────────────────────────────────
module wb_hs_checker #(
  parameter int unsigned DW = 32
) (
  input logic          clk_i,
  input logic          rst_i,
  input logic          cyc_o,
  input logic          stb_o,
  input logic          ack_i,
  input logic          err_i,
  input logic          rty_i,
  input logic          m_active,      // white-box: transfer outstanding
  input logic          m_done         // white-box: local completion pulse
);
  default disable iff (rst_i);

  // P1 — SPECIFICATION (RULE 3.25). CYC_O is asserted no later than the
  //      edge that qualifies STB_O, so a strobe without a cycle is never
  //      legal. Stated as the plain implication, checked every cycle:
  //      writing it as $rose(stb_o) |-> $rose(cyc_o) would WRONGLY forbid
  //      a master that opens its cycle early to request the bus.
  property p_stb_implies_cyc;
    @(posedge clk_i) stb_o |-> cyc_o;
  endproperty
  a_stb_implies_cyc : assert property (p_stb_implies_cyc)
    else $error("RULE 3.25: STB_O asserted without CYC_O");

  // P2 — SPECIFICATION (RULE 3.45). The three terminations are mutually
  //      exclusive. Written as an explicit integer sum rather than with
  //      $countones over a concatenation: Chapter 3.7 recorded an Icarus
  //      defect in exactly that construct which produced phantom failures.
  property p_one_termination;
    @(posedge clk_i) (int'(ack_i) + int'(err_i) + int'(rty_i)) <= 1;
  endproperty
  a_one_termination : assert property (p_one_termination)
    else $error("RULE 3.45: more than one termination asserted");

  // P3 — LOCAL POLICY. A termination is only meaningful against an
  //      outstanding transfer. This is NOT a Wishbone rule — the bus
  //      cannot see a master's intent — but a master acting on a
  //      termination it did not provoke is always wrong.
  property p_termination_needs_outstanding;
    @(posedge clk_i) (ack_i || err_i || rty_i) |-> m_active;
  endproperty
  a_termination_needs_outstanding :
    assert property (p_termination_needs_outstanding)
    else $error("termination observed with no outstanding transfer");

  // P4 — LOCAL POLICY. One bus transaction yields exactly one local
  //      completion. Catches a duplicated done_o pulse, which silently
  //      double-counts at the client.
  property p_one_done_per_transaction;
    @(posedge clk_i) m_done |-> $past(m_active && (ack_i || err_i || rty_i));
  endproperty
  a_one_done_per_transaction : assert property (p_one_done_per_transaction)
    else $error("local completion without a matching bus termination");
endmodule

P1 and P2 are conformance; a passive monitor on the bus can check both, and they hold for every Wishbone interface ever built.

P3 and P4 need white-box signals and encode this master's contract rather than the standard's. That split is not incidental — Chapter 4.9 §7 showed that protocol conformance is checkable from wires while intent is not, and Chapter 5.8 makes the distinction a design tool.

Tooling limitation. Icarus Verilog has no SVA support and cannot execute any of these. They are reviewed by inspection only; the synthesizable RTL above is elaborated and simulated, and this module reports the two separately throughout.

8. Common Mistakes

"STB is valid and ACK is ready."

Wrong mental model: importing valid/ready semantics wholesale.

Concrete bug: a slave asserting ACK_O as an advertised readiness, independent of any presented transfer — typically tied high.

Observable evidence: every transfer completing in one cycle including ones to unmapped addresses, and, in a shared fabric, transfers completing that were addressed to a different slave.

Correct model: RULE 3.35 makes the termination a response. The nearest legal equivalent is PERMISSION 3.10's ACK_O tied to the AND of STB_I and CYC_I — which is a response, and which carries two preconditions.

"The request is sent, so the master can move on."

Wrong mental model: a transfer is a message.

Concrete bug: a master that drives ADR_O from a live client input rather than a latched copy, so the address changes while the transfer is outstanding.

Observable evidence: the slave acting on an address the client had already moved past — and under a fast slave the bug never appears at all, because the transfer completes before anything changes.

Correct model: the transfer is presented continuously and must persist until terminated. Chapter 5.5 builds the master that gets this right and simulates the failure.

"ACK arriving means the data is on the bus somewhere."

Wrong mental model: read data is available around the acknowledge.

Concrete bug: capturing DAT_I one cycle after ACK_I.

Observable evidence: every read returning the previous read's value — the off-by-one Chapter 4.5 traced.

Correct model: RULE 3.65 qualifies the slave's DAT_O with its termination. The data is meaningful in the termination cycle and is not held afterwards.

9. Interview Reasoning

A master presents a transfer and holds it until a slave terminates it.

The master's claim has two parts. CYC_O says a bus cycle is in progress — this master is mid-operation and, in a shared system, is requesting the bus. STB_O says that within that cycle, a specific transfer is being presented right now. Everything else the master drives — address, write data, direction, byte lanes — is detail about that transfer, and RULE 3.60 makes it meaningful only while the strobe qualifies it.

The slave's answer is a response, not a state. RULE 3.35 requires the termination to be generated in response to the logical AND of CYC_I and STB_I. The slave is not reporting its own condition; it is answering a specific question it was asked.

The transfer occupies an interval. It begins at the edge where the slave first observes the qualified request and ends at the edge where the master observes the termination. In between, the master changes nothing and the slave works.

Why I would avoid the valid/ready framing even loosely. It predicts that a slave can advertise readiness with no request present, and that prediction is exactly wrong — a slave doing so terminates transfers it was never given, including other slaves'. The analogy fails at the one place a candidate is most likely to be tested.

The asymmetry worth naming. Initiation is entirely the master's; completion is entirely the slave's. Neither can do the other's job, and there is no negotiation — which is why the whole protocol fits in three wires.

10. Understanding Check

11. What's Next

The handshake is now visible as a whole: a claim, a wait, an answer, a release. The rest of Module 5 takes it apart.

Both halves of the master's claim have been driven from one register so far, and PERMISSION 3.40 says that is fine — for a master that never waits. But the two signals mean different things, and the difference decides what happens to a transfer when a master releases the bus too early.

When does a basic bus cycle begin and end, relative to the transfer inside it?

Chapter 5.2 — CYC — Cycle answers it. The full path is on the Wishbone curriculum index.

Continue learning

Standards & specifications

Governing standard
Wishbone SoC Interconnection Architecture (OpenCores)(opens OpenCores in a new tab)

Defines the Wishbone signal set, the bus cycles built from it and the interface rules a portable IP core must follow. It deliberately leaves interconnect topology, address map and arbitration policy to the integrator, so those are system decisions rather than requirements of the specification.

This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.

Where this fits

Part of the Wishbone curriculum.