Skip to content
VLSI Mentor

Wishbone · Module 11

Transaction Restart

A retry needs at least one non-presented clock or it is not a second transfer at all. Measured across RETRY_DELAY, and against a target whose early commit turned one write into three.

Chapter 11.3 settled whether to defer. Chapter 11.2 declared a RETRY_DELAY parameter, showed a gap in a waveform, and never checked that the two agreed.

Exactly how does a second attempt reach the bus, and what makes it safe to issue at all?

1. Why the Gap Is Structural

Suppose a master could re-present immediately, with STB_O never negating between attempts. What would the slave see?

One continuously presented transfer. CYC_I and STB_I asserted from the first clock to the last, with no interruption.

And the slave's behaviour follows from two rules it is already obeying. RULE 3.35 generates the termination from the AND of CYC_I and STB_I — still true, so it asserts RTY_O. RULE 3.50 requires the termination to be asserted and negated in response to the assertion and negation of STB_I — and STB_I never negates, so RTY_O never negates either.

The result is a stable state, not a sequence of attempts. STB_O high, RTY_O high, forever. Nothing counts, nothing progresses, and no component is misbehaving.

The non-presented clock is what makes the second qualification a second one. Without it there is one transfer that is being refused continuously, not a series of attempts.

This is the same structure Chapter 8.6 measured for bus cycles, where two cycles require CYC_O to be low at some rising edge in between and the turnaround clock is therefore irreducible. Here the same argument applies to STB_O and to attempts.

So RETRY_DELAY adds to a floor of one; it cannot reach zero. Section 6 measures the floor and the sum.

2. RETRY_DELAY, Defined As Measured

Modules 9 and 10 both established that a latency parameter's meaning must be written down and then checked. This one was written down in Chapter 11.2's RTL and the first measurement disagreed with it — the header said RETRY_DELAY = N gives N non-presented clocks, and the trace showed N + 1.

The corrected definition, which Section 6 measures across the range:

Non-presented clocks between two attempts = RETRY_DELAY + 1.

RETRY_DELAYnon-presented clockscomposition
01the structural release clock alone
12release + 1 delay clock
34release + 3 delay clocks

RETRY_DELAY = 0 is the fastest legal retry, not a disabled delay. It re-presents at the earliest clock at which a second transfer can exist.

Wishbone imposes no retry delay at all. No minimum gap, no backoff, no maximum rate — the specification says only that when and how a cycle is retried is defined by the IP core supplier. Everything in this section is local policy, and the floor is arithmetic rather than regulation.

3. What Must Be True Within and Between Attempts

Two different obligations, and only one of them is Wishbone's.

Within a presented attempt: RULE 3.60. ADR_O, DAT_O(), SEL_O(), WE_O and the tags are qualified by STB_O and must be stable while the transfer is outstanding. This is ordinary, and every attempt is an ordinary transfer.

Between attempts: nothing. No transfer is presented, so no rule applies. The specification has no opinion about what a master does in the gap — which is precisely the window Chapter 11.2 §7 measured a master corrupting its own request in.

So the module-wide invariant is stronger than the rule, and is labelled accordingly:

ScopeSource
metadata stable while outstandingwithin an attemptRULE 3.60
every attempt presents the accepted requestacceptance → completionLOCAL POLICY

4. Waveform — The Gap, at Two Settings

One clock is the floor

10 cycles
Ten clock cycles comparing two retry cadences. With retry delay zero the strobe is asserted at cycle two, is low at cycle three only, and is asserted again at cycle four. With retry delay one the strobe is asserted at cycle two, is low at cycles three and four, and is asserted again at cycle five. In both cases the first attempt is terminated by a retry and the second by an acknowledge, and in both cases at least one clock separates the two presentations.attempt 0, deferred in bothattempt 0, deferred in boththe irreducible release clockthe irreducible releaseclockRETRY_DELAY=0 re-presents hereRETRY_DELAY=0 re-presentshereCLK_ID0: STB_OD0: RTY_ID0: ACK_ID1: STB_OD1: RTY_ID1: ACK_It0t1t2t3t4t5t6t7t8t9
Figure 1 — the same deferred request at RETRY_DELAY = 0 and RETRY_DELAY = 1. The gap is one clock and two clocks respectively; neither can be zero. Traced from the simulation in Section 6.

