Skip to content
VLSI Mentor

Wishbone · Module 19

Peripheral Integration

Four register access policies in one bank, a side effect that must fire exactly once under wait states, two policies inside one 32-bit word, and a six-checker negative-control gate in which none of the six defects is a protocol violation.

Chapter 19.4 built the seam where a core meets the bus. This one builds the seam where the bus meets a register, and it is the boundary people most often assume does not exist.

Wishbone tells you what a legal WRITE cycle looks like. What does it tell you about what the register does when you write it?

Nothing. Not one word. And that is the correct division of labour — but it means RULE 2.00 is load-bearing rather than ceremonial:

"Each WISHBONE compatible IP core MUST include a WISHBONE DATASHEET as part of the IP core documentation."

1. A Register Is Not a Memory Word

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ─────────────────────────────────────────────────────────────────────────
// wb_csr_bank — SEAM 2, with every access policy in one place.
//
// A register is not a memory word. It is a set of FIELDS, each with its own
// rule about what a read returns and what a write does, and the interconnect
// knows none of that. Everything below is LOCAL REGISTER POLICY.
//
//   offset 0  SCRATCH   RW    plain storage. SEL_O honoured per byte.
//   offset 1  IDENT     RO    constant + an access counter. A write is
//                             answered ERR_O.
//   offset 2  FLAGS     W1C   bits are SET by hardware (set_i) and CLEARED
//                             by writing a 1 to them. Writing 0 does
//                             nothing. This is not "just a write".
//   offset 3  COMMAND   WO    a write fires a one-clock side effect. A read
//                             returns zero, which is a choice and is stated.
//

Four registers, four different answers to "what happens when I write this". A bus that carries all four identically is doing its job correctly; the difference is entirely inside the slave.

One Wishbone write cycle reaching four registers with four different local policies. The identical cycle, carrying CYC, STB, WE, ADR, SEL and DAT, arrives at a register bank. Inside, offset zero is a read-write scratch register that stores the data per selected byte lane, offset one is a read-only identity register that answers a write with ERR_O, offset two is a write-one-to-clear flag register that clears only the bits written as one and is set independently by hardware, and offset three is a write-only command register that fires a one-clock side effect and reads back as zero. The bus is the same in every case; only the slave's reaction differs.one WRITE cycleCYC STB WE ADR SELDATdecodeadr[1:0]SCRATCH RWstores, per laneIDENT ROanswers ERR_OFLAGS W1Ca 1 clears, a 0 doesnotCOMMAND WOfires once, readszero12

Every arrow leaving the decoder carries the same cycle. Nothing about the Wishbone transfer distinguishes the four destinations. The entire difference is local register policy, and it is documentation before it is RTL.

2. SIM H — The Policy Matrix, Against a Stated Expectation

Each row below was checked in the simulator against an expectation written before the access was issued. The peripheral leg inserts two wait states, so none of these is a single-clock transfer.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === SIM H - four access policies, one register bank ===
    the CSR bank at byte 0x3000 decodes only two offset bits,
    which is B3's Partial Address Decoding: "each SLAVE
    decodes only the range of addresses that it requires...
    The remaining address bits are decoded by the
    interconnection system."  Two wait states on this leg.

      access                 pol   result   expected     verdict
      write SCRATCH word     RW    ok       0x11223344  (write)      PASS
      read  SCRATCH          RW    ok       0x11223344  0x11223344   PASS
      write SCRATCH byte+1   RW    ok       0x1122ee44  (write)      PASS
      read  SCRATCH again    RW    ok       0x1122ee44  0x1122ee44   PASS
      write IDENT            RO    ERR      0x00000000  (write)      PASS
      read  IDENT            RO    ok       0xc5b00001  0xc5b00001   PASS
      read  COMMAND          WO    ok       0x00000000  0x00000000   PASS

