Skip to content
VLSI Mentor

Wishbone · Module 28

Intermediate Questions

Three flawed slaves, three waveform predictions, and the measurement that shows one write committing four times while every Wishbone rule is obeyed.

Chapter 28.1 was about describing the interface. This chapter is about predicting what a given piece of RTL will actually do — which is the first point in a Wishbone interview where memorisation stops working entirely.

The questions here all have the same shape: here is something that looks fine. Run it in your head.

1. Why A Zero-Wait Slave Hides Bugs

What the question tests: whether you understand that a phase without wait states has no interior.

Look at this and say what is wrong with it.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  logic commit;
  assign commit = WRITE_ON_STB ? (present && we_i) : (ack_o && we_i);

INTERVIEW REVIEW EXAMPLE — the WRITE_ON_STB branch is intentionally broken.

The broken branch commits on every clock the request is presented. The correct branch commits on the clock it is accepted. At zero wait states those are the same clock and the two branches are indistinguishable — not hard to tell apart, identical.

Here is the same slave, same program — one write to a register that increments on every committed write, then a read back:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  rig                        transfers  commits  value read back
  correct,      WAITS=3              2        1        1
  WRITE_ON_STB, WAITS=0              2        1        1
  WRITE_ON_STB, WAITS=3              2        4        4

  commits per write   correct 1   broken@0 1   broken@3 4

Three rigs. The broken one at zero waits is byte-identical to the correct one. Add three wait states and the same RTL commits four times.

Two things to take from the table. First, the transfer count is 2 in every row — a termination census cannot see this defect at all. Second, the reason a storage register would have hidden it even at three waits: writing 0xA1B2C3D4 four times leaves 0xA1B2C3D4. The defect is only observable through something not idempotent, which is why the register under test increments.

A design that passes only at zero latency has not been tested. It has been avoided.

2. Partial Writes, And Why The Bug Escapes

Q. What does SEL_O() do, and how would a byte-lane bug get through your test suite?

SEL_O() indicates which lanes carry valid data. Chapter 13.3 built the merge. The interview question is the second half.

Consider a slave that ignores SEL_I and writes all four lanes:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
          for (b = 0; b < SW; b = b + 1)
            if (IGNORE_SEL || sel_i[b])
              mem[widx][b*8 +: 8] <= dat_i[b*8 +: 8];

INTERVIEW REVIEW EXAMPLE — IGNORE_SEL is intentionally broken.

Q. Which test exposes it? Not the obvious one. A single-lane write of zeros into a location that already holds zeros produces the correct answer whether the mask is honoured or not. The stimulus hits the partial-write case, a coverage model records the bin as covered, and the defect walks through.

The test that exposes it needs a non-zero background: seed the word, write one lane, read it back. The measured control case from Chapter 28.10xA1B2C3D4 seeded, lane 1 written with 0xBB, read back 0xA1B2BBD4 — is exactly that shape, and every other lane in it is a live witness.

Coverage says the situation occurred. It does not say the stimulus was sensitive to the bug.

3. Retry Is A Termination, Not A Wait

Q. How is RTY different from waiting? What state may advance when you receive one?

Waiting is the absence of an answer. RTY is an answer: the phase is over, STB_O may be negated, the bus is free. And the operation did not happen.

So the split is:

may advancemust not advance
anything counting phasesanything counting work done
a retry counter, a backoff timerthe operation index, a data pointer, a byte count

Here is a driver that gets it wrong in one line, and one that does not:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
        // THE ONE LINE. On RTY the retry-aware driver leaves the
        // operation index exactly where it was, so the next request it
        // presents is the same request. The broken driver advances and
        // reports work that never happened.
        if (is_rty && RETRY_AWARE) begin
          idx_q <= idx_q;
        end else begin
          idx_q  <= idx_q + 5'd1;
          ndone_q <= ndone_q + 16'd1;
        end

Four operations; the memory answers RTY once, on its third transfer. Predict both rigs before looking.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  driver          attempts  operations done  RTY seen  phases at the pins
  retry-aware            5                4         1                   5
  RTY = done             4                4         1                   4

  terminations at the master port
  driver          ACK  RTY  ERR
  retry-aware        4    1    0
  RTY = done         3    1    0

  memory writes committed   retry-aware 3   RTY = done 2
  word at 0x0104            retry-aware 0x33330000   RTY = done 0x22220000

