Skip to content
VLSI Mentor

Wishbone · Module 10

Invalid Accesses

A local invalid offset fails in 3 clocks through the peripheral, an unmapped address in 2 through the default responder, and with no responder at all the transfer never ends.

Chapter 10.2 generated every error from the same place: the selected peripheral decided it could not serve the access.

That is one source among several, and the others are worth separating because they have different owners, different evidence and — as Section 6 measures — different latencies.

What happens when the address does not belong to that peripheral, or to any peripheral at all?

1. Who Is Entitled to Report What

The rule of thumb is that the component that detects the fault should be the component that reports it, and the reason is that nothing else has the information.

A peripheral knows its own offsets. It knows word 7 is not implemented and that STATUS is read-only. Nothing upstream knows that without duplicating the peripheral's register map into the fabric, which is a maintenance disaster and the reason nobody does it.

A decoder knows which addresses it routes. It knows word 100 belongs to nothing. No peripheral knows that — each one only sees transfers that were addressed to it, and an unmapped access is by definition addressed to none.

So the two error sources are not interchangeable and cannot cover for each other. A peripheral cannot report an unmapped address because it never sees one; a decoder cannot report an unimplemented register because it does not know which registers exist.

And this is a system-architecture claim rather than a protocol one. Wishbone says nothing about who generates errors. What it says is:

ERR_I"indicates an abnormal cycle termination. The source of the error … is defined by the IP core supplier."

The source is supplier-defined, which means the architecture decides it and the datasheet records it — RULE 2.15 again. This chapter's system makes two decisions and writes both into the RTL headers.

2. The Default Responder

When the decoder selects nothing, something has to happen, and there are exactly two options.

Option one: nothing. No select line is asserted, no termination is generated, and the master waits forever. This is legal. Nothing in Wishbone requires an unmapped access to fail, and nothing requires an interconnect to contain a responder.

Option two: a default responder. A target that owns no registers, is selected precisely when nothing else is, and terminates every transfer presented to it with ERR_O. The unmapped access then fails deterministically, in bounded time, with a reportable class.

The specification's contribution here is one sentence, and it is advice about the fabric rather than a rule about the access:

RECOMMENDATION 3.10 — design INTERCON modules to prevent deadlock. One solution is a watchdog timer function that monitors the MASTER's STB_O signal.

Read what that does and does not say. It is a RECOMMENDATION, addressed to INTERCON, about deadlock. It suggests a solution — a watchdog — and a default responder is a different solution to the same problem. It does not say unmapped accesses must error, and it does not say a system without a responder is non-conformant.

So "every unmapped address produces ERR" is a property of a system that chose it, and stating it as protocol law is the misconception this chapter is built to correct.

The trade, stated honestly

SilentDefault responder
Unmapped accesshangs foreverfails in bounded time
Failure is reportablenoyes
Bug surfacesas a system hang, far from the causeat the access
Costnonea small always-selected target
Hidesnothingnothing — but see below

The one real argument against a default responder is that it converts a loud failure into a quiet one. A hang stops the system and gets investigated; a stream of errors may be logged and ignored. That is a system-design judgement about which failure mode your software handles better, not a protocol question — and a system with a responder and no error logging has arguably made things worse.

