Wishbone · Module 6
Address Phase
Classic has one handshake, not an address channel. The address names a device and a register inside it, exists in three representations, and must stay coherent for the whole transfer.
Chapter 6.1 traced the read path and named the address as its first payload. That payload does two jobs at once, and the word "phase" invites an assumption from other protocols that is wrong here.
When does ADR_O identify the read target, and how long must that information stay coherent?
1. One Address, Two Jobs
A single value on ADR_O answers two different questions, resolved by two different pieces of logic.
Which device? The upper address bits select one slave. That decision belongs to the interconnect, and Chapter 3.5 built the general form.
Which register inside it? The lower bits become a local offset the slave indexes with. The slave knows nothing about where it sits in the system map.
The split is a system decision, not a protocol one. Wishbone defines neither the address map nor the decoding strategy — the specification's scope note leaves interconnect topology and address map to the integrator. Module 12 owns address decoding as a full subject; this chapter needs only enough to follow a read.
Why the slave is deliberately ignorant. A peripheral that knew its own base address could not be instantiated twice, or relocated, without editing its RTL. Giving it only a local offset is what makes it portable IP — which is the entire purpose of the Wishbone specification.
2. The Three Address Representations
A single read involves the same location expressed three ways, and confusing any two is a distinct bug.
| Representation | Example (ID) | Lives in | Width |
|---|---|---|---|
| Byte offset | 0x10 | datasheets, drivers, software | byte-granular |
| Global word address | 0x0000_0004 | ADR_O on the bus | AW = 30 |
| Local word offset | 0x4 | inside the slave | OFF_AW = 3 |
Byte → global is a right shift by two on a 32-bit port, plus the peripheral's base. Chapter 4.3 established why: the address array is ADR_O(n..2) and the two byte-offset bits are not on the bus at all.
Global → local is the decode of Figure 1.
All three are "the address of ID", and a debugging session that does not say which representation it is looking at will chase the wrong stage. Chapter 6.6 makes naming the representation an explicit step.
3. How Long the Address Must Stay Coherent
RULE 3.60 — "MASTER interfaces MUST qualify the following signals with [STB_O]: [ADR_O], [DAT_O()], [SEL_O()], [WE_O], and [TAGN_O]."
Qualified by STB_O means meaningful for as long as the strobe is asserted. Across a multi-cycle read that is an obligation to hold the value still, and Chapter 5.5 measured a master violating it for three of four cycles while reporting success.
Three consequences specific to reads.
A moving address redirects an outstanding read. The slave is still working; its ADR_I changes underneath it. Whether it serves the old or the new register depends on whether its decode is registered or combinational — and both slaves are conformant, because RULE 3.60 forbids the master from creating the situation at all.
No slave can defend against it. PERMISSION 3.10's slave is purely combinational with no storage. It cannot latch an address it was never told was new.
The interconnect cannot defend against it either. A decode that follows a changing address changes the slave select mid-transfer, so the strobe can move from one slave to another while a response is in flight — and Chapter 6.3 shows what that does to the return path.
4. RTL — The Decode
// ─────────────────────────────────────────────────────────────────────────
// wb_read_decode — the interconnect's address stage for the running system.
//
// PURPOSE. Split one global word address into a one-hot slave select and a
// local offset, and gate each slave's STB with its own select line.
//
// This is stage 3 of Chapter 6.1's Figure 1. It is deliberately small:
// Module 12 owns address decoding properly, and everything here exists only
// to make a read reach the right register.
//
// MAP (word addresses; byte addresses are 4x these):
// slave 0 REGS base 0x0000_0000 8 words (the running peripheral)
// slave 1 SCRATCH base 0x0000_0008 8 words (a second target, so that
// "wrong slave" is possible)
// anything else -> no select, and the default responder errors.
//
// Reset: none required — this block is purely combinational.
// ─────────────────────────────────────────────────────────────────────────
module wb_read_decode #(
parameter int unsigned AW = 30, // global word address width
parameter int unsigned OFF_AW = 3, // local word offset width
parameter int unsigned NSLV = 2
) (
// from the master
input logic [AW-1:0] adr_i,
input logic cyc_i,
input logic stb_i,
// to the slaves
output logic [NSLV-1:0] sel_slave_o, // ONE-HOT, or all-zero
output logic [NSLV-1:0] stb_slave_o, // per-slave strobe
output logic [OFF_AW-1:0] off_o, // local offset (shared)
output logic unmapped_o // no slave claims this address
);
// Each region is 2**OFF_AW words, so the region index is simply the
// address with the offset bits removed. Keeping the regions uniform and
// power-of-two sized makes the decode a comparison rather than a range
// check — an EDUCATIONAL SIMPLIFICATION, not a Wishbone requirement.
localparam int unsigned REGION_AW = AW - OFF_AW;
logic [REGION_AW-1:0] region;
assign region = adr_i[AW-1:OFF_AW];
// ── LOCAL OFFSET ──────────────────────────────────────────────────────
// The low bits pass through untouched. Every slave sees the same offset
// value; only the gated strobe decides which one acts on it.
assign off_o = adr_i[OFF_AW-1:0];
// ── SLAVE SELECT ──────────────────────────────────────────────────────
// One-hot by construction: `region` takes exactly one value, so at most
// one comparison can be true. A decoder built from overlapping range
// checks can produce two selects at once, and Section 7 gives the
// evidence that identifies that failure.
always_comb begin
sel_slave_o = '0;
unique case (region)
REGION_AW'(0): sel_slave_o[0] = 1'b1; // REGS words 0..7
REGION_AW'(1): sel_slave_o[1] = 1'b1; // SCRATCH words 8..15
default: sel_slave_o = '0; // unmapped
endcase
end
assign unmapped_o = (sel_slave_o == '0);
// ── PER-SLAVE STROBE ──────────────────────────────────────────────────
// RULE 3.30 forbids a slave from responding while CYC_I is negated, and
// RULE 3.35 requires terminations to come from the AND of CYC_I and
// STB_I. Gating the strobe with the select is what makes exactly one
// slave see a qualified transfer.
//
// NOTE that CYC is BROADCAST to every slave (Chapter 3.5) while STB is
// DECODED. That asymmetry is deliberate: CYC says a cycle is in
// progress, STB says THIS transfer is for you.
for (genvar i = 0; i < NSLV; i++) begin : g_stb
assign stb_slave_o[i] = stb_i & cyc_i & sel_slave_o[i];
end
endmodule// ─────────────────────────────────────────────────────────────────────────
// wb_addr_walk_master — THE ADDRESS-STABILITY BUG, isolated.
//
// NOT A REFERENCE DESIGN. Identical to Chapter 6.1's wb_read_master except
// that adr_o is driven from a counter that advances every cycle the read is
// outstanding, instead of from a value latched once at acceptance.
//
// Against a zero-wait-state slave it is indistinguishable from a correct
// master: the transfer completes in the cycle it is presented, so the
// counter never gets a chance to move. Introduce ONE wait state and it
// reads a different register from the one that was requested.
// ─────────────────────────────────────────────────────────────────────────
module wb_addr_walk_master #(
parameter int unsigned AW = 30,
parameter int unsigned DW = 32
) (
input logic clk_i,
input logic rst_i,
input logic req_i,
input logic [AW-1:0] req_adr_i,
input logic [DW/8-1:0] req_sel_i,
output logic acc_o,
output logic busy_o,
output logic done_o,
output logic [DW-1:0] rdat_o,
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
);
logic active_q;
logic [AW-1:0] adr_q;
logic [DW/8-1:0] sel_q;
assign acc_o = req_i & ~active_q;
assign busy_o = active_q;
assign cyc_o = active_q;
assign stb_o = active_q;
assign we_o = 1'b0;
assign dat_o = '0;
assign sel_o = sel_q;
// ── THE BUG ───────────────────────────────────────────────────────────
// adr_o comes from a register that is INCREMENTED while waiting. RULE
// 3.60 requires ADR_O to be qualified by STB_O — meaningful for the
// strobe's whole duration — and this violates it from the second cycle
// of any waited read onward.
assign adr_o = adr_q;
always_ff @(posedge clk_i) begin
if (rst_i) begin
active_q <= 1'b0;
adr_q <= '0;
sel_q <= '0;
done_o <= 1'b0;
rdat_o <= '0;
end else begin
done_o <= 1'b0;
if (acc_o) begin
active_q <= 1'b1;
adr_q <= req_adr_i;
sel_q <= req_sel_i;
end else if (active_q) begin
if (ack_i || err_i || rty_i) begin
active_q <= 1'b0;
done_o <= 1'b1;
if (ack_i) rdat_o <= dat_i;
end else begin
adr_q <= adr_q + AW'(1); // <-- walks while waiting
end
end
end
end
endmoduleReading the pair
Purpose. The decoder turns a global address into a selection and an offset; the walking master shows what happens when the address it decodes will not hold still.
Interface. The decoder is purely combinational, taking the master's address and qualifiers and producing per-slave strobes. The walking master presents Chapter 6.1's client contract exactly.
State. Decoder: none. Walking master: the outstanding flag and an address register that is rewritten while waiting — the single line that constitutes the bug.
Combinational logic. Decoder: region extraction, the one-hot select, the offset pass-through, and the per-slave strobe gating.
Sequential logic. Decoder: none, so no reset is required and none is present. That is worth noting explicitly, because a reviewer checking RULE 3.20 compliance should confirm a block has no state rather than look for a missing reset.
Read start. The decode is continuous — it produces a select whenever an address is present. What makes the selection meaningful is the gating with cyc_i & stb_i, so an idle bus selects nobody in any way that matters.
Address. off_o is driven to every slave unconditionally; only stb_slave_o differs between them. That is cheaper than routing per-slave address buses and is the standard shape.
Waiting. The decoder has no notion of waiting — it is a function of its inputs. If those inputs move, its outputs move, which is precisely why the master's stability obligation matters upstream of it.
Reset. Decoder: none needed. Walking master: synchronous active-high; active_q <= 0 negates both qualifiers per RULE 3.20.
Failure modes. Section 7.
Simplifications. Uniform power-of-two regions, two slaves, no default responder inside the decoder — unmapped_o is exported so a testbench or a wrapper can supply one. Chapter 3.5 discussed why a default responder matters; Module 12 owns real decoding.
5. Waveform — The Address That Walked
Address instability redirects an outstanding read
7 cyclesCycle 2 is the violation. STB_O is asserted, the read is outstanding, and ADR_O changes. RULE 3.60 qualifies the address with the strobe precisely so a slave can rely on it for the strobe's whole duration.
The two masters diverge in what they receive. The correct one is served word 4 — ID, 0x57420601. The walking one is served word 5, which the running peripheral does not implement, so it gets zero and an error. In a peripheral with a denser map it would have received a plausible wrong register instead, which is far harder to notice.
Against a zero-wait slave both traces are identical. The transfer would complete in cycle 1 and the counter would never advance. That is what makes this bug latency-dependent and what makes a wait-state configuration mandatory in a master's unit testbench.
6. Simulation — Address Stability, Measured
Both masters read word 4 (ID) from the running peripheral behind a slave inserting two wait states, with the client advancing its own request input to a different address immediately after acceptance.
=== SIMULATION B - address stability (WAITS=2) ===
correct walking
cycles the read was presented 3 3
distinct ADR_O values on the bus 1 3
ADR_O at the termination edge 0x4 0x6
cycles ADR_O != requested (0x4) 0 2
value captured 0x57420601 0x00000000
status OK ERRThe correct master presented exactly one address value across all three cycles of the presented transfer, and received ID.
The walking master presented three, ending on word 6 — two words past the request. It received an error, because word 6 is unmapped in the running peripheral.
Note that the client changing its own inputs affected neither master. Both latch at acceptance; the walking master's bug is that it rewrites its latched copy afterwards. That distinction matters for diagnosis: an unlatched master (Chapter 5.5) follows the client, while this one diverges from both the client and the request. The distinct ADR_O values row separates them.
7. Failure Modes and Discriminating Evidence
Symptom: the read returns a different register's value than requested.
Candidate causes. Four stages can produce this, and they are separable in order.
Discriminating evidence. Check each representation in turn:
| Check | If wrong, the fault is |
|---|---|
ADR_O vs the intended word address | the master, or a byte/word conversion in software |
ADR_O is 4× too large | byte offset used as a word address — conclusive |
decoded sel_slave | the decoder's region comparison |
off_o at the slave | the offset slice — an off-by-one or a width error |
| the slave's read-mux case | the slave (Chapter 6.3) |
The 4× signature is the one to look for first, because it is unambiguous and by far the commonest. A decoder bug shows the correct address on the bus with the wrong slave selected; a byte/word bug shows a visibly wrong address.
Property. P1 in Section 8.
Symptom: the read works at zero wait states and returns the wrong register when latency is added.
Candidate causes. The master's address does not hold still — either rewritten while waiting, or driven from an unlatched client input.
Discriminating evidence. Watch ADR_O across the whole strobe assertion. Any change before termination is a RULE 3.60 violation. Then separate the two causes: if the bus address tracks the client's input it is an unlatched master (Chapter 5.5); if it diverges from both the client and the original request it is being rewritten internally.
Likely RTL location. The adr_o assignment, or the register feeding it.
Property. P1.
Symptom: two slaves respond to the same read.
Candidate causes. A decoder producing more than one select — typically built from overlapping range comparisons rather than a unique case on a region index.
Discriminating evidence. Probe every slave's STB_I in the same cycle. More than one asserted is conclusive, and the resulting merged read data and doubled acknowledge will otherwise look like a baffling slave bug.
Likely RTL location. The select generation.
Property. P2.
Symptom: an address in no slave's range hangs the bus.
Candidate causes. No slave selected and no default responder, so nothing terminates.
Discriminating evidence. unmapped_o asserted with the strobe held and no termination anywhere. Chapter 5.1 §5's probe sequence reaches this at P2 — the strobe arrives at no slave.
Likely RTL location. The interconnect, not any slave. RECOMMENDATION 3.10 suggests a watchdog in the INTERCON precisely because this failure is otherwise silent.
Symptom: the correct slave is selected but indexes the wrong register.
Candidate causes. The offset slice is too narrow or too wide, so the local offset carries region bits or drops address bits.
Discriminating evidence. Compare off_o against the low bits of ADR_O. A mismatch localises to the slice; a match moves the search into the slave's read multiplexer.
8. Verification
// ─────────────────────────────────────────────────────────────────────────
// wb_addr_checker — address-phase properties.
//
// P1 is SPECIFICATION (RULE 3.60 read across a multi-cycle presentation)
// and is the property this chapter exists for. P2 and P3 are LOCAL DESIGN
// POLICY about this interconnect — the specification does not define
// address maps or decoding at all, so nothing here can be a Wishbone rule.
// ─────────────────────────────────────────────────────────────────────────
module wb_addr_checker #(
parameter int unsigned AW = 30,
parameter int unsigned OFF_AW = 3,
parameter int unsigned NSLV = 2
) (
input logic clk_i,
input logic rst_i,
input logic cyc_o,
input logic stb_o,
input logic [AW-1:0] adr_o,
input logic ack_i,
input logic err_i,
input logic rty_i,
input logic [NSLV-1:0] sel_slave, // white-box: decoder output
input logic [OFF_AW-1:0] off // white-box: local offset
);
default disable iff (rst_i);
logic terminated;
assign terminated = ack_i | err_i | rty_i;
// P1 — SPECIFICATION (RULE 3.60). The address is stable for as long as
// the transfer is presented. The end boundary is the TERMINATION:
// omitting `!terminated` would forbid a master from presenting a
// different read the cycle after one completes, which is legal and
// normal — the over-strong-property trap of Chapter 4.6 Section 10.
property p_address_stable_while_outstanding;
@(posedge clk_i) (cyc_o && stb_o && !terminated) |=> $stable(adr_o);
endproperty
a_address_stable_while_outstanding :
assert property (p_address_stable_while_outstanding)
else $error("RULE 3.60: ADR_O moved while the read was outstanding");
// P2 — LOCAL POLICY. The decoder selects at most one slave. $onehot0
// permits zero (an unmapped address) and forbids two.
property p_select_onehot0;
@(posedge clk_i) $onehot0(sel_slave);
endproperty
a_select_onehot0 : assert property (p_select_onehot0)
else $error("LOCAL: more than one slave selected");
// P3 — LOCAL POLICY. The local offset is exactly the low bits of the
// global address. Catches a mis-sized slice, which otherwise
// presents as a slave read-mux bug and sends the search one stage
// too far downstream.
property p_offset_matches_low_bits;
@(posedge clk_i) (cyc_o && stb_o) |-> (off == adr_o[OFF_AW-1:0]);
endproperty
a_offset_matches_low_bits : assert property (p_offset_matches_low_bits)
else $error("LOCAL: local offset does not match ADR_O low bits");
endmoduleP1 is a conformance property and needs no white-box access — a passive monitor on the bus catches both the walking master and an unlatched one. That is a pleasant contrast with Chapter 5.3's repeated-side-effect bug, which no bus-level property could see.
P2 and P3 need decoder internals, and they encode decisions the specification does not make. Wishbone defines no address map and no decoding strategy, so there is no rule number available for either — labelling them LOCAL POLICY is not a formality, it is the accurate description.
Tooling limitation. Icarus Verilog has no SVA support and cannot execute any of these. They are reviewed by inspection; the synthesizable RTL is elaborated and the address-stability failure is simulated in Section 6.
9. Common Mistakes
"The address is accepted, so the master can move on."
Wrong mental model: an AXI-style address channel with independent handshaking.
Concrete bug: a master that presents an address, drops STB_O, and waits for data.
Observable evidence: a one-cycle strobe followed by a permanent hang — the slave saw the request vanish.
Correct model: Classic has one handshake. RULE 3.60 qualifies the address with STB_O for the transfer's whole duration, and a combinational slave has nothing to remember it with.
"The offset from the datasheet is the address to put on the bus."
Wrong mental model: one address representation.
Concrete bug: byte offset 0x10 driven onto ADR_O, reading word 16.
Observable evidence: ADR_O exactly 4× the intended word address — unmistakable once you look for it.
Correct model: three representations, converted at defined points. Chapter 4.3 explains why the bus is word-addressed.
"A slave should check that the address is in its range."
Wrong mental model: the slave knows where it lives.
Concrete bug: a peripheral with its base address hard-coded, which cannot be instantiated twice or relocated.
Observable evidence: not a runtime failure — an integration failure, discovered when the map changes.
Correct model: the interconnect decides which slave; the slave decides which of its own registers. That separation is what makes a core portable IP, which is the specification's stated purpose.
10. Interview Reasoning
Three checks in order, each eliminating one stage, using the three address representations.
First: is ADR_O on the bus the word address I intended? If it is exactly four times too large, the answer is immediate — a byte offset was driven where a word address belongs. Chapter 4.3 established that a 32-bit port carries ADR_O(n..2), so the two byte-offset bits are not on the bus and the conversion is a right shift by two. This is the commonest of the three and the cheapest to rule out, which is why it goes first.
Second: with the right address on the bus, is the right slave selected? Probe the decoder's select lines, or each slave's STB_I. Wrong slave means the decoder's region comparison is wrong. Two slaves selected at once means the decode was built from overlapping range checks rather than a mutually-exclusive region index — and that produces merged read data and a doubled acknowledge, which looks like a baffling slave bug if you start at the slave.
Third: with the right slave selected, is the local offset right, and does the read mux agree with it? Compare off_o against the low bits of ADR_O. A mismatch is a mis-sized slice. A match sends the search into the slave's multiplexer — a missing or wrong case arm.
Why the order matters more than the checks. All three produce the same user-visible symptom: a successful read of the wrong value. Nothing about the returned data says which stage failed, so guessing costs a full debug cycle each time. Each check is one probe and eliminates one stage definitively.
The assertion that would have caught the middle one for free is a $onehot0 on the select vector — cheap, always true in a correct system, and it fires at the moment of the fault rather than when someone notices a wrong value downstream.
11. Understanding Check
12. What's Next
The address is settled: one value doing two jobs, three representations, and an obligation to stay coherent for the whole transfer.
The forward path has now delivered its question to the right register. What comes back is a different problem — the return path is driven by whichever slave was selected, merged with every other slave's, and meaningful for exactly one cycle.
How does read data travel from peripheral state back to the requester, and when is it trustworthy?
Chapter 6.3 — Data Return answers it. The full path is on the Wishbone curriculum index.
Continue learning
Related tutorials
- Related topic
ADR_O
A Wishbone address names a word, not a byte, and means nothing unless the strobe qualifies it: address width, decode, the master-offset split, and the stability obligation RULE 3.60 imposes.
- Related topic
Need for Standardized Interconnects
An address map answers where a register lives. It says nothing about which wires carry the request, when they are valid, how the target reports completion, or what happens on an error. Three peripherals with three private interfaces produce three adapters, three verification efforts and three ways to be wrong — which is the argument for standardising the interface rather than the map.
- Related topic
SoC Communication
Six chapters built the pieces; this one assembles them into a working fabric and traces three real accesses through it. The result works, and reading the nine unwritten rules a third party would need is what makes the case for a published protocol concrete rather than theoretical.
- Related topic
Transaction Lifecycle
One Wishbone transaction from a master's decision to act through the slave's termination and back to the caller: what is fixed by the protocol, what every implementation may vary, and what a real simulation of the assembled system shows at each step.
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.
