Skip to content
VLSI Mentor

Wishbone · Module 7

Waveform Analysis

A ten-step method for reading an unfamiliar Wishbone write off a waveform, applied to five traces — and the one question a bus trace can never answer about a write.

Chapter 6.6 built a nine-step method for reading a Wishbone read off a trace. A write needs one more step, and it is the one the bus cannot help with.

How do you read an arbitrary Wishbone write off a waveform, and localise a failure from evidence alone?

1. The Ten-Step Method

#QuestionLook atWhat a wrong answer means
1Is there a bus cycle?CYC_Ono cycle → master state machine
2Is a transfer presented?STB_O within CYC_Ostrobe outside a cycle → RULE 3.25 violation
3Is it a write?WE_O assertednegated → this is a read; wrong chapter
4Which register?ADR_O only while qualified4× expected → byte/word confusion
5What value?DAT_O only while qualifieddiffers from the request → master capture
6Which byte lanes?SEL_Oall-zero → legal, commits nothing
7Which target?slave select / per-slave STB_Inone → unmapped; two → decode fault
8When should it commit?the slave's declared policynot on the bus — read the datasheet
9How did it end?ACK_I / ERR_I / RTY_Inone → hang; ERR → legally refused
10Did it release?CYC_O/STB_O negate; one doneno release → master completion logic

Steps 4, 5 and 6 are the write tripleChapter 7.2 §1 showed each produces a distinguishable symptom, so checking them in order separates three faults that all present as "the register is wrong".

Step 9 comes late deliberately. On a read the termination gates the data, so it had to come before inspecting DAT_I. On a write the payload is the master's and is valid from the first cycle, so the termination only tells you when it ended — and checking it early tempts you to stop at "it acknowledged, so it worked".

2. Trace A — A Correct Write

Trace A: a correct delayed write

8 cycles
Eight clock cycles showing a correct Wishbone write with two wait states. The cycle and strobe signals rise together in cycle two and stay asserted through cycle four, with write enable high throughout. The address output holds word two, the data output holds zero zero zero zero zero zero zero f and all four byte selects are asserted for all three presented cycles. The slave acknowledges in cycle four and commits at the edge ending it. From cycle five the control register reads zero zero zero zero zero zero zero f, both qualifiers are negated and the completion pulse is asserted.steps 1-7: write word 2, all lanessteps 1-7: write word 2,all lanessteps 8-9: commit + ACKsteps 8-9: commit + ACKstep 10: releasedstep 10: releasedCLK_ICYC_OSTB_OWE_OADR_O----0x20x20x2----------------DAT_O----0000000F0000000F0000000F----------------SEL_O00001111111111110000000000000000ACK_ICONTROL000000000000000000000000000000000000000F0000000F0000000F0000000Fdone_ot0t1t2t3t4t5t6t7
Trace A — the reference. Work the ten steps against this before attempting a broken one.

Walking the method:

1–3. CYC_O asserted cycles 2–4; STB_O across the same interval; WE_O asserted throughout and never changing. A write, and it stayed a write.

4–6. ADR_O reads 0x2 in all three qualified cycles, DAT_O reads 0x0000000F, SEL_O reads 1111. One value each, no drift — RULE 3.60 and §3.2.2 satisfied.

7. One target selected for exactly the presented interval.

8. The slave's declared policy — commit on the edge it returns ACK_O — puts the commit at the edge ending cycle 4.

9. ACK_I in cycle 4 only. Cycles 2 and 3 are wait states.

10. Both qualifiers negate in cycle 5, one done pulse, CONTROL reads 0x0000000F.

Every step consistent. Note that CONTROL changes after edge 4 — the flop loaded at that edge, so the new value is visible from cycle 5. Reading it as "CONTROL changed in cycle 5" is the before/at/after confusion this course has been careful about: it changed at edge 4 and is observable in cycle 5.

3. Trace B — The Payload Drifted

Trace B: payload instability

7 cycles
Seven clock cycles showing a write whose payload changes while the transfer is outstanding. In cycle two the master presents word address two with data zero zero zero zero zero zero zero f and write enable high. In cycle three both the address and the data change, to word six and dead beef, while the strobe is still asserted and no termination has arrived. The slave acknowledges in cycle four, by which time the bus carries the drifted payload. The output data register at word six takes dead beef and the control register at word two is never written.steps 4-5: word 2, 0x0Fsteps 4-5: word 2, 0x0FSTEPS 4-5 FAIL: now word 6STEPS 4-5 FAIL: now word 6CLK_ICYC_OSTB_OWE_OADR_O----0x20x60x6------------DAT_O----0000000FDEADBEEFDEADBEEF------------ACK_ICONTROL00000000000000000000000000000000000000000000000000000000OUTPUT00000000000000000000000000000000DEADBEEFDEADBEEFDEADBEEFt0t1t2t3t4t5t6
Trace B — a successful write of a transaction nobody requested. The fault is at step 4 and 5, four steps before the acknowledge.