3. RTL — The Minimum Decode

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// wb_default_err_slave — the DEFAULT RESPONDER.
//
// A target that owns no registers and exists only to answer accesses that
// nothing else claims. It terminates every qualified transfer presented to
// it with ERR_O, immediately.
//
// THIS IS A SYSTEM ARCHITECTURE POLICY, NOT A WISHBONE REQUIREMENT.
// Nothing in the specification says an unmapped address must produce an
// error, and nothing says an interconnect must contain a responder like
// this. What the specification does say is that INTERCON modules should be
// designed to prevent deadlock — RECOMMENDATION 3.10 — and this is one of
// the two common ways to do that. The other is a watchdog, and Chapter
// 10.4 builds it.
//
// The choice being made here, explicitly: an access to an address nothing
// owns FAILS DETERMINISTICALLY rather than waiting forever. That trade is
// the subject of Chapter 10.3 Section 5.
// ─────────────────────────────────────────────────────────────────────────
module wb_default_err_slave #(
  parameter int unsigned DW = 32
) (
  input  logic            clk_i,
  input  logic            rst_i,
  input  logic            cyc_i,
  input  logic            stb_i,
  output logic [DW-1:0]   dat_o,
  output logic            ack_o,
  output logic            err_o,
  output int unsigned     hits_o        // observation only
);
  // RULE 3.35: generated from the AND of CYC_I and STB_I, like any other
  // termination. RULE 3.45 holds trivially — ack_o is tied low.
  assign ack_o = 1'b0;
  assign err_o = cyc_i && stb_i;

  // RULE 3.65 qualifies DAT_O() with the termination. A defined value,
  // chosen to be recognisable in a trace rather than plausible as data.
  assign dat_o = 32'hE22_0DEF;

  always_ff @(posedge clk_i) begin
    if (rst_i)                hits_o <= '0;
    else if (cyc_i && stb_i)  hits_o <= hits_o + 1;
  end
endmodule

// wb_err_fabric — the minimum decode needed to make error OWNERSHIP
// concrete. This is not an address-decoding tutorial; Module 12 owns that.
//
// The map is one region and everything else:
//
//   word 0..15    the register peripheral
//   anything else UNMAPPED
//
// HAS_DEFAULT selects what happens to an unmapped access:
//
//   1  the default responder is selected and answers ERR
//   0  NOTHING is selected. No termination is ever generated, and the
//      transfer stays outstanding forever. Chapter 10.3 SIM F measures
//      this deliberately, with a bounded observation window.
//
// WHY BOTH ARE LEGAL. Wishbone does not require an unmapped access to
// error, and does not require a default responder to exist. The silent
// configuration is a conformant Wishbone system that hangs on a software
// bug; the default-responder configuration is a conformant Wishbone system
// that fails cleanly. The specification's guidance is RECOMMENDATION 3.10 —
// design INTERCON to prevent deadlock — which is advice about the fabric,
// not a rule about the access.
// ─────────────────────────────────────────────────────────────────────────
module wb_err_fabric #(
  parameter int unsigned AW          = 30,
  parameter int unsigned DW          = 32,
  parameter bit          HAS_DEFAULT = 1'b1
) (
  input  logic            clk_i,
  input  logic            rst_i,

  // ── master side ──
  input  logic            m_cyc_i,
  input  logic            m_stb_i,
  input  logic            m_we_i,
  input  logic [AW-1:0]   m_adr_i,
  input  logic [DW-1:0]   m_dat_i,
  input  logic [DW/8-1:0] m_sel_i,
  output logic [DW-1:0]   m_dat_o,
  output logic            m_ack_o,
  output logic            m_err_o,

  // ── peripheral side ──
  output logic            p_cyc_o,
  output logic            p_stb_o,
  output logic            p_we_o,
  output logic [3:0]      p_adr_o,
  output logic [DW-1:0]   p_dat_o,
  output logic [DW/8-1:0] p_sel_o,
  input  logic [DW-1:0]   p_dat_i,
  input  logic            p_ack_i,
  input  logic            p_err_i,

  // ── observation only ──
  output logic            sel_periph_o,
  output logic            sel_default_o,
  output int unsigned     default_hits_o
);
  localparam logic [AW-1:0] REGION_LIMIT = AW'(16);

  logic in_region;
  assign in_region = (m_adr_i < REGION_LIMIT);

  // Select lines. Exactly one may be asserted, and when HAS_DEFAULT is 0
  // an unmapped access selects NEITHER — which is the whole point of the
  // silent configuration.
  assign sel_periph_o  = m_cyc_i && in_region;
  assign sel_default_o = m_cyc_i && !in_region && HAS_DEFAULT;

  // Peripheral port: presented only when the peripheral is selected, so a
  // slave never sees a transfer that was not addressed to it.
  assign p_cyc_o = sel_periph_o;
  assign p_stb_o = sel_periph_o && m_stb_i;
  assign p_we_o  = m_we_i;
  assign p_adr_o = m_adr_i[3:0];
  assign p_dat_o = m_dat_i;
  assign p_sel_o = m_sel_i;

  // Default responder port.
  logic d_ack, d_err; logic [DW-1:0] d_dat;
  wb_default_err_slave #(.DW(DW)) u_def (
    .clk_i(clk_i), .rst_i(rst_i),
    .cyc_i(sel_default_o), .stb_i(sel_default_o && m_stb_i),
    .dat_o(d_dat), .ack_o(d_ack), .err_o(d_err), .hits_o(default_hits_o));

  // Return path. An unselected source contributes nothing, so RULE 3.45
  // is preserved end to end: at most one class reaches the master.
  always_comb begin
    m_ack_o = 1'b0;
    m_err_o = 1'b0;
    m_dat_o = '0;
    if (sel_periph_o) begin
      m_ack_o = p_ack_i;
      m_err_o = p_err_i;
      m_dat_o = p_dat_i;
    end else if (sel_default_o) begin
      m_ack_o = d_ack;
      m_err_o = d_err;
      m_dat_o = d_dat;
    end
    // else: nothing selected, nothing returned, transfer stays outstanding.
  end
