Wishbone · Module 24
Error Generation
ERR describes the request, RTY describes the slave — and B3 dictates neither response. Retrying a permanent fault cost 400 clocks for nothing; aborting a temporary one abandoned work that would have succeeded twenty clocks later.
Chapter 24.4 decided when a slave answers. This chapter decides what it answers when the answer is no — and Wishbone gives you two different ways to say it.
[ERR_O]describes a property of the REQUEST.[RTY_O]describes a property of the SLAVE.That rule is not in B3. It is this module's, and the rest of the chapter is the measurement that justifies it.
1. Two Signals, Two Refusals To Specify
B3 defines both and declines to say what to do about either:
PERMISSION 3.20 — "MASTER and SLAVE interfaces MAY be designed to support the
[ERR_I]and[ERR_O]signals. In these cases, the SLAVE asserts[ERR_O]to indicate that an error has occurred during the bus cycle. This specification does not dictate what the MASTER does in response to[ERR_I]."PERMISSION 3.25 — "MASTER and SLAVE interfaces MAY be designed to support the
[RTY_I]and[RTY_O]signals. In these cases, the SLAVE asserts[RTY_O]to indicate that the interface is busy, and that the bus cycle should be retried at a later time. This specification does not dictate what the MASTER will do in response to[RTY_I]."
Read them side by side and something asymmetric appears. [RTY_O] is given a meaning — busy, try again — and [ERR_O] is given only a name. Neither is given a required response.
And then B3 makes the documentation compulsory anyway:
RULE 2.15 item 4 — "If a SLAVE supports the optional
[ERR_O]signal, then the WISHBONE DATASHEET MUST describe the conditions under which the signal is generated." Item 5 says the same for[RTY_O].
Unconstrained behaviour, compulsory documentation. That combination is unusual and it is exactly right: B3 is specifying an interface, not a policy, and it knows the difference.
2. The Rule This Module Adopts
// [ERR_O] is generated when, and only when:
// - the offset is RESERVED (a hole inside the window)
// - the access is a WRITE to a READ-ONLY offset
// - the access is MISALIGNED for the register's width
// All three are PERMANENT properties of the request. Retrying an
// identical request produces an identical error.
//
// [RTY_O] is generated when, and only when:
// - the addressed resource is BUSY and the same request is
// expected to succeed later
// This is a TEMPORARY property of the slave, never of the request.Invert it and both failure modes are silent:
[ERR_O]for a busy resource turns a transient into a permanent failure that the master will not retry.[RTY_O]for a bad address turns a permanent failure into an infinite loop.
OBSERVATION 3.30 is B3 acknowledging that the slave is the party who knows:
"Internal SLAVE signals also determine what cycle termination signal is asserted and when it is asserted."
The priority is explicit, and it is the opposite of the one in wb_ack_gen:
// A PERMANENT fault outranks a TEMPORARY one. A request that can never
// succeed should not be told to try again - that is the RTY-for-a-bad-
// address infinite loop. This priority is a LOCAL POLICY and it is the
// opposite of wb_ack_gen's RTY-over-ERR ordering, which resolves a
// different question: that one asks which signal wins when both are
// wanted, this one asks which condition is wanted at all.3. Retrying A Permanent Fault
Four writes to a read-only register. The fault is a property of the request; it can never succeed.
ERR policy clocks ok retries aborts timeouts
abort 11 0 0 4 0
retry up to 3 47 0 12 4 0
retry forever 400 0 134 0 0 -> NOT ONE POLICY SUCCEEDED, because none could.
The abort policy learned that in 11 clocks.
The retry policy spent 47 clocks and 12 retries
re-discovering what the first attempt already
proved. RETRYING A PERMANENT FAULT IS PURE
COST - and B3 cannot tell you that, because it
does not know which faults are permanent.Eleven clocks against four hundred, for the identical outcome. And the retry-forever rig never finished at all — it exhausted a 400-clock budget having resolved nothing.
4. Aborting A Temporary One
The same two policies, against a resource that is busy for twenty clocks and then free:
rig clocks ok retries aborts unheard to
RTY + abort 11 0 0 4 0 0
RTY + retry up to 8 32 4 7 0 0 0 -> RETRY SUCCEEDED 4 TIMES, ABORT 0. This is
SIM H EXACTLY INVERTED. Same two policies, and
the one that was pure waste against a permanent
fault is the only one that works against a
temporary one.Neither policy is correct. The master cannot choose well because the master does not know which kind of fault it has. The slave does — and the choice between
[ERR_O]and[RTY_O]is how it tells anybody.
And a slave that chooses wrong:
ERR_FOR_BUSY + abort 11 0 0 4 0 0
-> ERR_FOR_BUSY completed 0 of 4. It answered a
TEMPORARY condition with a PERMANENT signal, and
the master correctly stopped trying. The
resource was free 20 clocks later and nobody
ever went back. NO RULE WAS BROKEN.The master behaved correctly and the work was abandoned anyway.
5. B3 Predicts The Deadlock
Both signals are optional. RULE 3.40 lists only [ACK_O] as mandatory for a slave. So a slave that supports [RTY_O] may be wired to a master that has no [RTY_I] pin — and B3 says what happens:
OBSERVATION 3.35 — "If the SLAVE supports the
[ERR_O]or[RTY_O]signals, but the MASTER does not support these signals, deadlock may occur."
Measured:
68 terminations were driven onto the bus that
this master has no pin to receive. The slave
answered. The master is deaf. The phase never
ends, and NOTHING IS VIOLATED.The slave answered sixty-eight times. RULE 3.35 satisfied, RULE 3.45 satisfied, RULE 3.50 satisfied. The deadlock is entirely inside the master, and from the bus the cycle looks answered.
6. The Correction: B3 Is Not Silent About Timeouts
Module 23 states, in four separate chapters, that "B3 specifies no timeout of any kind." Chapter 23.4 adds that a watchdog "belongs to the master" because "the slave has no signal with which to raise the alarm."
Both halves are wrong, and the text that corrects them was in the cached specification the whole time:
RECOMMENDATION 3.10 — "Design INTERCON modules to prevent deadlock conditions. One solution to this problem is to include a watchdog timer function that monitors the MASTER's
[STB_O]signal, and asserts[ERR_I]or[RTY_I]if the cycle exceeds some pre-defined time limit. INTERCON modules can also be designed to disconnect interfaces from the WISHBONE bus if they constantly generate bus errors and/or watchdog time-outs."
The accurate statement is narrower and more interesting:
B3 imposes no normative timeout — there is no MUST, no bound on latency, and no timeout signal anywhere in the interface. But it is not silent: it recommends a watchdog, it places that watchdog in the INTERCON rather than the master, and it names the signals the watchdog should assert. A hung cycle is a foreseen condition in B3, not an oversight. The specification simply declines to make handling it mandatory.
A RECOMMENDATION is not a RULE. But "B3 has no timeout" and "B3 does not require a timeout" are different sentences, and Module 23 published the first while meaning the second.
7. The Watchdog Works, Twice Fails, And Both Failures Are Structural
logic watching;
assign watching = ENABLED && cyc_i && stb_i;Where it works — a master deaf to [RTY_I] but with an [ERR_I] pin:
-> THE WATCHDOG RESCUED THE DEAF-TO-RTY RIG.
It fired 4 times, asserted [ERR_I], and the
master - which HAS an [ERR_I] pin - aborted 4
requests instead of hanging.Where it cannot — a master with neither pin:
-> AND IT COULD NOT RESCUE THE NEXT ONE. The same
watchdog fired 386 times at a master with
NEITHER pin. It resolved 0 of 4 requests and
burned its whole 400-clock budget.
READ WHAT RECOMMENDATION 3.10 ACTUALLY SAYS: the
watchdog "asserts [ERR_I] or [RTY_I]". THOSE ARE
THE OPTIONAL SIGNALS WHOSE ABSENCE CAUSES THE
DEADLOCK IN THE FIRST PLACE. B3's recommended
remedy is expressed in the same vocabulary as the
disease, so it cures every case except the one
OBSERVATION 3.35 actually describes.And where it is blind — a master that retries forever:
-> AND THE WATCHDOG NEVER SAW THE LIVELOCK AT ALL.
RTY_FOREVER + retry-forever made 134 retries in
400 clocks, resolved 0 requests, and tripped
the watchdog 0 times.
RECOMMENDATION 3.10 says to monitor the
MASTER's [STB_O]. Every retry NEGATES [STB_O]
and re-asserts it, so each attempt is a fresh,
short phase and the counter restarts. A
WATCHDOG ON [STB_O] CATCHES A HUNG PHASE AND IS
BLIND TO A LIVELOCKED MASTER.
Monitoring [CYC_O] instead would catch it - and
would false-trip on any legitimate long block
cycle, which is presumably why B3 named
[STB_O]. There is no free choice here.Three rigs, three outcomes, one watchdog. It is not broken in any of them.
[STB_O]measures one phase, which is the thing that can hang, and a livelocked master is not one long phase — it is many short correct ones.
A mistake worth recording
The first version of this watchdog also required that no termination be present before counting:
// The first version of this module also required `!answered` - it only
// counted while no termination was on the wire, reasoning that a cycle
// being answered is not stuck. THAT MADE IT BLIND TO THE EXACT CASE
// OBSERVATION 3.35 DESCRIBES: a slave asserting [RTY_O] at a master
// with no [RTY_I] pin IS being answered, continuously, and the master
// still never progresses. The deadlock is inside the master, and from
// the bus the cycle looks answered.The guard was reasonable and it deleted the module's entire purpose. B3 says to monitor [STB_O] and a time limit; it says nothing about terminations, and adding that condition made the watchdog agree with the bus that everything was fine.
The price of the correct version is that LIMIT must exceed the worst legitimate latency on the fabric — and B3 bounds no latency, so that number cannot be derived. It has to be chosen, and choosing it too low turns a slow slave into a bus error.
8. The Full Matrix
rig C1 C2 C3 C4 C5 C6 FUNC
correct 0 0 0 8 0 0 ok
DAT_ALWAYS 3.65 0 0 0 8 0 50 ok
SIDE_ON_STB 0 0 0 8 0 0 OVER-POPPED
IGNORE_SEL 0 0 0 8 0 0 WRONG BYTES
BUS_WINS 0 0 0 8 0 0 HW LOST
REG, correct 0 0 0 8 0 0 ok
NO_NEGATE 3.50 5 0 0 8 5 0 ok
TIED (LEGAL) 3.35 33 0 0 8 7 0 okThree rows are all zeros on every protocol checker and all three destroy something: a FIFO over-popped, three bytes overwritten, a hardware event erased. One row fires on two checkers and is legal. One column fires on every row by design, because RULE 3.25 constrains signals a slave never drives and the stimulus has to break it for any slave-gate defect to be reachable at all.
The diagonal is the least informative part of that table, which is the recurring result of this curriculum and the reason the off-diagonals are published.
9. The Datasheet, Which RULE 2.15 Makes Mandatory
| item | value |
|---|---|
4 [ERR_O] conditions | reserved offset; write to read-only; misaligned access |
5 [RTY_O] conditions | addressed resource busy — never a permanent condition |
| 7 port size | 32-bit |
| 8 granularity | 8-bit |
| 9 maximum operand size | 32-bit |
| 10 data ordering | LITTLE ENDIAN |
| 11 transfer sequence | UNDEFINED — SINGLE cycles only |
12 [CLK_I] constraints | none imposed by this core — see the note |
// NOTE ON ITEM 12. "None imposed" is true of the RTL and is NOT a
// statement that any frequency will work. With SCHEME=COMB there is a
// combinatorial path from [STB_I] to [ACK_O] which B3 s4.1 calls "the
// dominant timing factor" in a large SoC. NO SYNTHESIS TOOL WAS RUN ON
// THIS CORE, so item 12 records the absence of a constraint rather than
// the presence of a guarantee.Items 4 and 5 are the two rows an integrator actually needs, and they are exactly the two that B3 cannot supply.
10. What This Chapter Did Not Build
- No retry limit in the slave. A slave cannot count retries — each one is a fresh request and nothing distinguishes it. The limit lives in the master, and Chapter 12.6 owns the master-side view.
- No bus disconnection. RECOMMENDATION 3.10's second sentence suggests disconnecting an interface that persistently errors. That is an interconnect policy; Chapter 23.6 is where the fabric lives.
- No error classification on the wire.
[ERR_O]is one bit. A timeout and a bad address arrive identically, and B3 offers tags — RULE 3.70 requires every user-defined tag to be assigned a TAG TYPE — but this module defines none. - No synthesis. Every timing claim in Module 24 is a claim about clock counts.
Module 24 ends here. Five chapters built a register map, a read datapath with side effects, a write datapath with two writers, four termination schemes and a policy engine — and found that B3 quantifies its own central trade-off to the clock, that three of this module's worst defects are invisible to every protocol checker, and that a claim published four times in Module 23 was contradicted by a RECOMMENDATION nobody had read.
Module 25 turns to DMA: a master that generates its own traffic, descriptors, and the arbitration pressure that follows.
Continue learning
Related tutorials
- Related topic
RTY_I
A slave saying "not now" rather than "no". Unlike a wait state it releases the bus, which breaks a whole class of deadlock — and unlike an error it invites another attempt, which is what makes livelock possible.
- Related topic
Timeout Handling
Wishbone defines no timeout. A measured watchdog: exact parameter semantics, a boundary edge where the real answer wins, and a late response that terminates the wrong transfer unless the guard drains it.
- Related topic
Temporary Resource Unavailability
A full queue can be answered with wait states or with RTY. Measured against the same condition: 11 clocks of bus occupancy and one attempt, against 4 clocks and four attempts.
- Related topic
Starvation
A requester eligible at 63 arbitration opportunities and chosen at one, on a bus that never stopped transferring. Starvation is not deadlock, and a finite trace demonstrates a mechanism rather than proving an infinity.
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.