Row three is the one to linger on. A byte write at offset +1 changed 0x11223344 into 0x1122ee44 — one lane, in place. That requires the adapter to have generated SEL_O = 0010 and the slave to have honoured it. Both halves of that have to be right, and they are on opposite sides of the bus from each other.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
      if (ack_o && we_i) begin
        case (off)
          // SEL_O honoured per byte lane. A byte write to offset 0 must
          // leave the other three lanes alone, and Chapter 19.3 measures
          // an adapter that makes that impossible.
          2'd0: for (b = 0; b < SW; b = b + 1)
                  if (sel_i[b]) scratch_q[b*8 +: 8] <= dat_i[b*8 +: 8];
          // WRITE-1-TO-CLEAR. Writing a 0 to a set bit leaves it set;
          // writing a 1 clears it. A hardware set on the same clock wins,
          // and that collision rule is stated rather than left to chance.
          2'd2: if (sel_i[0]) flags_q <= (flags_q & ~dat_i[7:0]) | set_i;
          default: ;
        endcase
      end

3. Write-One-to-Clear Is Not "Just a Write"

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    FLAGS, offset 8, write-1-to-clear
      hardware set bits 3 and 1      flags now 0x0a
      read FLAGS                     0x0000000a
      write 0x02 (clear bit 1)       flags now 0x08
      write 0x00 (a plain write)     flags now 0x08
      -> write-1-to-clear is not just a write. Writing zero
         to a set bit leaves it set, which is the whole
         point: a read-modify-write of this register cannot
         accidentally clear a flag it did not know about.

Writing zero to a set bit left it set. That is the entire point of the policy: a read-modify-write of this register cannot accidentally clear a flag it did not know about, which is what would happen if FLAGS were plain storage and two pieces of software touched it.

And the flags are set by hardware while the bus is doing something else, so there is a collision to resolve — a flag can be set on the same clock the core writes a one to clear it. The GPIO slave writes that rule as a single expression, deliberately:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ── THE BIT THAT IS NOT A REGISTER ──────────────────────────────────────
// The edge flags are set by the PINS. Nothing on the bus causes them and
// nothing on the bus prevents them. A flag can be set on the same clock
// the core writes a 1 to clear it, and the rule for that collision is
// written as one expression - hardware wins - because two non-blocking
// assignments to one flag would silently keep the clear and lose the
// event.

Two non-blocking assignments to one flag would silently keep the clear and lose the event. This is the same class of defect as Chapter 16.3's counter bug, and the fix is the same: one assignment, one expression, hardware wins.

4. A Side Effect Must Fire Exactly Once