endmodule

Reading the pair

The fabric's job is three lines of decode and a return mux. in_region decides; sel_periph_o and sel_default_o are its two consequences; the return path forwards whichever selected source answered.

HAS_DEFAULT is the architectural switch, and both settings produce a conformant system. At 1 an unmapped access fails; at 0 it hangs. The same RTL, the same master, the same peripheral — and Section 6 runs both.

The peripheral never sees an unselected transfer. p_cyc_o is sel_periph_o, so a slave outside the region is not merely ignored, it is not presented to. That is why it cannot report an unmapped access: it has no evidence one occurred.

RULE 3.45 is preserved end to end by the mux structure. An unselected source contributes nothing to m_ack_o / m_err_o, so at most one class reaches the master however many targets exist. A fabric that ORed all slaves' terminations together unconditionally would violate exclusivity the moment two decodes overlapped — which is a real decoder bug and Module 12's to explore.

The default responder answers immediately and that is not an accident. It has no work to do, so it terminates in the presenting clock — a combinational path from STB_I to ERR_O, which PERMISSION 3.30 explicitly allows. Section 6 measures the latency difference this produces, and it turns out to be usable evidence.

Its DAT_O is 0xE220DEF, a defined value chosen to be recognisable rather than plausible. RULE 3.65 qualifies DAT_O() with the termination, so driving something is required in the sense that the signal must be in a defined state; what it should be is not specified, and a client must not consume it.

hits_o is instrumentation, not interface. It counts accesses that reached the responder, which is the single most useful diagnostic a fabric can expose — a non-zero count is a software address bug, immediately, and Chapter 10.5 builds on it.

4. Waveform — Two Failures, Different Evidence

Same verdict, different source

9 cycles
Nine clock cycles comparing two failing reads. The first access to word seven asserts cycle and strobe at cycles two and three, with the peripheral select line asserted for both, and its error input rises at cycle three after one wait clock. The second access to word one hundred asserts cycle and strobe at cycle two only, with the default responder select line asserted instead, and its error input is already asserted at cycle two. Both report a client error, the first at cycle four and the second at cycle three.different select lines alreadydifferent select linesalreadyperipheral errors after its waitperipheral errors after itswaitCLK_IL: CYC+STBL: sel periphL: ERR_IU: CYC+STBU: sel defltU: ERR_It0t1t2t3t4t5t6t7t8
Figure 1 — a read of word 7 (local invalid offset) and a read of word 100 (unmapped), started on the same clock. Both fail. Traced from the simulation in Section 6.

Look at cycle 2 first. Both accesses are presented. They are already distinguishablesel periph is asserted for one and sel deflt for the other. The decode happened before either target did anything.

The upper access takes two clocks. The peripheral is selected, inserts its one wait state, and asserts ERR_I at cycle 3. Its error costs exactly what a successful access costs, because the same latency counter gates both.