Steps 1–3 pass. Steps 7 through 10 also pass — one clean termination, one commit, a proper release.

Steps 4 and 5 fail together, and that pairing is itself information: an address that drifts alone is one bug, an address and data drifting together is a master that lost its whole payload copy.

CONTROL was never written; OUTPUT_DATA holds a value nobody requested. The master reported success.

Two master faults produce this, and the trace alone does not separate themChapter 7.3 §5 showed the discriminator is the slave's remembered offset, not anything on the bus:

RememberedCommittedFault
wrongsame as rememberedthe master never latched
rightdifferentthe slave committed from the bus

And a third possibility the trace does distinguish: if ADR_O tracks the client's current request input, the master is unlatched; if it diverges from both the client and the original request, the master latched and then rewrote.

4. Trace C — The Mask Was Ignored

Trace C: SEL ignored

6 cycles
Six clock cycles showing a narrow write that destroys neighbouring bytes. The control register holds eleven twenty-two thirty-three forty-four before the transfer. In cycle two the master presents a write to word two with data aa bb cc dd and only select bit one asserted. The slave acknowledges in the same cycle. From cycle three the control register reads aa bb cc dd, meaning all four bytes were replaced even though only one byte lane was selected.SEL=0010 selects one laneSEL=0010 selects one laneall four bytes replacedall four bytes replacedCLK_ISTB_OWE_OADR_O----0x2----------------DAT_O----AABBCCDD----------------SEL_O000000100000000000000000ACK_ICONTROL1122334411223344AABBCCDDAABBCCDDAABBCCDDAABBCCDDt0t1t2t3t4t5
Trace C — every protocol step passes, and three bytes of unrelated state are gone.

All ten steps pass. The payload is stable, SEL_O is driven and meaningful, the termination is single and clean, the release is proper.

And three bytes that the transfer never named are gone. 0x11, 0x22 and 0x44 were valid state; only lane 1 was selected.

The tell is in the committed value itself. CONTROL became exactly DAT_O. A correct masked write can never produce that unless SEL_O was 1111 — so SEL_O = 0010 with CONTROL == DAT_O is conclusive without any internal probe.

That is unusual and worth noticing, because it is one of the few write faults the bus trace does settle. Chapter 7.2 §6 measured zero trace differences between this slave and a correct one — but that was comparing two traces; here the single trace plus the committed value is enough.

5. Trace D — The Command Fired Four Times

Trace D: repeated side effect

9 cycles
Nine clock cycles showing a write to a command register through a slave with three wait states, where the side effect is gated on the request being presented rather than accepted. Both qualifiers and write enable are asserted from cycle two through cycle five with a stable address of word nine. The acknowledge appears only in cycle five. The command pulse signal is high for all four presented cycles rather than one, and the launch counter advances from zero to four.step 8 FAILS: commit on cycle 1step 8 FAILS: commit oncycle 1one ACK, four launchesone ACK, four launchesCLK_ICYC_OSTB_OWE_OADR_O----0x90x90x90x9----------------ACK_Icmd_pulselaunches012344444t0t1t2t3t4t5t6t7t8
Trace D — one write, one termination, four launches. The bus is entirely conformant.

Steps 1–7 pass and steps 9–10 pass. One transfer, one termination, a stable payload, a clean release.

Step 8 is the failure, and it is visible here only because cmd_pulse and launches are in the trace. Neither is a Wishbone signal.

Remove those two rows and this trace is indistinguishable from Trace A with a different address. That is the point: Chapter 7.4 §5 measured byte-identical bus traces between a correct slave and this one.

The two evidence patterns to recognise:

The launch count tracks the wait length, not the number of writes. Four launches for a three-wait write; two for a one-wait write. Correlation with latency rather than traffic is unique to this bug.

The pulse is four cycles wide instead of one. A downstream block that edge-detects sees one launch and masks the bug entirely; a level-sensitive one sees a long assertion. That divergence between consumers is itself diagnostic, and it explains why the same RTL can appear fine in one integration and fail in another.

6. Trace E — Refused, Not Failed

Trace E: a legal refusal