Note the ACK column, taken from a raw-pin census rather than from the driver being judged: 4 versus 3. The broken driver claims four operations and the pins recorded three successful ones. That single discrepancy is the whole diagnosis, and it is available without opening a waveform.

Note also what is not wrong: neither driver violates the protocol. B3 does not require a master to persevere. What the broken one does is claim an operation completed when the bus said otherwise — and when and how to retry is explicitly supplier-defined, which means it is your specification that this driver violates, not Wishbone's.

4. What Changes When ACK Is Registered

Q. You move ACK_O behind a flip-flop. What changes?

A weak answer: "it gets slower." A better one names both halves.

What changes architecturally: nothing. Same target, same operation, same committed data, same termination class.

What changes in clocks: one extra per transfer, because the master cannot see the answer until the clock after the slave decided it.

What changes in timing: the combinational path from the master's STB_O through the slave's termination logic and back to the master's ACK_I is broken. That path is real, and the specification names it:

OBSERVATION 3.50 — In large high speed designs the asynchronous assertion ... could lead to unacceptable delay times, caused by the loopback delay from the MASTER to the SLAVE and back to the MASTER.

Chapter 28.4 measures the clock half and says plainly which half was not measured.

5. Three Waveform Predictions

6. Decoding, Safely

Q. How do you decode address ranges without introducing an aliasing bug?

The mechanism is Chapter 12.3. The interview question is what makes one decoder trustworthy and another not, and it comes down to two things you can state in a sentence each.