The lower access takes one. The default responder has nothing to do and terminates in the presenting clock. The unmapped access fails faster than the mapped one.

Both produce a client error, and at the client the two are indistinguishable. Same class, same contract, same err bit. Everything that separates them is inside the fabric — which is the practical case for exposing select lines and a responder hit count.

5. Simulation — SIM D, E and F

SIM D and E share one run, because the point is the comparison: three accesses through the same fabric, differing only in address.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === SIM D/E - local invalid offset vs unmapped address ===
    fabric maps words 0..15 to the peripheral; a default responder
    answers everything else.

    access                      periph  default  ok  err  clks  data
    word 4    mapped, legal       1       0      1    0      3    0x57421001
    word 7    local invalid       1       0      0    1      3    0x57421001
    word 100  unmapped            0       1      0    1      2    0x57421001

    default responder hits      1

Read the periph and default columns. Word 4 and word 7 both selected the peripheral; word 100 selected the default responder. The decode is the first piece of evidence and it is available before any target responds.

Read the clks column, which is the second. The legal read and the local-invalid read both took 3 clocks. The unmapped access took 2.

That difference is not arbitrary and it generalises. The peripheral's error costs exactly what its success costs, because both are gated on the same latency counter. A default responder has no work to do, so it answers immediately. An unmapped access failing faster than a mapped one is the normal shape of such a system, and it is usable evidence.

Read what is identical. Word 7 and word 100 produce the same client verdict: ok = 0, err = 1. At the client contract there is nothing to tell them apart — same class, same bit, same report.

And the data column is the same value three times, including on both failures: 0x57421001, the ID captured by the first successful read. The master did not capture on either error, so the register still holds what it held. This is Chapter 10.1's stale-value point, now visible across two different error sources.

default responder hits = 1 — one access reached it, out of three. That counter is the cheapest address-bug detector a fabric can carry, because a non-zero value means software addressed something that does not exist.

SIM F — the same unmapped address, with HAS_DEFAULT = 0.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === SIM F - unmapped address, NO default responder ===
    after 40 clocks of observation:
      master still busy          1
      still presenting           1
      peripheral selected        0
      default responder selected 0
      any termination seen       0
      client completions         0

Forty clocks of observation and nothing happened. The master is still busy, still presenting, and has reported nothing. No select line is asserted, so no target has the transfer — and none ever will.

The observation window is a testbench bound, not a recovery mechanism. Nothing in this system would have ended the transfer at clock 41, or 41,000. The simulation stops watching; the hang does not stop.

Every component here is conformant. The master holds its request as RULE 3.60 requires. The peripheral is not presented to and correctly says nothing. The fabric routes exactly what it was told to route. There is no violation anywhere, and the system is dead.

Which is the sharpest available statement of this module's premise. Chapter 9.5 showed that a slave may insert any number of wait states, so "still waiting" never expires. Here nothing is even waiting on anything — and the bus cannot tell the difference. At clock 40 this trace and a legitimately slow peripheral's are the same trace.

What would resolve it is not protocol but policy, and there are exactly two mechanisms. A default responder answers at the address — this chapter's. A watchdog answers at the masterChapter 10.4's. The specification recommends the second; both are systems decisions.

6. Failure Modes and Discriminating Evidence

Symptom: an access fails and nobody can say which component refused it.

Candidate causes. Peripheral-local error, or unmapped address.

Discriminating evidence. The select lines. If a peripheral select was asserted, the peripheral answered and the offset or the operation was the problem. If the default responder's select was asserted, no peripheral was ever addressed and the fault is in the address, not the register.

Second-order evidence. Latency. A peripheral error costs what that peripheral's success costs; a default responder answers immediately. Measured here: 3 clocks against 2.

Symptom: a system hangs on what should be a simple register access.

Candidate causes. Unmapped address with no default responder, or a genuinely stuck target.

Discriminating evidence. Is any select line asserted? None asserted means the address reached nothing — a decode or software address bug, and the peripheral is entirely innocent. One asserted means the target has the transfer, and Chapter 9.5's question applies: is its latency counter progressing?