6 cycles
Six clock cycles showing a write to a read-only register. In cycle two the master presents a write to word zero, the status register, with data and byte selects valid. The slave asserts its error output instead of its acknowledge in the same cycle, and the acknowledge stays low. The status register is unchanged throughout. The master completes with an error status.step 9: ERR, not ACKstep 9: ERR, not ACKSTATUS correctly unchangedSTATUS correctly unchangedCLK_ISTB_OWE_OADR_O----0x0----------------DAT_O----11111111----------------ACK_IERR_ISTATUS000000A5000000A5000000A5000000A5000000A5000000A5t0t1t2t3t4t5
Trace E — the write did not happen, and that is correct behaviour.

Step 9 is where this trace differs from every other, and reading it as a failure is the mistake.

STATUS is read-only. The slave refused the write with ERR_O and committed nothing — and the same term that produced the refusal also blocked the commit, so they cannot disagree.

This is the trace that catches a client bug, not a hardware one. A client that ignores its status output sees a completed transfer and a register that did not change — indistinguishable, from the client's side, from Trace C or D.

RULE 3.45 keeps ACK_O and ERR_O mutually exclusive, so the evidence is unambiguous once you look. Step 9 says check which one, not whether either arrived.

7. The Decision Tree

A decision tree for diagnosing a Wishbone write from a waveform. The top row shows four outcomes of applying the ten step method: the method may stop at step three or nine with no termination or an error termination, at steps four to six with a drifting payload, at step eight with a commit at the wrong time, or pass every step while the committed state is still wrong. The bottom row shows what each implicates: no termination points at decode, slave or return path; a drifting payload points at the master's payload registers; a wrong commit time points at the slave's commit gating; and all steps passing points at the byte mask or the register decode inside the slave.stops at 3 or 9no ACK, or ERRstops at 4-6payload driftedstops at 8commit at wrong timeall 10 passstate still wrongdecode / slave /returnor a legal refusalmaster payload regsunlatched, or rewrittenslave commit gatingpresented vs committedmask or registerdecodeinside the slave12
Figure 1 — where the method stops determines what to open.

The rightmost branch is where a write differs most from a read. On a read, "all steps pass and the value is wrong" left four candidates (Chapter 6.6 §5). On a write it leaves two — the byte mask or the register decode — because Trace C showed the mask fault is often settled by the committed value alone.

What to add to the trace when the bus view is exhausted, in order of usefulness: the slave's commit term, its local offset, the per-slave select vector, any side-effect counter, and — for a registered slave — its remembered payload. Those five resolve every failure in Module 7.

8. Failure Modes and Discriminating Evidence

Symptom: the write completes and the register did not change.

Candidate causes. A legal refusal; an all-zero SEL_O; a commit that never fired; a write to the wrong register that changed a different one.

Discriminating evidence. Check ERR_I first — it is one signal and it eliminates the commonest non-bug. Then SEL_O. Then whether any register changed at all; if one did, this is a wrong-address fault wearing a different symptom.

Symptom: a register the software never addressed changed.

Candidate causes. A drifting payload, or a decode fault.

Discriminating evidence. ADR_O across the whole strobe assertion. Stable and wrong means decode; changing means the payload drifted, and then Chapter 7.3's remembered-offset comparison separates master from slave.

Symptom: bytes the write never named changed.

Candidate causes. The commit ignores SEL_I.

Discriminating evidence. CONTROL == DAT_O with SEL_O != 1111 is conclusive from the bus trace alone, which is unusual for a write fault.

Symptom: an operation starts more times than software asked.

Candidate causes. The commit is gated on presentation.

Discriminating evidence. Count side effects against the wait length. Correlation with latency rather than traffic is unique to this bug, and the pulse width is a second, independent tell.

Symptom: the write hangs.

Candidate causes. Decode selected nobody; the slave has an unterminated path; the return path drops it; the master lacks the termination input the slave produced.

Discriminating evidence. Chapter 6.1 §6's probe order applies unchanged — the forward and return paths are the same for both directions. OBSERVATION 3.35 names the last case.

Symptom: works at zero wait states, breaks with latency.

Candidate causes. Either master bug from Trace B, or the commit gating from Trace D. All three are structurally invisible at zero latency.

Discriminating evidence. Re-run with LAT > 0. If the fault only appears then, it is one of those three — and whether the payload drifted separates the master bugs from the slave one.

9. What a Write Waveform Cannot Tell You

Worth stating plainly, because the method's value depends on knowing its edge.

A bus trace can establish: that the protocol was obeyed; which register was addressed; what value and which lanes were presented; whether the payload held still; how the transfer ended.