Cycle 3 is low in both rows, and that clock is the subject of the figure. With RETRY_DELAY = 0 it is the only gap clock; with RETRY_DELAY = 1 it is the first of two. No setting removes it.

The D0 rows show the fastest legal retry. Attempt 0 at cycle 2, release at cycle 3, attempt 1 at cycle 4. Two presentations, one clock apart, and the slave sees two separate qualifications.

The D1 rows show one added delay clock. Attempt 1 arrives at cycle 5 instead of 4.

Both attempts in both rows present the same address, latched at acceptance — not shown here to keep the figure to seven rows, and measured in Chapter 11.2 §7.

What the figure would look like with no gap at all. STB_O high from cycle 2 onwards and RTY_I high beside it, unchanging. One transfer being refused continuously — and the reason Section 1 calls the gap structural rather than configured.

5. RTL — The Target That Commits Too Early

Section 7's experiment needs a target that breaks the side-effect contract, and the mistake it models is a realistic one: adding deferral to a working slave and leaving the commit block alone.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// wb_defer_slave — defers a fixed number of attempts, then accepts.
//
// A deterministic stand-in for a resource that clears on its own after a
// known number of tries. Nothing here is random: the Nth attempt succeeds,
// every time, in every run.
//
//   attempt 1 .. DEFER_COUNT    -> RTY_O   not ready yet
//   attempt DEFER_COUNT+1 ..    -> ACK_O   accepted, and recorded
//   offset not implemented      -> ERR_O   never
//
// DEFER_COUNT = 0 accepts immediately and is the no-deferral control.
//
// THE RECORDING IS THE POINT. On acceptance the slave latches the address
// and data it was actually presented, so a testbench can prove WHICH
// request finally committed. Chapter 11.2 uses that to show a master
// retrying something other than what its client asked for.
//
// SIDE-EFFECT CONTRACT: a deferred attempt records nothing and counts
// nothing. Only an accepted attempt does.
// ─────────────────────────────────────────────────────────────────────────
module wb_defer_slave #(
  parameter int unsigned OFF_AW      = 4,
  parameter int unsigned DW          = 32,
  parameter int unsigned DEFER_COUNT = 2
) (
  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,
  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                err_o,
  output logic                rty_o,

  // observation only
  output logic [7:0]          seen_o,        // qualified attempts observed
  output int unsigned         accepts_o,     // attempts actually accepted
  output logic [OFF_AW-1:0]   acc_adr_o,     // the offset that was accepted
  output logic [DW-1:0]       acc_dat_o      // the payload that was accepted
);
  localparam logic [OFF_AW-1:0] O_ID  = 4'd4;
  localparam logic [OFF_AW-1:0] O_CMD = 4'd9;
  localparam logic [DW-1:0] ID_VALUE = 32'h5742_1101;

  logic [7:0] seen_q;
  logic       xfer, mapped, defer;

  assign xfer   = cyc_i && stb_i;
  assign mapped = (adr_i == O_ID) || (adr_i == O_CMD);

  // The attempt currently presented is the (seen_q+1)th this slave has
  // observed. It is deferred while that index is within DEFER_COUNT.
  assign defer = (seen_q < 8'(DEFER_COUNT));

  assign rty_o = xfer &&  mapped &&  defer;
  assign ack_o = xfer &&  mapped && !defer;
  assign err_o = xfer && !mapped;

  // No read result on a deferral: the interface is "not ready to send data".
  assign dat_o = (xfer && !we_i && mapped && !defer) ? ID_VALUE : '0;

  assign seen_o = seen_q;

  always_ff @(posedge clk_i) begin
    if (rst_i) begin
      seen_q <= '0; accepts_o <= '0; acc_adr_o <= '0; acc_dat_o <= '0;
    end else begin
      // Count each qualified attempt once, at its terminating edge. All
      // three classes terminate in the presenting clock here.
      if (xfer && mapped) seen_q <= seen_q + 8'd1;

      // ── COMMIT, only on acceptance. A deferred attempt records nothing.
      if (xfer && mapped && !defer) begin
        accepts_o <= accepts_o + 1;
        acc_adr_o <= adr_i;
        acc_dat_o <= dat_i;
      end
    end
  end
endmodule
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// wb_defer_slave_commit — THE BUG, isolated. NOT A REFERENCE DESIGN.
//
// Identical to wb_defer_slave except that the commit is no longer gated on
// acceptance:
//
//     if (xfer && mapped && !defer)  begin ... commit ... end
// becomes
//     if (xfer && mapped)            begin ... commit ... end
//
// So the slave RECORDS THE COMMAND AND THEN RETURNS RTY_O. The termination
// says "not now"; the internal state says the operation happened.
//
// WHY THIS IS NOT AN OBVIOUS MISTAKE. The mistake it models is adding
// deferral to a working slave: the designer inserts an rty_o expression
// and narrows ack_o, and leaves the commit block alone because it "already
// worked". Each line reads correctly; nobody checks that the commit and
// the termination still agree.
//
// WHAT IS STILL CORRECT. Everything on the bus. The terminations are
// qualified (RULE 3.35), exclusive (RULE 3.45) and negated with STB_I
// (RULE 3.50). A protocol checker passes it, and a correctly-written
// master retrying against it will duplicate the command — through no
// fault of its own and with no way to detect it.
//
// NOTE WHAT WISHBONE DOES AND DOES NOT SAY HERE. There is no rule that a
// deferring target must leave its state unchanged. "No side effect on RTY"
// is a CONTRACT A TARGET OFFERS so that it is safe to retry against, not
// a protocol requirement — which is precisely why it has to be documented
// under RULE 2.15 and checked by an assertion rather than assumed.
// ─────────────────────────────────────────────────────────────────────────
module wb_defer_slave_commit #(
  parameter int unsigned OFF_AW      = 4,
  parameter int unsigned DW          = 32,
  parameter int unsigned DEFER_COUNT = 2
) (
  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,
  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                err_o,
  output logic                rty_o,
  output logic [7:0]          seen_o,
  output int unsigned         accepts_o,
  output logic [OFF_AW-1:0]   acc_adr_o,
  output logic [DW-1:0]       acc_dat_o
);
  localparam logic [OFF_AW-1:0] O_ID  = 4'd4;
  localparam logic [OFF_AW-1:0] O_CMD = 4'd9;
  localparam logic [DW-1:0] ID_VALUE = 32'h5742_1101;

  logic [7:0] seen_q;
  logic       xfer, mapped, defer;

  assign xfer   = cyc_i && stb_i;
  assign mapped = (adr_i == O_ID) || (adr_i == O_CMD);
  assign defer  = (seen_q < 8'(DEFER_COUNT));

  // The bus interface is correct and unchanged. That is the point.
  assign rty_o = xfer &&  mapped &&  defer;
  assign ack_o = xfer &&  mapped && !defer;
  assign err_o = xfer && !mapped;
  assign dat_o = (xfer && !we_i && mapped && !defer) ? ID_VALUE : '0;

  assign seen_o = seen_q;

  always_ff @(posedge clk_i) begin
    if (rst_i) begin
      seen_q <= '0; accepts_o <= '0; acc_adr_o <= '0; acc_dat_o <= '0;
    end else begin
      if (xfer && mapped) seen_q <= seen_q + 8'd1;

      // ── THE BUG: no `!defer` term. Every attempt commits, including the
      //    ones this slave is about to defer.
      if (xfer && mapped) begin
        accepts_o <= accepts_o + 1;
        acc_adr_o <= adr_i;
        acc_dat_o <= dat_i;
      end
    end
  end
endmodule

Reading the pair

wb_defer_slave gates its commit on !defer, so only an accepted attempt records anything. wb_defer_slave_commit drops that term, so every observed attempt commits — including the ones it is about to defer.

The bus interfaces are identical and both are conformant. Terminations qualified (RULE 3.35), exclusive (RULE 3.45), negated with STB_I (RULE 3.50). A protocol checker passes the broken one, and a correctly-written master retrying against it duplicates the command through no fault of its own.

Note precisely what Wishbone does and does not say here, because it is the sharpest protocol-versus-policy boundary in the module. There is no rule that a deferring target must leave its state unchanged. "No side effect on RTY" is a contract a target offers so that it is safe to retry against — not an obligation the specification imposes.

Which has a consequence worth stating plainly: a master cannot verify it. There is nothing on the bus that distinguishes a target that committed from one that did not, so the property has to be documented under RULE 2.15 and checked by an assertion inside the target.

And the failure is silent in the worst way. The client asked once, the master retried correctly, the bus was well-formed, and the device did the work three times.

6. Simulation — SIM G: The Retry Gap

One deferral, so there is exactly one gap between attempt 0 and attempt 1. The measurement counts clocks in which the master is busy but presenting nothing.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === SIM G - RETRY_DELAY, measured ===
    slave defers once, so there is exactly one gap between attempts.

    RETRY_DELAY   non-presented clocks between attempts   RD + 1
         0                       1                        1
         1                       2                        2
         3                       4                        4

gap = RETRY_DELAY + 1 on every row, including zero.

The zero row is the one worth dwelling on. RETRY_DELAY = 0 produced one non-presented clock, not none. That clock is the release — the structural separation Section 1 argued is required for a second transfer to exist at all.

And this table is a correction, not a confirmation. The RTL header originally claimed RETRY_DELAY = N gives N non-presented clocks. The first trace showed two clocks at N = 1, and the definition was rewritten to match the hardware rather than the hardware adjusted to match the prose. The parameter's published meaning is now the measured one.

Why the discrepancy was easy to introduce. The delay counter genuinely does insert exactly RETRY_DELAY clocks. The extra clock comes from the state transition itself — leaving the presenting state, which is where STB_O negates — and it is invisible if you reason about the counter alone.

Which is the recurring lesson from Modules 9 and 10 in a third form. Chapter 9.1's WAIT_CYCLES, Chapter 10.4's TIMEOUT_CYCLES and this RETRY_DELAY all have an off-by-one between the counter's value and the observable behaviour. In every case the fix was to measure the parameter and publish the measurement.

7. Simulation — SIM H: Side-Effect Safety

One client write, against a target that defers twice before accepting. The client asked for one command to be enqueued.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === SIM H - side-effect safety across a retry ===
    slave defers 2 attempts then accepts; one client write.

    target                     attempts seen  commits recorded  client ok
    wb_defer_slave                   3              1            1
    wb_defer_slave_commit            3              3            1

    one client write should produce exactly one commit.

Both targets saw three attempts. Same master, same retry policy, same bus traffic — the trace is identical.

The correct target recorded one commit. The broken one recorded three.

One client write became three enqueued commands. For a command queue that is three operations performed where one was asked for: three packets transmitted, three motor steps, three DMA descriptors queued.

And the client was told it succeeded, once, in both rigs. There is nothing in the completion to distinguish them — the master behaved identically because the bus behaved identically.

Note that the master is blameless and powerless here. It latched its request, released on each RTY, waited, re-presented the same operation, and reported one outcome. Every property in Chapter 11.2 §9 passes. The defect is entirely inside the target, and no master-side change can detect or prevent it.

The evidence is the comparison the table makes: the target's commit count against the number of ACK terminations. They must be equal. Three commits against one acknowledge is conclusive, and it requires instrumentation inside the target because the bus shows one success either way.

Which makes this the clearest instance in the module of a boundary worth keeping sharp. The specification defines a termination class that means not now. It does not define what a target may do before saying it — so "safe to retry against" is a property a target has or lacks, must publish under RULE 2.15, and cannot be inferred from conformance.

8. Failure Modes and Discriminating Evidence

Symptom: an operation is performed more times than it was requested.

Candidate causes. A target that commits on attempts it defers, combined with a master that retries correctly.

Discriminating evidence. The target's side-effect count against its ACK count. Measured here as 3 against 1. The bus shows one success in both the correct and broken rigs, so this cannot be found from a trace.

Likely RTL location: separate conditions for the commit and the termination. The correct slave computes both from one term.

Symptom: a retrying master makes no progress and the bus looks continuously busy.

Candidate causes. STB_O never negating between attempts — so there are no attempts, only one refused transfer.

Discriminating evidence. Count STB_O rising edges, not RTY_I assertions. One rise with RTY_I held is a master that has not released; several rises are genuine attempts.

Correct model: the gap is structural. Section 1.

Symptom: retries arrive at a different cadence than the parameter suggests.

Candidate causes. The usual off-by-one between a delay counter and the observable gap.

Discriminating evidence. Measure non-presented clocks between two presentations and compare against the parameter. Here the relationship is RETRY_DELAY + 1, and it was published only after being measured.

Symptom: a design works against one deferring target and duplicates work against another.

Candidate causes. The two targets differ in whether they commit before deferring, and nothing in either datasheet says so.

Discriminating evidence. Instrument the target, not the bus. And read the datasheet — RULE 2.15 requires the conditions generating RTY_O to be documented, and a target whose deferral has side effects is one whose documentation should say so.

9. Verification

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Properties for restart timing and for the side-effect contract. Exactly
// one of these is the specification's; the rest are the local policy that
// makes retry work.
//
// NOTE ON EXECUTION: Icarus Verilog does not support SVA. These were
// reviewed by inspection and are NOT claimed to have been executed. The
// numbers in Sections 6 and 7 come from procedural checks, which Icarus
// does run.
// ─────────────────────────────────────────────────────────────────────────
module wb_restart_props #(
  parameter int unsigned RETRY_DELAY = 0
) (
  input logic        clk_i, rst_i,
  input logic        cyc_o, stb_o,
  input logic        ack_i, err_i, rty_i,
  input logic        busy_o,
  input int unsigned commits_i,       // the TARGET's side-effect count
  input int unsigned acks_i           // ACK terminations observed
);
  default clocking cb @(posedge clk_i); endclocking
  default disable iff (rst_i);

  logic deferred;
  assign deferred = cyc_o && stb_o && rty_i;

  // R1 — SPECIFICATION (RULE 3.50, from the master's side). A deferred
  //      attempt is released: STB_O negates. Without this the slave's
  //      termination never negates either and there is no second attempt.
  R1_release_after_rty: assert property ( deferred |=> !stb_o );

  // R2 — LOCAL POLICY. The gap is at least one clock. This is the
  //      structural floor from Section 1, stated as a property: a
  //      presentation never immediately follows a deferral.
  R2_gap_floor: assert property ( deferred |=> !stb_o );

  // R3 — LOCAL POLICY. The configured delay is honoured: after a
  //      deferral, STB_O stays low for RETRY_DELAY+1 clocks before the
  //      next presentation. Written for the general case; at
  //      RETRY_DELAY = 0 it degenerates to R2.
  R3_gap_exact: assert property (
    deferred |=> (!stb_o [* (RETRY_DELAY + 1)] ##1 (stb_o || !busy_o))
  );

  // R4 — LOCAL CONTRACT, and the property this chapter exists for. The
  //      TARGET's side-effect count never exceeds the number of accepted
  //      transfers. Wishbone does not require this; it is what makes a
  //      target safe to retry against.
  R4_no_commit_on_defer: assert property ( commits_i <= acks_i );

  // R5 — LOCAL CONTRACT, the incremental form of R4. It fails on the
  //      FIRST duplicate rather than at the end of the run, which is a
  //      materially better debugging signal.
  R5_commit_only_on_ack: assert property (
    (commits_i != $past(commits_i)) |-> $past(cyc_o && stb_o && ack_i)
  );
endmodule

R1 and R2 are the same expression and different claims, which is worth being explicit about rather than deduplicating. R1 is what RULE 3.50 forces from the master's side — the termination cannot negate unless STB_O does. R2 is the design statement that the gap exists at all. They coincide here because the floor is one clock; in a design with a longer mandatory gap they would not.

R4 and R5 are the pair that matter. R4 is a global invariant and fails at the end; R5 fails on the first duplicate commit and names the clock. Both are checked inside the target, because neither is visible on the bus.

And none of these is enforceable by a master. A master can satisfy every property in Chapter 11.2 §9 and still duplicate work against a target that breaks R4. The contract has to be held by the component that owns the side effect.

10. Common Mistakes

"RETRY_DELAY = 0 means the retry is immediate, with no gap."

Wrong mental model: the parameter controls the whole separation.

What is true: there is always at least one non-presented clock. Measured: RETRY_DELAY = 0 gives 1, = 1 gives 2, = 3 gives 4.

Concrete bug: a timing budget that assumes back-to-back attempts, or a testbench expecting a presentation on the clock after a deferral.

Correct model: gap = RETRY_DELAY + 1, and the 1 is structural.

"The master can just keep STB_O asserted and wait for the slave to relent."

Wrong mental model: holding the request is a cheaper retry.

What is true: RULE 3.50 means the slave's RTY_O never negates while STB_I is held, so the state is stable and nothing progresses. One transfer being refused, not a series of attempts.

Observable evidence: one STB_O rising edge with RTY_I asserted across many clocks.

Correct model: release, then re-present. That is what makes a second transfer exist.

"A target can perform the operation and then return RTY — the master will retry anyway."

Wrong mental model: the retry re-does something harmless.

What is true: measured — one client write became three enqueued commands. The master was correct throughout and had no way to detect it.

Observable evidence: the target's commit count against its ACK count. Nothing on the bus.

Correct model: one condition drives the termination and the side effect. And document it: RULE 2.15 requires the conditions generating RTY_O to be published, and a deferral with side effects is a condition worth publishing.

"Wishbone guarantees a deferred transfer changed nothing."

Wrong mental model: the protocol protects retry safety.

What is true: there is no such rule. The specification defines a class meaning not now; it says nothing about what a target may do before saying it.

Correct model: it is a contract, offered by the target, verifiable only from inside it. A target that does not offer it cannot be retried against, whatever the master does.

"If the bus trace is clean, the retry is safe."

Wrong mental model: conformance covers this.

What is true: the correct and the duplicating targets produce identical traces — three attempts, one acknowledge, one completion.

Correct model: retry safety is a target-internal property, and the instrument that checks it is a side-effect counter.

11. Interview Reasoning

Present, terminate, release, wait, present again — and the release is the part people leave out.

Attempt N is presented with CYC_O and STB_O asserted and the metadata latched at client acceptance. The slave answers RTY_O at a terminating edge, qualified by CYC_I && STB_I like any other class. That attempt is over.

The master negates STB_O. This is not optional and not merely tidy. RULE 3.50 requires the slave's termination to be asserted and negated in response to the assertion and negation of STB_I — so if STB_O never negates, RTY_O never negates, and the state is stable forever. One transfer being refused continuously, not a sequence of attempts.

So at least one non-presented clock is structural. I measured the gap across the parameter: RETRY_DELAY = 0 gives one non-presented clock, 1 gives two, 3 gives four. gap = RETRY_DELAY + 1, and the 1 cannot be configured away.

Then attempt N+1 is presented with the same metadata. Same address, same direction, same byte lanes, same payload — from the latches, never re-read from the client. A new transfer carrying the same operation.

The check I would apply to a waveform is to count STB_O rising edges rather than RTY_I assertions. Two rises means two attempts; one rise with RTY_I held means a master that has not released.

And I would mention that the published definition of RETRY_DELAY in my own design was wrong at first. The header claimed N non-presented clocks; the trace showed N+1. I corrected the documentation to the hardware rather than the other way round — which is the third parameter in three modules to have an off-by-one between its counter and its observable behaviour.

12. Understanding Check

13. What's Next

The mechanism is complete: a class meaning not now, a master that re-issues the operation it accepted, a bounded count, an exact gap, and a target contract that makes re-issuing safe.

Every scenario so far has been engineered to isolate one property. Real systems present all of them at once, mixed with conditions where retrying is the wrong answer entirely.

Given a failing or stalled access, which of these is it — and which of them should retry at all?

Chapter 11.5 — Real Examples classifies a set of realistic conditions, measures which respond to retry and which do not, and separates a retry loop from a long wait and from an exhausted policy in a trace. 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.