Why this ordering matters: the natural instinct is to look inside the peripheral, and in the unmapped case the peripheral never saw anything.

Symptom: errors appear in a system that previously worked, after a memory-map change.

Candidate causes. Software addressing a region the fabric no longer routes.

Discriminating evidence. The default responder's hit count. Non-zero means addresses are arriving that nothing owns. The count alone localises it to the address, without any peripheral-side investigation.

Symptom: a peripheral errors on an access that should be legal.

Candidate causes. The offset arriving at the peripheral is not the offset software issued — a decode width or alignment problem.

Discriminating evidence. Compare ADR_O at the master against the offset presented at the peripheral. The fabric truncates a wide address to the peripheral's local width, and a mismatch between what software meant and what arrived is a fabric bug wearing a peripheral disguise.

Scope note: address translation in general is Module 12's.

7. Verification

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Properties for the fabric. Every one of these is LOCAL SYSTEM POLICY
// except the exclusivity check, which is the specification's obligation
// preserved across a routing element.
//
// 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 Section 5 come from procedural checks, which Icarus does run.
// ─────────────────────────────────────────────────────────────────────────
module wb_fabric_props #(
  parameter bit HAS_DEFAULT = 1'b1
) (
  input logic clk_i, rst_i,
  input logic m_cyc_i, m_stb_i,
  input logic m_ack_i, m_err_i,
  input logic sel_periph_i, sel_default_i,
  input logic p_cyc_i, p_stb_i
);
  default clocking cb @(posedge clk_i); endclocking
  default disable iff (rst_i);

  // F1 — SPECIFICATION (RULE 3.45), preserved through the fabric. However
  //      many targets exist, at most one class reaches the master. A
  //      decoder with overlapping regions breaks this.
  F1_one_class_upstream: assert property ( !(m_ack_i && m_err_i) );

  // F2 — LOCAL POLICY. The two select lines are mutually exclusive: an
  //      access is routed to a peripheral or to the default responder,
  //      never both.
  F2_selects_exclusive: assert property ( !(sel_periph_i && sel_default_i) );

  // F3 — LOCAL POLICY. A peripheral is never presented a transfer that was
  //      not routed to it. This is what makes "the peripheral cannot report
  //      an unmapped access" true by construction rather than by custom.
  F3_no_unrouted_presentation: assert property ( p_stb_i |-> sel_periph_i );

  // F4 — LOCAL POLICY, and only when a default responder exists. Every
  //      presented transfer selects something, so none can be orphaned.
  //      With HAS_DEFAULT = 0 this property is deliberately FALSE, and the
  //      configuration it fails in is the one SIM F measures.
  generate if (HAS_DEFAULT) begin : g_bounded
    F4_always_routed: assert property (
      (m_cyc_i && m_stb_i) |-> (sel_periph_i || sel_default_i)
    );
  end endgenerate

  // F5 — LOCAL POLICY. A termination reaching the master came from a
  //      selected source. A fabric that ORed unselected slaves' outputs
  //      would fail this before it failed F1.
  F5_termination_has_source: assert property (
    (m_ack_i || m_err_i) |-> (sel_periph_i || sel_default_i)
  );
endmodule

F4 is the interesting one because it is conditional on the architecture. With a default responder it holds; without one it is false, and the configuration in which it fails is a legal Wishbone system. That is unusual enough to be worth stating: a property that a conformant design deliberately violates is a property about a design choice, not about the protocol.

F1 is the specification's, and putting it upstream of the fabric matters. RULE 3.45 binds each slave, but a routing element can construct a violation out of two individually-conformant slaves by selecting both. The property belongs where the classes are combined.

F3 is what makes the ownership argument structural. A peripheral cannot report an unmapped access because it is never presented one — and F3 is the assertion that says so. Without it, "the peripheral never sees it" is a claim about this implementation rather than a checked invariant.

8. Common Mistakes

"An unmapped Wishbone address always produces an error."