A bus trace cannot establish: when the slave actually committed; how many times it committed; whether a side effect fired once; whether the bytes that changed are the bytes that should have.

Traces C and D are the two halves. C is fully conformant and destroyed neighbouring state — though its committed value happens to betray it. D is fully conformant and shows nothing at all without two non-bus signals.

This is the same boundary the whole course has been mappingChapter 5.8 §8 collected it, and Modules 6 and 7 added four more instances. Conformance is necessary, finite, and not sufficient.

And on a write the consequence is worse. A read fault returns a wrong answer that a re-read corrects. A write fault has already replaced state that no longer exists anywhere.

10. Common Mistakes

"ACK arrived, so the write worked."

Wrong mental model: protocol completion equals architectural success.

Concrete bug: Traces B, C and D all acknowledge normally.

Observable evidence: a clean trace and a device in the wrong state.

Correct model: ACK_O proves the transfer ended. Step 9 is the ninth step for a reason — it says when, not whether it worked.

"The register did not change, so the write failed."

Wrong mental model: an unchanged register means a fault.

Concrete bug: Trace E — a correct refusal of a read-only register, or a legal all-zero SEL_O.

Observable evidence: ERR_I asserted, which a client ignoring its status never sees.

Correct model: check which termination arrived before concluding anything.

"Read DAT_O to see what was written."

Wrong mental model: the data bus always says the data.

Concrete bug: reading DAT_O from an unqualified cycle and diagnosing the wrong value.

Observable evidence: a value that matches neither the request nor the committed state — because it is residue.

Correct model: RULE 3.60 makes DAT_O meaningful only under STB_O. Steps 4, 5 and 6 all say while qualified for this reason.

11. Interview Reasoning

Ten questions in a fixed order, and I stop at the first one whose answer does not make sense.

Is there a cycle, is a transfer presented inside it, and is it a write? CYC_O, STB_O within it, then WE_O asserted — and asserted for the whole presented interval, because a direction that flips mid-transfer means RULE 3.60's stability was broken.

What is the triple — address, data, byte lanes — and did any of it move? All three read only in qualified cycles; outside them they are residue. An address four times too large is a byte/word confusion. And I check all three even if only one looks wrong, because which ones drifted together tells me whether the master lost one register or its whole payload copy.

Which target? Per-slave STB_I or the select vector. None means unmapped; two means a decode fault.

When should this slave have committed? This is the step with no read equivalent, and the answer is not on the bus — it comes from the slave's declared policy. A slave that commits on the edge it acknowledges and one that commits a cycle earlier are both legal, and "the register changed at the wrong time" is unanswerable without knowing which.

How did it end? One of ACK_I, ERR_I, RTY_I. ERR is not a failure to diagnose — it may be a correct refusal of a read-only register, and a client that ignores status cannot tell that from a silent fault.

Did it release cleanly, with one completion?

What I am driving at is not "I recognise this bug" but "the method stopped at step N, so open that stage". And if all ten pass and the state is still wrong, that is itself the finding — the bus has told me everything it can, and the rest is the byte mask or the register decode inside the slave.

The one shortcut worth knowing. If the committed value equals DAT_O exactly while SEL_O was not all-ones, the slave ignored the mask. That is the rare write fault the bus trace settles on its own.

12. Understanding Check

13. Module 7 Complete

A Wishbone write is now fully traced, implemented, verified and diagnosable.

ChapterOwns
7.1the nine-stage path; the ownership reversal; the declared commit policy
7.2the payload path; the byte-lane mask; what a narrow write must not destroy
7.3termination versus commit; registered responses and lost context
7.4payload coherence while waiting; one commit, however long it takes
7.5the ten-step method; five traces; what a write trace cannot answer (this chapter)

What Module 7 deliberately did not do. It used one basic write throughout and left the wider subjects alone: Module 8 owns the cycle taxonomy — including its own treatment of the single write cycle alongside block and read-modify-write — Module 9 wait-state generation and performance, Module 10 errors, Module 11 retry, Module 12 address decoding, Module 13 byte selects.

Modules 6 and 7 now hold the two primitives. A read asks and receives; a write carries and commits. Everything Wishbone does beyond this point is built from those two — held together under one CYC_O, repeated back to back, or combined into an indivisible pair.

How do the single read and the single write compose into Wishbone's full set of bus cycles?

Module 8 — Bus Cycles answers it. It has not shipped yet, which is why it appears in bold rather than as a link. The full path is on the Wishbone curriculum index.

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.