Wishbone · Module 6
Read Cycle Flow
One Wishbone read followed through nine stages from a client request to a returned value: what each stage contributes, why the forward and return paths are asymmetric, and where a read that hangs actually stopped.
Module 5 taught the handshake as a timed contract — a cycle that frames, a strobe that presents, a termination that answers. Reads and writes were vehicles for it.
Module 6 makes one of them the subject.
What is the complete architectural path of a single Wishbone read?
1. The Nine Stages
A read passes through nine identifiable stages. Naming them now gives the rest of Module 6 — and every debugging section in it — a shared vocabulary.
| Stage | What it contributes | Owns it | Chapter |
|---|---|---|---|
| 1 Client request | a local intention: read this address | client | 5.5 |
| 2 Master presents | ADR_O, WE_O negated, CYC_O+STB_O | master | 6.2 |
| 3 Decode | global address → slave select + local offset | interconnect | 6.2 |
| 4 Slave indexes | local offset → which register | slave | 6.3 |
| 5 Read mux | register value → DAT_O, plus ACK_O | slave | 6.3, 6.4 |
| 6 Merge | one slave's response onto the return path | interconnect | 6.3 |
| 7 Capture | DAT_I sampled at the termination edge | master | 6.3 |
| 8 Result | rdat + one completion pulse | master | 5.6 |
| 9 Release | CYC_O/STB_O negated | master | 5.2 |
The ninth stage has no box in the figure because it produces nothing — but a master that never reaches it has not finished, and Chapter 5.6 showed what a missing release costs.
2. Reading Is Not the Absence of Writing
WE_O negated means read, not idle. That sounds obvious and produces a specific bug when misread.
The WE_O signal description is explicit: "The write enable output [WE_O] indicates whether the current local bus cycle is a READ or WRITE cycle. The signal is negated during READ cycles, and is asserted during WRITE cycles."
It says nothing about whether a transfer exists. That is CYC_O and STB_O's job, and Chapter 5.1 established that values on wires are not requests. WE_O low with both qualifiers low is an idle bus; WE_O low with both asserted is a read in progress. The direction bit does not distinguish those two — the qualifiers do.
What the master still drives during a read. RULE 3.60 qualifies ADR_O, DAT_O(), SEL_O() and WE_O with STB_O — note that DAT_O is in that list. A master presenting a read still has its write-data output qualified, and Chapter 4.6 showed it typically carries the previous write's value. The specification's own SINGLE READ figure shows the master's DAT_O in an undefined state throughout.
Which is why a slave must check WE_I before writing anything — a point Chapter 4.6 made and that Section 6 of this chapter revisits from the read side.
3. The Running Peripheral
Module 6 uses one device throughout, extended as chapters require.
| Byte offset | Word offset | Register | Access | Contents |
|---|---|---|---|---|
0x00 | 0 | STATUS | read-only | flags, some externally driven |
0x04 | 1 | COUNT | read-only | a free-running counter |
0x08 | 2 | CONTROL | read/write | configuration |
0x0C | 3 | INPUT_DATA | read-only | an external input, changes on its own |
0x10 | 4 | ID | read-only | a constant |
4. RTL — The Master and the Register Bank
// ─────────────────────────────────────────────────────────────────────────
// wb_read_master — the Module 6 running master.
//
// PURPOSE. Turn a local client read request into a Wishbone read and return
// the value. It is Chapter 5.6's wb_completion_master specialised for reads:
// the same client contract, the same acceptance boundary, the same
// level-sampled termination and the same one-pulse completion.
//
// WHAT IS NEW HERE is only that WE_O is driven low and that the captured
// value is the point of the exercise rather than a detail of it.
//
// CLIENT CONTRACT (LOCAL POLICY, not Wishbone — RULE 2.15 would require a
// datasheet to state it):
// * req_i is accepted only in a cycle where acc_o is also asserted.
// * one transaction outstanding at a time.
// * done_o pulses once per accepted request; rdat_o is then valid and held.
//
// Reset: SYNCHRONOUS, ACTIVE HIGH (RULES 2.30, 3.00, 3.20).
// ─────────────────────────────────────────────────────────────────────────
module wb_read_master #(
parameter int unsigned AW = 30, // WORD address width
parameter int unsigned DW = 32
) (
input logic clk_i,
input logic rst_i,
// ── local client side (not Wishbone) ────────────────────────────────
input logic req_i,
input logic [AW-1:0] req_adr_i, // WORD address
input logic [DW/8-1:0] req_sel_i,
output logic acc_o,
output logic busy_o,
output logic done_o,
output logic [1:0] status_o, // 0=ok 1=error 2=retry
output logic [DW-1:0] rdat_o,
// ── Wishbone MASTER interface ───────────────────────────────────────
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
);
localparam logic [1:0] ST_OK = 2'd0, ST_ERR = 2'd1, ST_RTY = 2'd2;
// ── STATE ─────────────────────────────────────────────────────────────
// active_q: a read is outstanding. adr_q / sel_q: the PRIVATE COPY that
// makes RULE 3.60 satisfiable across an unbounded wait (Chapter 5.5).
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;
// ── BUS OUTPUTS ───────────────────────────────────────────────────────
// PERMISSION 3.40 lets both qualifiers share one signal: this master
// never negates STB_O mid-transfer.
assign cyc_o = active_q;
assign stb_o = active_q;
assign adr_o = adr_q;
assign sel_o = sel_q;
// WE_O held low for the whole transfer. RULE 3.60 qualifies it with
// STB_O, so it must be stable while the transfer is presented — here it
// is a constant, which satisfies that trivially and makes the read
// direction impossible to corrupt mid-transfer.
assign we_o = 1'b0;
// DAT_O is a master OUTPUT even on a read, and RULE 3.60 qualifies it.
// Driving zero is an EDUCATIONAL CHOICE, not a requirement: the
// specification's SINGLE READ figure shows it undefined, and Chapter 4.6
// showed a master legally leaving stale write data here. Zero makes
// simulation traces easier to read and hides nothing, because a correct
// slave ignores DAT_I entirely when WE_I is negated.
assign dat_o = '0;
logic terminated;
assign terminated = ack_i | err_i | rty_i;
always_ff @(posedge clk_i) begin
if (rst_i) begin
active_q <= 1'b0; // RULE 3.20
adr_q <= '0;
sel_q <= '0;
done_o <= 1'b0;
status_o <= ST_OK;
rdat_o <= '0;
end else begin
done_o <= 1'b0; // done_o is a PULSE
if (acc_o) begin
// ── READ START ──────────────────────────────────────────────────
// Metadata captured once. From the next edge the client may change
// its inputs freely; the bus is driven from adr_q / sel_q.
active_q <= 1'b1;
adr_q <= req_adr_i;
sel_q <= req_sel_i;
end else if (active_q && terminated) begin
// ── TERMINATION EDGE ────────────────────────────────────────────
// Chapter 5.6's four obligations. The capture condition needs only
// two terms here rather than three, because this master never
// writes — there is no `!we_q` to check.
//
// active_q : the transfer is still presented, so the selected
// slave is still driving the return path
// ack_i : a SUCCESSFUL termination. RULE 3.65 ties the slave's
// DAT_O to its termination; on ERR or RTY there is no
// defined read value.
if (ack_i) rdat_o <= dat_i;
status_o <= ack_i ? ST_OK : (err_i ? ST_ERR : ST_RTY);
active_q <= 1'b0; // release CYC_O and STB_O
done_o <= 1'b1; // report exactly once
end
end
end
endmodule// ─────────────────────────────────────────────────────────────────────────
// wb_read_regs — the running peripheral, read path only.
//
// PURPOSE. Turn a local word offset into a register value, and terminate.
// This is stage 4, 5 and part of 6 of Figure 1.
//
// TERMINATION STYLE. Combinational, which PERMISSION 3.30 explicitly allows
// ("i.e. there is a combinatorial logic path between [STB_I] and [ACK_O]")
// and OBSERVATION 3.40 credits with one transfer per clock. Chapter 6.4
// builds the registered alternative and weighs them.
//
// Reset: SYNCHRONOUS, ACTIVE HIGH (RULES 2.30, 3.00).
// ─────────────────────────────────────────────────────────────────────────
module wb_read_regs #(
parameter int unsigned OFF_AW = 3, // 8 word offsets
parameter int unsigned DW = 32
) (
input logic clk_i,
input logic rst_i,
// Wishbone SLAVE interface
input logic cyc_i,
input logic stb_i,
input logic we_i,
input logic [OFF_AW-1:0] adr_i, // LOCAL word offset
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,
// device-side inputs: genuinely external, change on their own
input logic [DW-1:0] input_data_i,
input logic [7:0] flags_i
);
// Word offsets. The byte offsets a datasheet would quote are 4x these.
localparam logic [OFF_AW-1:0] O_STATUS = 3'd0; // byte 0x00
localparam logic [OFF_AW-1:0] O_COUNT = 3'd1; // byte 0x04
localparam logic [OFF_AW-1:0] O_CTRL = 3'd2; // byte 0x08
localparam logic [OFF_AW-1:0] O_INPUT = 3'd3; // byte 0x0C
localparam logic [OFF_AW-1:0] O_ID = 3'd4; // byte 0x10
localparam logic [DW-1:0] ID_VALUE = 32'h5742_0601; // "WB", module 6 rev 1
logic [DW-1:0] ctrl_q;
logic [DW-1:0] count_q;
// ── THE QUALIFIED TRANSFER ────────────────────────────────────────────
// RULE 3.30 forbids responding to any slave signal while CYC_I is
// negated; RULE 3.35 requires the termination to be generated from the
// AND of CYC_I and STB_I.
logic xfer;
assign xfer = cyc_i & stb_i;
// ── OFFSET LEGALITY ───────────────────────────────────────────────────
logic known_off;
always_comb begin
unique case (adr_i)
O_STATUS, O_COUNT, O_CTRL, O_INPUT, O_ID: known_off = 1'b1;
default: known_off = 1'b0;
endcase
end
// A write to a read-only offset is refused. Module 6 is about reads, so
// the write path exists only to keep CONTROL genuinely writable and to
// keep the read/write distinction honest.
logic illegal;
assign illegal = ~known_off | (we_i & (adr_i != O_CTRL));
// RULE 3.35 both; RULE 3.45 mutually exclusive by construction.
assign err_o = xfer & illegal;
assign ack_o = xfer & ~illegal;
// ── THE READ MULTIPLEXER ──────────────────────────────────────────────
// RULE 3.65 requires a slave to qualify DAT_O() with its termination, so
// ack_o appears in the condition. Driving '0 otherwise also keeps a
// merged return path clean (Chapter 3.5) — Chapter 6.3 develops both.
//
// dat_o is assigned unconditionally first, so every path through this
// block writes it. That is what prevents an inferred latch.
always_comb begin
dat_o = '0;
if (xfer && !we_i && ack_o) begin
unique case (adr_i)
O_STATUS: dat_o = {24'd0, flags_i};
O_COUNT: dat_o = count_q;
O_CTRL: dat_o = ctrl_q;
O_INPUT: dat_o = input_data_i; // sampled combinationally
O_ID: dat_o = ID_VALUE;
default: dat_o = '0;
endcase
end
end
// ── STATE ─────────────────────────────────────────────────────────────
// count_q free-runs: it is a genuinely moving value, which makes it a
// useful read target for detecting a master that captures at the wrong
// edge (Chapter 6.3).
always_ff @(posedge clk_i) begin
if (rst_i) begin
ctrl_q <= '0;
count_q <= '0;
end else begin
count_q <= count_q + 32'd1;
// The only write path. Gated on ack_o, not merely on xfer — the
// distinction is invisible here because this slave never waits, and
// load-bearing the moment it does (Chapters 5.3 and 6.5).
if (xfer && we_i && ack_o && (adr_i == O_CTRL)) begin
for (int unsigned n = 0; n < DW/8; n++) begin
if (sel_i[n]) ctrl_q[n*8 +: 8] <= dat_i[n*8 +: 8];
end
end
end
end
endmoduleReading the pair
Purpose. The master converts a client intention into a qualified read and captures the answer; the register bank converts a local offset into a value and terminates.
Interface. The master's client side is Module 5's contract unchanged. The slave sees a Wishbone slave interface plus two genuinely external device inputs.
State. Master: the outstanding flag and the address/select copy. Slave: CONTROL and a free-running counter.
Combinational logic. Master: acc_o and all bus outputs from state. Slave: xfer, offset legality, two exclusive terminations, and the read multiplexer.
Sequential logic. Master: capture at acceptance, capture-and-release at termination. Slave: the counter, and the single write path.
Read start. CYC_O and STB_O rise together at the edge following req_i & ~active_q, with adr_q already loaded at that same edge. RULE 3.25's "no later than" is met by rising together.
Address. From adr_q, written once. It cannot move while the transfer is outstanding — Chapter 6.2 simulates what happens when it can.
Data return. From the slave's read multiplexer, gated on ack_o per RULE 3.65.
ACK. Combinational from the qualified transfer and offset legality, per PERMISSION 3.30.
Capture. rdat_o <= dat_i at the termination edge, only on ack_i.
Waiting. This pair never waits — ack_o is asserted in the presented cycle. Chapter 6.5 adds latency and shows what must stay coherent.
Reset. Synchronous, active high. active_q <= 0 negates both qualifiers, satisfying RULE 3.20 through the state encoding.
Failure modes. Section 6.
Simplifications. No interconnect yet — the slave's adr_i is assumed already decoded to a local offset, which Chapter 6.2 builds. One outstanding transaction. No read side effects until Chapter 6.5.
5. The Canonical Read, Edge by Edge
A single Wishbone read
6 cyclesNarrate it — this is the habit Module 6 trains.
Before edge 2. The master drives CYC_O, STB_O, ADR_O = 4 and WE_O = 0. The slave, answering combinationally, already has ACK_O asserted and 0x57420601 on its DAT_O. Nothing has been observed yet by either side.
At edge 2 — both the sampling edge and the termination edge. The slave sees a qualified transfer. The master samples ack_i asserted and dat_i in the same instant. This is the only edge at which the returned value is meaningful, per RULE 3.65.
After edge 2. active_q has cleared, so CYC_O and STB_O are negated. rdat_o holds the value. done_o pulses. The slave, seeing STB_I negate, drops ACK_O and reverts DAT_O — RULE 3.50, which OBSERVATION 3.10 calls automatic.
Why sampling and termination coincide here. The slave is combinational, so Chapter 5.7's CONTINUATION interval is empty. The entire forward-and-return path of Figure 1 must resolve inside cycle 2 — which is OBSERVATION 3.50's loopback, and the reason Chapter 6.4 exists.
6. Failure Modes and Discriminating Evidence
Symptom: the read hangs — STB_O asserted, no termination, forever.
Candidate causes. Any of the nine stages. All produce an identical master-side waveform, which is why probing in order matters more than guessing.
Discriminating evidence. Walk the path from Figure 1:
| Probe | If absent, the fault is |
|---|---|
CYC_O/STB_O at the master | the master's own state machine, or a RULE 3.25 duration violation (5.2) |
CYC_I/STB_I at the intended slave | address decode or forward routing |
ACK_O inside that slave | the slave — usually an unhandled default in the offset decoder |
ACK_I back at the master | the response merge, or a master lacking the termination the slave produced |
The first probe where the expected signal is missing names the stage, and nothing else does. Chapter 5.1 §5 established this sequence; Chapter 6.6 turns it into a full method.
Likely RTL location. Determined by the probe, never assumed.
Symptom: the read completes and returns the wrong register's value.
Candidate causes. Wrong address on the bus, wrong decode, wrong local offset, or a wrong read-multiplexer case.
Discriminating evidence. Compare ADR_O at the master against the intended word address, then the decoded select, then the local offset, then the multiplexer output. The first mismatch names the stage. Chapter 6.2 and Chapter 6.3 develop each.
Symptom: the read completes and returns zero.
Candidate causes. An offset the slave does not implement — but that should produce ERR_O, not ACK_O with zero. Or the master captured outside the termination cycle and sampled a reverted return path.
Discriminating evidence. Check status_o. ST_ERR means the slave refused and zero is expected; ST_OK with zero means the capture is suspect — Chapter 5.6 measured a late-capturing master returning zero on every read.
Symptom: reading a register appears to change the device.
Candidate causes. Either the slave has a genuine read side effect (see the callout in Section 2), or its write path is missing its WE_I term and is firing on reads.
Discriminating evidence. Check what value the register took. A genuine read-to-clear takes a defined value — usually zero. A missing-WE_I bug takes the previous write's data, because RULE 3.60 leaves that on DAT_O during a read (Chapter 4.6). That fingerprint separates a feature from a bug in one observation.
7. Verification
// ─────────────────────────────────────────────────────────────────────────
// wb_read_flow_checker — the read-path invariants introduced here.
//
// P1 and P2 are SPECIFICATION. P3 is a DESIGN OBLIGATION derived from
// RULE 3.65 — the rule constrains the SLAVE's DAT_O, and what the master
// does with that window is the master's design (Chapter 5.8 Section 11).
// P4 is LOCAL POLICY for this master's client contract.
// ─────────────────────────────────────────────────────────────────────────
module wb_read_flow_checker #(
parameter int unsigned DW = 32
) (
input logic clk_i,
input logic rst_i,
input logic cyc_o,
input logic stb_o,
input logic we_o,
input logic ack_i,
input logic err_i,
input logic rty_i,
input logic [DW-1:0] rdat_q, // white-box: captured result
input logic busy_o,
input logic done_o
);
default disable iff (rst_i);
// P1 — SPECIFICATION (RULE 3.25). A strobe never exists outside a cycle.
property p_stb_implies_cyc;
@(posedge clk_i) stb_o |-> cyc_o;
endproperty
a_stb_implies_cyc : assert property (p_stb_implies_cyc)
else $error("RULE 3.25: STB_O asserted without CYC_O");
// P2 — SPECIFICATION (RULE 3.60, as stability). WE_O is qualified by
// STB_O, so the DIRECTION of a presented transfer cannot change
// while it is outstanding. A read must stay a read.
property p_direction_stable;
@(posedge clk_i) (cyc_o && stb_o && !(ack_i||err_i||rty_i)) |=> $stable(we_o);
endproperty
a_direction_stable : assert property (p_direction_stable)
else $error("RULE 3.60: WE_O changed while the transfer was outstanding");
// P3 — DESIGN OBLIGATION (from RULE 3.65). The captured result changes
// only at the edge of a SUCCESSFUL termination of a presented read.
// Catches both the off-by-one capture and an unconditional one.
// $past is required: rdat_q changes AT the edge, while the
// conditions authorising it were true BEFORE it.
property p_capture_on_successful_read;
@(posedge clk_i) $changed(rdat_q) |-> $past(cyc_o && stb_o && ack_i && !we_o);
endproperty
a_capture_on_successful_read :
assert property (p_capture_on_successful_read)
else $error("read data captured outside a successful read termination");
// P4 — LOCAL POLICY. One completion per bus termination, and never
// without an outstanding transaction.
property p_done_follows_termination;
@(posedge clk_i) done_o
|-> $past(busy_o && cyc_o && stb_o && (ack_i || err_i || rty_i));
endproperty
a_done_follows_termination : assert property (p_done_follows_termination)
else $error("completion pulse without a matching bus termination");
endmoduleP2 is worth a note. It is the read-specific form of RULE 3.60's stability obligation: a transfer whose WE_O flips mid-flight is not one transfer, and a slave that samples the direction late would perform the wrong operation. In wb_read_master it holds trivially because we_o is a constant — which is the point of making it a constant rather than a register.
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 simulated in Section 8.
8. Simulation — The Basic Read, Measured
wb_read_master was pointed at wb_read_regs and asked to read each implemented offset once, plus one unimplemented offset.
=== SIMULATION A - basic read ===
off register expected captured status ADR_O WE_O done
0 STATUS 0x000000a5 0x000000a5 OK 0x0 0 1
1 COUNT (moving) 0x00000006 OK 0x1 0 1
2 CONTROL 0x00000000 0x00000000 OK 0x2 0 1
3 INPUT_DATA 0xcafebabe 0xcafebabe OK 0x3 0 1
4 ID 0x57420601 0x57420601 OK 0x4 0 1
7 (unmapped) - 0x57420601 ERR 0x7 0 1
completions: 6 requests -> 6 done pulses
WE_O asserted at any point: 0Every implemented offset returned its own value, so the read multiplexer and the address path agree.
COUNT returned 0x06 — a moving value, captured at a specific edge, and the exact number depends only on how many cycles elapsed before that read. Chapter 6.3 uses exactly this property to expose a master that captures at the wrong edge, because a stale capture of a constant is invisible.
The unmapped offset returned ERR and left rdat_o unchanged at the previous read's value. That is correct: on an error there is no defined read value, so the master does not capture — and a client that checks status_o before using rdat_o is never misled. A client that ignores status_o sees a plausible stale value, which is the argument for the three-way status rather than a single flag.
WE_O was never asserted, confirming P2 held throughout.
9. Common Mistakes
"A Wishbone read has an address phase and then a data phase, like AXI."
Wrong mental model: separate handshaked channels.
Concrete bug: a master that presents an address, drops the strobe, and waits for data on a later "phase". The slave sees the request vanish and nothing ever completes.
Observable evidence: a strobe asserted for one cycle, then a hang with no termination.
Correct model: Classic has one handshake. The address is qualified by STB_O for the transfer's whole duration and the data comes back within that same transfer. Chapter 6.2 scopes the phrase "address phase" carefully for exactly this reason.
"WE_O low means the bus is idle."
Wrong mental model: the direction bit indicates activity.
Concrete bug: a slave gating on ~we_i without the qualifiers, acting on an idle bus whose WE_O happens to be low.
Observable evidence: reads that appear to happen with no software access, or side effects firing between transfers.
Correct model: WE_O describes direction, CYC_O & STB_O describe existence. Chapter 5.1 §1 is the general form of this.
"A read cannot change hardware state."
Wrong mental model: reads are passive by definition.
Concrete bug: a driver that re-reads an interrupt status register "just to be safe", clearing events nobody handled.
Observable evidence: lost interrupts correlated with diagnostic or logging code.
Correct model: read-to-clear and pop-on-read are ordinary peripheral designs. The direction bit says where the data flows, not whether the device changed. Chapter 6.5 builds one correctly.
10. Interview Reasoning
Before the first edge. A client presents a read request. The master, idle, asserts its accept signal — that conjunction is the acceptance boundary, and it is the last moment the client's inputs matter.
At the acceptance edge. The master latches the word address and byte selects into private registers and sets its outstanding flag. The transaction now exists. Everything the bus sees from here comes from those registers, which is what makes RULE 3.60 satisfiable across a wait of unknown length.
Before the next edge. CYC_O and STB_O are asserted, ADR_O carries the word address, WE_O is negated to indicate a read. The interconnect decodes the address, selects one slave and presents a local offset. The selected slave indexes its register file and — if it answers combinationally — already has ACK_O asserted and the value on its DAT_O.
At the termination edge. The slave sees a qualified transfer. The master samples ack_i asserted while its own transfer is presented — that conjunction is what makes the termination its termination — and samples dat_i in the same instant. RULE 3.65 ties the slave's read data to its termination, so this is the only edge at which the value is meaningful.
After that edge. The master clears its outstanding flag, which negates both qualifiers. The captured value is in a register. One completion pulse goes to the client. The slave, seeing STB_I negate, drops ACK_O and stops driving read data — OBSERVATION 3.10 calls that automatic.
If the slave needs longer, nothing about the story changes except that the termination edge arrives later. The master holds everything still and samples the termination as a level every cycle. There is no separate wait signal — the slave throttles purely by withholding its acknowledge.
The two things I would emphasise as the actual content. The address is meaningful for the whole transfer; the data is meaningful for one cycle. And the master must sample the termination as a level, not an edge, because a slave may legally hold ACK asserted — RULE 3.55.
11. Understanding Check
12. What's Next
The whole read is now visible: nine stages, a forward path carrying a question and a return path carrying an answer, with the data meaningful for exactly one cycle.
The first payload on that forward path is the address, and it has been treated as a value that simply appears on ADR_O. It carries more than a number — it selects a device and a register inside it, and the phrase used for that interval invites an assumption from other protocols that is wrong here.
When does
ADR_Oidentify the read target, and how long must that information stay coherent?
Chapter 6.2 — Address Phase answers it. The full path is on the Wishbone curriculum index.
Continue learning
Related tutorials
- Related topic
Data Flow
One Wishbone access, followed through every block in both directions: what the master drives, where the address changes form, which signals are broadcast and which are decoded, and how read data and termination find their way back to exactly one requester.
- Related topic
Write Cycle Flow
A read asks a question and the slave supplies the answer; a write carries the answer with it and changes the device. One Wishbone write from client intent to committed register, and why the ownership reversal changes everything downstream.
- 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.
- 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.
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.