Compare the full width. Here is the compare, with both defects a decoder of this shape can carry:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  logic [AW-1:0] cmp_mask0, cmp_mask1, cmp_adr;
  assign cmp_mask0 = WINDOW_WIDE ? (S0_MASK[AW-1:0] & ~16'h0100)
                                 :  S0_MASK[AW-1:0];
  assign cmp_mask1 = S1_MASK[AW-1:0];
  assign cmp_adr   = ADDR_TRUNCATE ? {{(AW-8){1'b0}}, oadr[7:0]} : oadr;

  logic hit0, hit1;
  assign hit0 = ((cmp_adr & cmp_mask0) == (S0_BASE[AW-1:0] & cmp_mask0));
  assign hit1 = ((cmp_adr & cmp_mask1) == (S1_BASE[AW-1:0] & cmp_mask1));

INTERVIEW REVIEW EXAMPLE — WINDOW_WIDE and ADDR_TRUNCATE are intentionally broken.

A compare that silently drops high bits does not produce a missing region — it produces an extra one. Addresses that belong nowhere start matching somewhere. With the windows at 0x00000x00FF and 0x01000x01FF, work out which addresses each defect misroutes before reading on; the two defects agree on the one address a bug report would quote, and disagree on exactly one other.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  address  expected  decoder 1       decoder 2       d1 multi-select
  0x0000   S0 regs   S0 regs         S0 regs          no
  0x00ff   S0 regs   S0 regs         S0 regs          no
  0x0100   S1 mem    S0 regs         S0 regs         YES
  0x01ff   S1 mem    S0 regs         S0 regs         YES
  0x0200   unmapped  unmapped        S0 regs          no
  0x0300   unmapped  unmapped        S0 regs          no
  0x1000   unmapped  unmapped        S0 regs          no

  target mismatches      decoder 1 4   decoder 2 7
  multi-select events    decoder 1 4   decoder 2 0
  protocol violations    decoder 1 P0 0 P2 0   decoder 2 P0 0 P2 0

0x0200 is the discriminating address, and it is not the one that reproduces the bug. A widened window still ends at 0x01FF, so 0x0200 remains unmapped; a truncated compare discards the high byte, 0x0200 becomes 0x0000, and the register window claims it. Sweep window boundaries, not typical addresses. Neither decoder violates a single rule.

Report overlap. If two regions can claim one address, first-match-wins resolves it deterministically and silently. The shadowed peripheral does not complain; it simply stops receiving traffic. A decoder that cannot report multi-select cannot tell you this happened.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  // An overlap that first-match-wins makes SILENT. A widened window
  // does not announce itself as a collision; it simply shadows its
  // neighbour, and this is the only wire that says so.
  assign p2_multi_o   = present && hit0 && hit1;

Q. What happens on an unmapped address? Whatever you decided. B3 defines nothing. A default responder answering ERR is the only one of the three common policies that tells anybody — and it is a policy, so say so.

7. Read-Modify-Write And The Word "Indivisible"

Q. Does an RMW cycle guarantee atomicity?

This is the intermediate question most likely to catch a well-read candidate, because the specification's own section opens with:

"The RMW (read-modify-write) cycle is used for indivisible semaphore operations."

That is a statement of purpose. Section 3.4 provides no locking mechanism, no arbitration rule and no protection guarantee. What RULE 3.85 and §3.4 actually define is a structure: one CYC_O spanning a read transfer and a write transfer.

So the honest decomposition has three parts, and a strong answer gives all three:

  1. ProtocolCYC_O held across both halves. This is all Wishbone defines.
  2. Arbiter — exclusivity additionally requires an arbiter that honours CYC_I as a bus claim. RECOMMENDATION 3.05 says arbitration logic "often uses CYC_I to select between MASTER interfaces." Often, not must.
  3. Target — and no second port into the slave. Chapter 4.9 measured a lost update with CYC_O held perfectly, through a dual-port slave.

Never say "holding CYC_O makes it atomic." Say: holding CYC_O is the protocol half; exclusivity also needs an arbiter that honours it and a target with no back door.

8. Designing For Arbitrary Latency

Q. How would you write a master that tolerates any slave latency?

The answer is a state machine with one property: nothing that belongs to the request is re-derived while the phase is open. Capture the request when you issue it, drive the captured copy, and change nothing until a termination arrives.

A wait-tolerant master state machine with three states and the invariant each one maintains. From idle, accepting a client request captures the address, the direction, the byte selects and the write data into registers and moves to the present state. In the present state the master drives the captured copy, never the live client signals, and remains there for as long as no termination arrives; this is where rule 3.60 stability is preserved automatically because there is nothing live left to change. A termination moves the machine to the respond state, where it classifies the answer as acknowledge, error or retry and reports it to the client, and only a retry returns it to present with the same captured request rather than to idle.IDLEcapture the request on acceptPRESENTdrive the CAPTURED copy, notthe live oneRESPONDclassify ACK / ERR / RTYthe invariantnothing request-shaped isre-read while the phase isopen12

The dashed return edge is the RTY path from Section 3: back to PRESENT with the same captured request, not back to IDLE to fetch a new one.

An interviewer will push on the capture: "why not just drive the client's signals directly?" Because the client is not bound by RULE 3.60. It may withdraw, change its mind, or be a FIFO that pops. The register is what converts an unconstrained client into a conformant master.

9. Three Code Reviews In One Sitting

Given ten minutes and three snippets, what do you say about each?

snippetthe defectthe discriminating test
commit keyed to stb_icommits once per presented clockrun it with wait states against a non-idempotent register
byte lanes ignoredpartial writes overwrite untouched lanesseed non-zero, write one lane, read back
RTY treated as completionwork counted that did not happencompare driver completions against a raw-pin ACK census

Notice what the third column has in common: none of the three defects is found by the test that reproduces the symptom. Each is found by a test constructed so that the defect and the correct behaviour must disagree.

10. What To Carry Forward

  • Zero latency is not a test configuration, it is a blind spot. Two of this chapter's three defects are structurally invisible there.
  • Commit on the termination. Then find a non-idempotent location and prove it.
  • RTY ends the phase and not the work. Phases may advance; work may not.
  • A coverage hit is not sensitivity. Seed non-zero before you believe a byte-lane test.
  • RULE 3.60 binds the master, not the interconnect. The same property can be clean at one boundary and broken at another.
  • RMW is a structure, not a guarantee. Protocol, arbiter, target — all three or none.
  • Capture the request. A wait-tolerant master is one with nothing live left to change.

Chapter 28.3 adds a second master, an interconnect, and the question of whether the transfer that completed was even yours.

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.