Wrong mental model: the protocol defines what happens to an address nothing owns.

What is true: it does not. No rule requires an unmapped access to fail and none requires a default responder to exist. The closest the specification comes is RECOMMENDATION 3.10, which advises designing INTERCON to prevent deadlock and suggests a watchdog as one solution.

Concrete bug: assuming an error will arrive, and shipping software with no timeout on a system whose fabric is silent.

Observable evidence: SIM F — 40 clocks, no select, no termination, no completion, nothing non-conformant.

Correct model: deterministic failure is a system feature somebody built. Check whether yours has one.

"The peripheral should report the unmapped access."

Wrong mental model: the slave is the thing that knows about addresses.

What is true: the peripheral never sees it. The decoder did not select it, so STB_I was never asserted at its port. It has no evidence the access happened.

Concrete bug: looking inside a peripheral for the cause of an error it did not generate — the most common wasted hour in this class of failure.

Observable evidence: sel_periph = 0 for the failing access.

Correct model: the detector reports. The decoder knows about the map; the peripheral knows about its registers.

"A default responder hides bugs."

Wrong mental model: converting a hang into an error makes a problem quieter.

What is true: it converts an unlocalised failure into a localised one. A hang surfaces far from its cause and takes the system with it; an error surfaces at the access, with the address still available. The hit counter names the problem directly.

Where the concern is legitimate: a system that generates errors and does not log them. That is a software gap, and it is worth fixing rather than using as an argument for hanging instead.

Correct model: the responder is not the policy — the responder plus what software does with the error is the policy.

"A local invalid offset and an unmapped address are the same kind of failure."

Wrong mental model: both are "bad address", so both are one bug class.

What is true: they are detected by different components, reported by different components, and have different fixes. Measured, they even have different latencies — 3 clocks against 2 in this system.

Concrete bug: a debug procedure that treats every ERR identically and therefore starts in the wrong place half the time.

Observable evidence: the select lines, which differ from the presenting clock onwards.

Correct model: error provenance is a first-class question, and Chapter 10.5 is about answering it systematically.

9. Interview Reasoning

Yes, and in a system with no default responder and no watchdog it will — with nothing anywhere behaving incorrectly.

What happens mechanically. The decoder finds no region owning the address, so it asserts no select line. No peripheral is presented the transfer. Nothing generates a termination because nothing has the transfer. The master holds CYC_O and STB_O as RULE 3.60 requires and waits.

I measured exactly this — forty clocks of observation with no select line asserted, no termination, and the master still busy. The observation window is a testbench bound, not a recovery mechanism. Nothing in the system would have ended it at clock 41 or 41,000.

And every component is conformant. That is the part worth emphasising: there is no violation to find. The master is doing precisely what the specification requires, which makes it look like the stuck component when it is the one behaving correctly.

What prevents it is system policy, and there are two mechanisms. A default responder — a target selected when nothing else is, which terminates with ERR. Or a watchdog in the interconnect, which is what RECOMMENDATION 3.10 suggests: design INTERCON to prevent deadlock, one solution being a watchdog monitoring the master's STB_O.

Note what that recommendation is. A recommendation, about interconnect design, aimed at deadlock. It does not say unmapped accesses must error, and a system without either mechanism is not non-conformant — it is just fragile.

So the answer I would give in a review is: yes it can hang, the protocol will not save you, and whether your system fails cleanly is a question about your fabric, which somebody needs to have decided on purpose.

10. Understanding Check

11. What's Next

Error ownership is now concrete: the peripheral answers for its own registers, the decoder answers for addresses nothing owns, and each is distinguishable afterwards by select line and by latency.

One case was measured and deliberately left unresolved. SIM F's transfer is still outstanding, and nothing in the system will ever end it. A default responder fixes the case where the address is wrong — it does nothing for a target that was correctly selected and has stopped answering.

If a selected target never responds, when does "still waiting" become "failure" — and who decides?

Chapter 10.4 — Timeout Handling builds the watchdog, defines its parameter exactly, and measures the boundary edge and the late response that arrives after the system has given up. 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.