This is the defect that wait states create and that a zero-wait-state testbench cannot find.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  logic cmd_hit;
  assign cmd_hit    = we_i && (off == 2'd3);
  assign cmd_fire_o = FIRE_EVERY_CLK ? (xfer && cmd_hit)
                                     : (ack_o && cmd_hit);
  assign cmd_value_o = dat_i;
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    COMMAND, offset 12, a side effect with two wait states
      one write, phase held 3 clocks  commands fired 1
      -> fired on the ANSWERED clock, once. A slave that
         acted on every presented clock would have fired
         three commands from one write.

One write, phase held for three clocks, one command fired. With FIRE_EVERY_CLK the side effect keys off xfer — the request being presented — rather than ack_o, the request being accepted, and one write becomes three commands.

5. Two Policies Inside One 32-Bit Word

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// ── WHY THE MASK IS IN THE SAME REGISTER AS THE FLAGS ───────────────────
// So that one 32-bit access can read both, and so that the byte lanes have
// different policies within one word: SEL_O lane 0 is W1C, lane 1 is RW.
// A slave that ignores SEL_O cannot implement that, and an adapter that
// cannot express a byte write makes it unreachable. Chapter 19.4 measures
// exactly that failure.
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    GPIO, two policies inside one 32-bit word
      write mask 0xF0 into lane 1    irq line 0
      pin 4 rises                    flags 0x10  irq 1
      read ISTAT                     0x0000f010
      byte write 0x10 to lane 0      flags 0x00  irq 0
      -> lane 0 is write-1-to-clear and lane 1 is plain RW,
         in the same register. An adapter that cannot
         express a byte write cannot reach either of them
         separately - which is what SIM E measured.

Read 0x0000f010. Lane 1 holds the interrupt mask 0xF0, written by an earlier access; lane 0 holds the edge flag 0x10, set by a pin. One register, two policies, two lanes — and the byte write of 0x10 to lane 0 cleared the flag and dropped the interrupt line without disturbing the mask.

This is why Chapter 19.4 §3 matters at this seam. An adapter that asserts all four lanes on every access cannot reach either field separately. The register is not exotic; packing a mask next to its flags is the normal thing to do, and it is normal precisely because SEL_O exists.

6. What the DATASHEET Has To Say

RULE 2.15 enumerates what a datasheet must state. Four of its items are the whole of this chapter:

itemwhat must be documentedwhy it cannot be inferred
4how a master reacts to ERR_IPERMISSION 3.20: "This specification does not dictate what the MASTER does in response to [ERR_I]."
4the conditions under which a slave generates ERR_Oa slave may refuse for any local reason — a read-only register, an unimplemented offset
7the port size — 8, 16, 32 or 64-bitnothing on the wires says how wide the other end thinks it is
8the granularitySEL_O's array boundaries are the granularity; get it wrong and every sized access is wrong

A slave that does not state its granularity cannot be integrated, because there is no way to know what SEL_O bit 2 means to it. That is not a rule about silicon. It is a rule about a document, and it is the specification acknowledging that the gap between two conformant interfaces is closed by writing, not by wiring.

7. The Negative-Control Gate

A checker that has only ever passed has not been shown to check anything. Six checkers are run against seven systems: the correct one, and six that differ from it by exactly one parameter.

Every one of those six parameters is a decision somebody could plausibly make, and not one of them is a Wishbone protocol violation.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === NEGATIVE-CONTROL GATE ===
    one stimulus, seven systems. Each broken system differs
    from the correct one by exactly one parameter. Every
    parameter is a decision somebody could plausibly make
    and none of them is a Wishbone protocol violation.

    checker                       corr DROP SEL ERR ALIAS FIRE IRQ
    ONE TRANSFER PER REQUEST      PASS FAIL PASS PASS PASS  PASS PASS
    SEL MATCHES ACCESS SIZE       PASS PASS FAIL PASS PASS  PASS PASS
    ERROR REACHES THE CORE        PASS PASS PASS FAIL PASS  PASS PASS
    REGISTER DECODE IS EXACT      PASS PASS PASS PASS FAIL  PASS PASS
    SIDE EFFECT FIRES ONCE        PASS PASS PASS PASS FAIL  FAIL PASS
    INTERRUPT REACHES THE CORE    PASS PASS PASS PASS PASS  PASS FAIL

    raw numbers behind those verdicts
      rig              LSreq LSxf drop SELv traps rd12       cmds irqs
      correct            10   10    0    0    1   0x00000000  1    1
      REQ_DROP           10   10    3    0    1   0x00000000  1    1
      SEL_IGNORED        10   10    0    8    1   0x00000000  1    1
      ERR_SWALLOWED      10   10    0    0    0   0x00000000  1    1
      CSR_ALIAS          10   10    0    0    2   0xc5b00001  0    1
      FIRE_EVERY_CLK     10   10    0    0    1   0x00000000  3    1
      IRQ_VIA_BUS        10   10    0    0    1   0x00000000  1    0

    scratch register after the three sized writes
      correct        0xbeef7744
      SEL_IGNORED    0x77777777
      (every other rig writes the scratch correctly)

    CHECKERS REQUIRED:              >= 5
    CHECKERS DECLARED:              6
    CHECKERS PASSING THE CORRECT DUT:
      6/6 (any failure here would be an error below)
    EACH CHECKER FAILS ITS OWN TARGET:
      6/6

Six checkers, six targets, six detections, and every checker passes the correct system. That is the gate.

The interesting cell is not on the diagonal

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    READ THE MATRIX, NOT THE DIAGONAL.
    Five of the six defects are caught by exactly one
    checker and are invisible to the other five. The SEL
    checker does not notice a swallowed error; the trap
    checker does not notice a missing interrupt; not one of
    them would have found the system broken on its own.

    CSR_ALIAS is the exception and it is the most useful
    cell in the table. It fails TWO checkers - decode and
    side effect - because address decode sits upstream of
    everything the slave does. The COMMAND write never
    reached COMMAND; it landed on IDENT, which is read-only,
    so the bank answered ERR and the core took a second trap
    it had no reason to expect. One wrong bit in a decoder
    produced a missing side effect and a spurious error,
    and neither symptom names the cause.

CSR_ALIAS trips two checkers, and the second one is not obviously related to the first. The decoder ignored one address bit, so a write intended for the write-only COMMAND register landed on the read-only IDENT register instead. The bank did the right thing — answered ERR_O, per its own documented policy — and the core took a trap it had no reason to expect, while the side effect the software was waiting for never happened.

Neither symptom names the cause. A missing side effect and a spurious error are what you would see on a logic analyser; one wrong bit in an address decoder is what you would have to deduce.

8. The Integration Audit

Every number below comes from the single run published in Chapter 19.1 §6 — boot, RAM fill, DMA copy, concurrent core traffic, timer interrupt, interrupt service. Nothing was re-stimulated to make a table tidy.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === SIM J - the integration audit ===
    every number below comes from the run above. Nothing
    was re-stimulated to make a table look tidy.

    SEAM 1 - the core side, per port
      port          requests  transfers  answers
      instruction      10        10         10
      load/store       18        18         18
      -> ONE REQUEST, ONE TRANSFER, ONE ANSWER, both ports.

      seam violations   dropped moved  SEL  ADDR  trap
      instruction          0      0     0    0     0
      load/store           0      0     0    0     0

      stall clocks (core not ready)   IF 0   LS 0
      wait  clocks (bus not ready)    IF 21   LS 40
      -> counted separately and never summed. They are two
         different parties refusing to proceed.

    SEAM 2 - the bus side
      shared-bus clocks              614
      clocks a cycle was open        66
      ownership: IF 20  LS 38  DMA 8
      ACK terminations               36
      ERR terminations               0
      transfers seen by both seams   28
      clocks the DMA was busy but did not own the bus  10

      CONSERVATION:  28 core transfers + 8 DMA transfers
                  =  36, and the bus terminated 36 times.
      -> every transfer any master started was terminated
         exactly once, and nothing terminated that nobody
         started. The DMA's 4 words are 8 transfers
         because a copy is a read and then a write.

Three things in that audit are worth naming.

One request, one transfer, one answer, both ports. Ten and eighteen, matched three ways. A seam that invents or destroys work fails here first.

Stall and wait are on separate lines with a note saying why. Twenty-one wait clocks on the fetch port and forty on the data port, against zero stall clocks on both. Adding them would produce a number that describes nothing — Chapter 19.3 §5 measured why.

The conservation check balances. Twenty-eight core transfers plus eight DMA transfers against thirty-six terminations. The DMA's four words are eight transfers because a copy is a read and then a write — and a system in which that arithmetic does not close has either lost a termination or delivered one nobody asked for.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
    SLAVES
      ROM reads 10   refused 0
      RAM writes 8
      timer expiries 1   reloads 1
      GPIO edges 0
      CSR commands 0   writes refused 0
      CSR scratch  0x5a5a0005
      DMA words    4

    THE CORE'S VIEW
      traps taken   0
      interrupts    1
      -> the trap count is a seam-1 number and the interrupt
         count is neither seam's. B3 describes one of these
         mechanisms and names neither.

The last line is the module. The trap count is a seam-1 number. The interrupt count is neither seam's. B3 describes one of these mechanisms and names neither.

9. What To Take Away

the questionwho answers it
the cycleis this a legal Wishbone transfer?B3, completely and unambiguously
seam 1does the core's request survive becoming one?you, and the core's README
seam 2what does the register do when it arrives?you, and RULE 2.00 says: in writing

The bus was never the hard part. Eighteen chapters settled it. The two boundaries B3 declines to describe are where the defects in this module live, and all six of them are legal.

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.