Wishbone · Module 12
Default Slave
One unmapped address through two systems differing in a single parameter: one ends in the clock it was presented, the other was still presenting forty clocks later.
Chapter 12.5 and Chapter 12.4 both ended with an access that no target claimed, answered by something that has not been built yet.
Nothing owns this address. What happens?
1. Two Architectures, One Difference
The decoder behaves identically in both. It reports sel = 000 and unmapped = 1 for an address no window contains, which is correct and is not the question.
The question is what is wired to that unmapped signal.
| no default responder | with a default responder | |
|---|---|---|
| decoder output | sel = 000, unmapped = 1 | sel = 000, unmapped = 1 |
| targets strobed | none | none |
| anything else strobed | nothing | the default responder |
| termination | never | ERR, combinationally |
| the master | still presenting | proceeds |
Only one row differs, and everything else follows from it.
The selection rule is the complement of the map:
dflt_cyc = cyc && unmapped
dflt_stb = stb && unmappedDerived from unmapped rather than from ~|sel — the two are equal, and Chapter 12.1's P2 asserts it, but taking it from the decoder keeps one source for the classification instead of two expressions that must agree.
And it is qualified by the strobe like every other target. A default responder that asserted ERR whenever the address was unmapped, regardless of whether a transfer was in progress, would be driving a termination outside a bus cycle — which RULE 3.35 forbids for exactly the same reason it forbids it of any slave.
2. RTL — The Default Responder
// ── Default responder: owns every address no real target claimed ────────
// LOCAL SoC POLICY, not Wishbone law. Wishbone requires a slave to answer
// every qualified strobe it receives (the STB_O description); it says
// nothing about who answers an address no slave decodes. Deciding that the
// interconnect itself answers, and answers with ERR, is the integrator's
// architectural choice. Chapter 12.6 measures the alternative.
module wb_default_slave #(
parameter int unsigned DW = 32
) (
input logic cyc_i,
input logic stb_i,
output logic [DW-1:0] dat_o,
output logic ack_o,
output logic err_o
);
assign ack_o = 1'b0;
assign err_o = cyc_i && stb_i;
// RULE 3.65 has the slave qualify DAT_O() with its termination. There is
// no data to return for an address that does not exist, and returning a
// recognisable constant is more useful in a trace than returning zero.
assign dat_o = cyc_i && stb_i ? DW'(32'hDEAD_0000) : '0;
endmoduleReading it
Nine lines, no state, and no address input. It does not need one — it has already been told, by the fact that it was strobed at all, that the address belongs to nobody. The decoder did the deciding.
ack_o is tied low and that is the load-bearing decision. An ERR is a refusal the master can act on; an ACK for an address that exists nowhere is indistinguishable from success, and it would convert every bad pointer in the system into a silent no-op. P13 in Section 8 forbids it.
dat_o returns a constant rather than zero. RULE 3.65 qualifies DAT_O() with the termination, so the master should not be reading it at all on an ERR. Returning 0xDEAD0000 costs nothing and makes a trace self-explaining: a value that appears in a log identifies its own source. Zero does not — zero is also what an uninitialised RAM word returns.
This is one policy of several. The alternatives are real and each has a context where it is right:
| policy | behaviour | where it fits |
|---|---|---|
ERR | refuse, visibly | almost everywhere; this SoC |
ACK with zero | pretend it worked | probing firmware that must not fault |
RTY | defer forever | nowhere — the condition never clears |
| nothing | hang | never on purpose |
The RTY row is worth stating explicitly. RTY means not now, try later (Chapter 11.1), and an address that does not exist will not start existing. A master honouring it retries until its budget is spent — turning an immediate, clear failure into a slow one. It is conformant and it is wrong.
3. Simulation — SIM H: Nothing Answers
One access to byte 0x5000_0000, which no window contains, into a system with GEN_DFLT = 0. The master presents and waits, as a master with no timeout does. The observation window is capped by the testbench at 40 clocks — that bound belongs to the experiment, not to the system.
=== SIM H - no default responder ===
one access to byte 0x50000000, which no target claims.
the master presents it and waits, as a master without a
timeout does. Observation is capped at 40 clocks.
sel vector 000
unmapped 1
targets strobed 0
wait clocks 40 (capped)
terminated no
ACK / ERR / RTY 0 / 0 / 0
the decoder was right: nothing owns this address. Nothing
was strobed, so nothing owed a response, so no response
came. The transfer is still open. Only the testbench's cap
ended this simulation - the system had no opinion.Reading it
Every line of that report describes correct behaviour, and the transfer never ends.
The decoder was right. sel = 000 and unmapped = 1: nothing owns 0x5000_0000, which is true. No target was strobed, which is the qualification rule from Chapter 12.4 working exactly as specified.
So no slave owes a response. The STB_O description obliges a slave to answer every assertion of STB_O — and not one slave saw an assertion. Zero acknowledgements, zero errors, zero retries, and zero rules broken.
Only the testbench's cap stopped the simulation. Remove it and the loop runs forever; the system has no opinion about when this should end because nothing in it is responsible for ending it.
4. Simulation — SIM I: The Same Address, One Parameter Changed
GEN_DFLT = 1 and nothing else. Same address, same decoder, same targets, same master.
=== SIM I - the same address, with a default responder ===
sel vector 000
unmapped 1
real targets strobed 0
default strobed 1
wait clocks 0
terminated ERR
DAT returned 0xdead0000
same decoder, same verdict, same empty sel vector. The one
difference is that something is wired to answer when the
vector is empty. The termination is combinational, so the
access ends in the clock it was presented - 0 wait clocks
instead of never ending at all.
architecture wait clocks terminated class
no default 40 (cap) no none
default responder 0 yes ERR
ERR here is THIS SoC's policy for an address nobody owns.
Wishbone requires a slave to answer a strobe it receives;
it does not say who answers for an address that reaches no
slave at all. That gap is the integrator's to close.Reading it
The first three lines are identical to SIM H. sel = 000, unmapped = 1, no real target strobed. The decoder's verdict did not change, because the decoder is not what changed.
The fourth line is the entire difference: default strobed 1. Something is wired to the complement of the map, and it received the transfer that no target claimed.
Zero wait clocks. The termination is combinational in the qualified strobe, so the access ends in the clock it was presented — the same cost as an acknowledged access to a fast peripheral. A default responder is not a recovery mechanism that runs after a delay; it is a participant in the transfer.
And the comparison table is the argument in two rows. Same address, same decoder, same verdict about ownership. 40 clocks and counting, versus 0 and done.
The last paragraph of the output is the honest caveat. ERR is this SoC's answer. Wishbone requires a slave to answer a strobe it receives; it does not say who answers for an address that reaches no slave — and the whole of this chapter sits in that gap.
5. The Two Systems Side by Side
Forty clocks of nothing, or one clock of ERR
8 cyclessel[2:0] is flat at zero across the whole figure in both systems. The decoder is not the variable. A and B receive the same verdict and do different things with it.
A: ERR_I never rises — not late, not eventually. There is nothing in system A whose job is to raise it.
System B is finished at cycle 2, which is where A's 40-clock observation window has not yet begun to look unusual.
6. What a Default Responder Is Not
It is not a peripheral. It has no window, no registers and no base address. It owns the complement of every window, which is most of a 32-bit space and cannot be written as a base and a size.
It is not a catch-all target that makes bad addresses harmless. It makes them visible. An unmapped access is still a bug in whatever produced the address — the default responder ensures it is reported at the point of failure instead of surfacing as a hang somewhere downstream.
It is not a timeout, and it does not replace one. A timeout (Chapter 10.4) bounds a transfer to a target that exists and is not answering. A default responder answers for a target that does not exist. Different causes, different evidence, different fixes — and a system wanting both hangs to be bounded and bad addresses to be diagnosed needs both mechanisms.
It is not a security boundary. An unmapped access being refused is a correctness property, not a protection one. Module 18 is where access control belongs, and it is a different mechanism with a different threat model.
7. Failure Modes and Discriminating Evidence
Symptom: an access hangs and the target looks slow.
Candidate causes. No default responder plus an unmapped address. A target that failed to terminate. A decode hole where a window was expected.
Discriminating evidence. The select vector. All-zero means no target was asked and no amount of waiting will produce an answer. One bit set with no termination is a genuine target fault, and the investigation moves inside that target. This single observation separates the two cases, and without it a watchdog can only report that something did not answer.
Symptom: a bad pointer produces no error and no effect.
Candidate causes. A default responder configured to ACK, or an unmapped access silently discarded.
Discriminating evidence. Whether the transfer terminated, and with what. An ACK with no state change anywhere means something answered for an address that owns nothing. That may be deliberate policy — probing firmware sometimes wants it — and RULE 2.15 requires it to be documented. What it must not be is an accident.
Symptom: unmapped accesses are retried repeatedly and then fail.
Candidate causes. A default responder answering RTY.
Discriminating evidence. The termination class on each attempt. Repeated RTY for a fixed address is a condition that cannot clear: the address will not become mapped. A master honouring it burns its whole retry budget (Chapter 11.2) to reach the failure it would have had immediately.
Symptom: a new peripheral is unreachable and its accesses return ERR.
Candidate causes. The window was never added to the map, so the default responder is answering for it.
Discriminating evidence. The select vector, again. All-zero means the map does not contain the peripheral — the peripheral is probably fine and the map is incomplete. One bit set with ERR means the target was reached and refused, which is Chapter 12.5's in-window hole.
8. Verification
// ─────────────────────────────────────────────────────────────────────────
// wb_default_props — the default responder's ownership and its policy.
// ─────────────────────────────────────────────────────────────────────────
module wb_default_props (
input logic clk_i,
input logic rst_i,
input logic cyc_i,
input logic stb_i,
input logic [2:0] sel_i,
input logic unmapped_i,
input logic dflt_stb_i,
input logic m_ack_i,
input logic m_err_i
);
default disable iff (rst_i);
// P11 — LOCAL ARCHITECTURE.
// The default responder and a real target are mutually exclusive owners.
property p_default_excludes_targets;
@(posedge clk_i) dflt_stb_i |-> (sel_i == 3'b000);
endproperty
a_default_excludes_targets: assert property (p_default_excludes_targets);
// P12 — LOCAL SoC POLICY. Not a Wishbone requirement.
// A presented unmapped access terminates, in the same clock, with ERR.
// Wishbone requires a SLAVE to answer a strobe it receives; it says
// nothing about an address that reaches no slave. This SoC's answer is
// ERR and it is a choice — another SoC could answer ACK with zero, and
// RULE 2.15 would require either choice to be documented.
property p_unmapped_errs;
@(posedge clk_i) (cyc_i && stb_i && unmapped_i) |-> (m_err_i && !m_ack_i);
endproperty
a_unmapped_errs: assert property (p_unmapped_errs);
// P13 — LOCAL ARCHITECTURE.
// The default responder never acknowledges. An ACK for an address that
// exists nowhere is the failure mode this property exists to forbid,
// because it is indistinguishable from success at the master.
property p_default_never_acks;
@(posedge clk_i) (dflt_stb_i && m_ack_i) |-> 1'b0;
endproperty
a_default_never_acks: assert property (p_default_never_acks);
endmoduleP12 is the chapter's policy written as a checkable statement, and it is labelled LOCAL for a reason. It says a presented unmapped access terminates with ERR in the same clock. That is false of SIM H's system, which is equally conformant, and it would be false of a system whose policy was ACK with zero.
A property this specific must carry its scope. Asserting P12 against a design whose documented policy is ACK would fail a correct system — and the temptation would then be to weaken the property rather than notice it was aimed at the wrong architecture.
P13 is the one worth keeping in every configuration. Whatever the policy, the default responder must not acknowledge, because an acknowledgement is indistinguishable from success. A system that has chosen ACK-with-zero has deliberately given that up, and should say so in the same place it documents the policy.
9. Common Mistakes
"An unmapped access should just wait — maybe something will claim it."
Wrong mental model: the address might become valid.
What is true: the map is fixed at elaboration. Nothing will claim it, ever. SIM H is that wait, and the only thing that ended it was the testbench.
"A default slave means a default peripheral."
Wrong mental model: it is a target that catches leftovers.
What is true: it has no window. It owns the complement of the map — most of the address space — which is not expressible as a base and a size. It is a property of the interconnect, not a device on it.
"A timeout handles this."
Wrong mental model: a hang is a hang.
What is true: a timeout bounds the damage and misdiagnoses the cause. It reports "the target did not respond" about an address with no target. Chapter 10.4's watchdog and this chapter's responder solve different problems, and a system that wants both properties needs both mechanisms.
"Returning ACK with zero is friendlier than ERR."
Wrong mental model: fewer faults is better.
What is true: it converts every bad pointer into a silent no-op. There are contexts where that is right — probe-the-hardware firmware that must not fault — but it is a deliberate trade of diagnosability for robustness, and RULE 2.15 requires it to be documented rather than discovered.
"RTY is the safe answer because the master can decide what to do."
Wrong mental model: deferring is neutral.
What is true: RTY asserts that the condition may clear, and this one cannot. A conformant master will re-issue until its budget is exhausted, reaching the same failure after N attempts instead of one — Chapter 11.2 measures what that costs.
10. Interview Reasoning
Wire something to the complement of the address map and let it terminate the transfer.
Why the hang happens. The decoder correctly selects nothing, so no slave is strobed, so no slave owes a response. Every component is behaving correctly — the STB_O description obliges a slave to answer strobes it receives, and none received one.
The mechanism. dflt_stb = stb && unmapped, and a responder that asserts ERR on that. Combinational, so it costs no extra clock. Measured: 0 wait clocks against a transfer that was still open at 40.
Why ERR and not ACK. An acknowledgement for an address that exists nowhere is indistinguishable from success, and would turn every bad pointer into a silent no-op.
The distinction worth volunteering: this is not a timeout. A timeout bounds a transfer to a target that exists and is not answering; this answers for a target that does not exist. A system that wants both needs both, and the select vector is what tells you which situation you are in.
11. Understanding Check
None of them. That is what makes the measurement worth publishing.
The decoder was correct. 0x5000_0000 is in no window, so sel = 000 and unmapped = 1 are the right answers.
The router was correct. No select bit was set, so no target received a strobe — the qualification rule from Chapter 12.4 working as specified.
Every target was correct. The STB_O description obliges a slave to answer every assertion of STB_O it receives. Not one of them received an assertion, so not one of them owed anything.
The gap is architectural, not behavioural. Nothing in the system was given the job of answering for an address outside the map, so nothing did. Adding a component with that job is the whole of SIM I.
12. What's Next
Every address in the space now has an owner: one of three targets, or the responder that owns everything else.
And "owner" has turned out to be coarser than "has hardware behind it". Three quarters of RAM's window, and 1022 words of each peripheral's, are reserved and empty.
What does a decoder owe to the space a map reserves and does not implement?
Chapter 12.7 — Sparse Address Spaces sweeps the whole map, separates the two kinds of refusal, and measures how much of a reserved space is actually there. The full path is on the Wishbone curriculum index.
Continue learning
Related tutorials
- Related topic
The ERR Signal
ACK and ERR are two classes of the same event: the transfer ended. Two structurally identical accesses, both terminating in two clocks, only one of which succeeded.
- Related topic
Error Responses
A master that folds ACK or ERR into success reports a failed write as successful over a byte-identical bus. A slave that asserts both classes at once is caught by a checker in one clock.
- Related topic
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.
- Related topic
CPU to Peripheral Communication
A CPU reaches hardware outside itself by reading and writing addressed locations, and a peripheral is hardware it cannot execute. Everything a driver does has to be expressed as a read or a write of a location the peripheral answers for — and once more than a couple of peripherals exist, wiring each one to the core separately stops scaling. That is the problem an on-chip bus is the answer to.
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.
