Skip to content
VLSI Mentor

Wishbone · Module 15

Synchronization

Two locks that are real, correctly asserted and useless. Measured: protecting the read loses an update, and protecting the write loses the same one.

Chapter 15.1 ended with LOCK_O repairing a lost update. That is not the same as knowing what a lock has to cover.

Which clocks have to be protected, and what does a lock over the wrong ones buy?

1. Where the Specification Puts the Boundary

Two sentences settle the roles, and neither is in the RMW section.

From the BLOCK section, describing what CYC_O and LOCK_O each do:

CYC_O … can be used to request permission to access a shared resource from a local arbiter. To hold the access until the end of the cycle the LOCK_O signal must be asserted.

From LOCK_O's own description:

when asserted, indicates that the current bus cycle is uninterruptible. … Once the transfer has started, the INTERCON does not grant the bus to any other MASTER, until the current MASTER negates LOCK_O or CYC_O.

Read the last clause carefully: the hold ends when the master negates either signal. Not when the operation finishes, not when the write commits — when the master stops asserting. So the lifetime of the protection is entirely the master's to choose, and choosing it badly is this chapter's subject.

And there is a slave-side statement that bounds the claim. LOCK_I's description says a slave receiving it "is accessed by a single MASTER only, until either LOCK_I or CYC_I is negated." A single master — which Chapter 15.3 shows is a narrower promise than it sounds.

2. What Is Not Specified

No numbered rule in the Classic chapter constrains an arbiter. The nearest statement is advisory:

RECOMMENDATION 3.05Arbitration logic often uses CYC_I to select between MASTER interfaces. Keeping CYC_O asserted may lead to arbitration problems.

"Often." It describes practice, not obligation, and it warns in the direction Chapter 15.1 measured.

And the introduction delegates the whole question: "Arbitration methodology is defined by the end user (priority arbiter, round-robin arbiter, etc.)."

So the honest decomposition has three parts and only one is Wishbone's:

provided byin this module
the cycle structurethe specification — §3.4, RULE 3.85, RULE 3.25wb_incr_master
bus exclusion over an intervalthe interconnect, by policywb_owner2
resource exclusionthe system, by constructionChapter 15.3

3. Simulation — SIM C: The Lock Released After the Read

LOCK_O is asserted for the read half and released when the read is answered. The write half runs unlocked. Everything else is identical to Chapter 15.1's working case.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === SIM C - LOCK released after the read ===

    policy                HOLD_READ - LOCK asserted for the read half only
    counter before        10
    A read                10
    B read                10
    A wrote               11
    B wrote               11
    read phases served    2
    write commits         2
    counter after         11
    expected after two    12
    result                LOST UPDATE

    The lock was real, it was asserted, and it covered the
    wrong interval. Protecting the read protects nothing:
    the read had already happened when the value went stale.

Reading it

Both masters read 10 again. The lock was asserted, the arbiter honoured it, and the update was lost anyway.

The lock protected the read from interference — and a read does not need protecting. Reading a value is not an operation that can be corrupted by a concurrent reader; it is what happens afterwards that is fragile. By the time the lock was released the master had captured 10 and was committed to writing 11, and the other master was free to read the same 10.

This is the most instructive of the four policies because it is the one a careful engineer reaches for by accident. Protecting the access that touches the bus first feels like protecting the operation. The interval that matters starts at the read and ends at the write, and this lock covers the first instant of it.

4. Simulation — SIM D: The Lock Asserted for the Write Only

The mirror image. The read half runs unlocked; LOCK_O is asserted for the write half.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
  === SIM D - LOCK asserted for the write only ===

    policy                HOLD_WRITE - LOCK asserted for the write half only
    counter before        10
    A read                10
    B read                10
    A wrote               11
    B wrote               11
    read phases served    2
    write commits         2
    counter after         11
    expected after two    12
    result                LOST UPDATE

    A write lock serialises the writes. It cannot make the
    value they were computed from current, and both were
    computed before either write began.

Reading it

The same result, reached the other way round. Both masters read 10, both wrote 11, the counter moved by one.

And here the lock did exactly what a write lock can do: it serialised the writes. They did not collide, they did not interleave, and one of them landed cleanly after the other. That is real and it is worthless, because both were computed from a value that was stale before either lock was taken.

The formulation worth carrying away:

A write lock makes the write orderly. It cannot make the value the write was computed from current.

Which is why "we use LOCK_O" is not an answer to "is this operation atomic". Both SIM C and SIM D use LOCK_O. Both assert it correctly. Both lose the update.

5. Four Policies, One Table

Everything measured so far, with the interval each one actually covers:

policyCYC_O across both halvesLOCK_O coverscounter 10 →result
noneno — two cyclesnothing11lost update
CYC onlyyesnothing11lost update
read onlyyesthe read half11lost update
write onlyyesthe write half11lost update
whole operationyesread through write12correct

One row works. It is the one where the protection is continuous from before the read is observable until after the write commits — and the other four differ from it by where the coverage stops, not by whether a lock exists.

Read the second row against the fifth once more. They are the same master, the same arbiter, the same slave, the same stimulus. The second is the B3 RMW cycle exactly as §3.4 defines it.

6. What "Synchronization" Means Here, and What It Does Not

This module uses the word in one narrow sense and it is worth fencing off from the others.

What is being synchronised is access to one resource over one interval. That is a hardware ownership question with a hardware answer.

It is not a software synchronization primitive. A mutex, a semaphore, a condition variable are software constructs with blocking, queueing, priority and fairness semantics. Wishbone provides none of those — and the specification's phrase "indivisible semaphore operations" describes the primitive an RMW can be used to build, not a primitive it provides.

The relationship is worth stating exactly. A test-and-set built on an RMW cycle can be the hardware foundation of a software lock. The RMW gives you one indivisible read-then-write against one resource. Everything above that — what a waiter does, how contention is resolved, whether anyone starves — is software's, and none of it is on the bus.

And nothing here provides ordering between different resources. Two RMW operations on two counters are two independent operations. An operation that must see a consistent view of both is not expressible as one Wishbone cycle, and pretending otherwise is the most expensive mistake available in this area.

7. Failure Modes and Discriminating Evidence

Symptom: an operation uses LOCK_O and still loses updates.

Candidate causes. The lock covers the wrong interval — released after the read, or taken before the write.

Discriminating evidence. The clocks on which LOCK_O is asserted, against the clocks between the read's termination and the write's commit. Any uncovered clock in that span is the defect. The two masters' read values confirm it: both reading the same number means the gap was entered.

Likely RTL location: the master's lock generation, not the arbiter.

Symptom: the writes are ordered correctly and the total is still wrong.

Candidate causes. A write-only lock.

Discriminating evidence. Whether the two writes carry the same value. Correctly serialised writes of the same stale number are the signature. Ordering is not the problem and improving it will not help.

Symptom: the operation is correct in isolation and fails under load.

Candidate causes. A protection scheme with a small uncovered window that is only entered when another master happens to be waiting.

Discriminating evidence. An ownership timeline across the interval, which Chapter 15.4 records per clock. A single owner change inside the interval is conclusive, and it may occur in one run out of many.

Symptom: a design works with one arbiter and fails with another.

Candidate causes. The master relies on CYC_O retention for exclusion, and the first arbiter happened not to re-grant.

Discriminating evidence. Whether LOCK_O is asserted at all. If not, the design depends on arbiter behaviour that no rule requires — the introduction states arbitration methodology is the end user's — and it will vary between integrations.

8. Verification

The properties in Chapter 15.1 Section 9 cover this chapter, and P4 is the one under test.

p_lock_spans_operation asserts LOCK_O through the read half, the gap and the write half. It is true under the whole-operation policy and deliberately false under all four others — which is why it carries its scope in its comment. SIM C and SIM D are that property failing in two different places.

P5 — no release between the halves — is the CYC_O half of the same idea, and it separates an RMW cycle from two transfers with a data dependency.

Neither is specification-derived. §3.4 requires CYC_O across both halves and says nothing about LOCK_O at all, which is exactly why the four policies in Section 5 are all conformant.

9. Common Mistakes

"We use LOCK_O, so the operation is atomic."

Wrong mental model: the signal is the guarantee.

What is true: SIM C and SIM D both use it and both lose the update. The question is never whether a lock exists but which clocks it covers.

"Locking the write is enough — that's where the state changes."

Wrong mental model: protect the moment of modification.

What is true: the value was stale before the write began. A write lock serialises writes and cannot refresh what they were computed from.

"Locking the read is enough — that's where the value is captured."

Wrong mental model: protect the moment of observation.

What is true: a read needs no protection; what follows it does. Releasing the lock at the read's termination opens the interval at exactly the wrong moment.

"Read, then some unrelated work, then write is an RMW."

Wrong mental model: the dependency makes it one operation.

What is true: it is two transfers with a dependency. If ownership is released in between, the interval is not protected, and the specification's cycle is not what is being performed — §3.4 requires CYC_O across both halves.

"An RMW gives software a mutex."

Wrong mental model: the bus provides the primitive.

What is true: it provides one indivisible read-then-write against one resource. Blocking, queueing, fairness and starvation are software's, and the specification's "semaphore operations" phrase describes what can be built, not what is supplied.

10. Interview Reasoning

From before the read is observable until the write commits — continuously.

Why it starts at the read. The operation's correctness depends on the value the read returned still being current when the derived value lands. The moment another agent changes it, the derivation is invalid and the master has no way to detect that.

Why it ends at the commit, not at the write's presentation. A presented write that has not been acknowledged has changed nothing. Module 7's distinction applies unchanged — the operation is not complete until the slave commits.

Why "continuously" is the load-bearing word. SIM C protects the read and SIM D protects the write. Both are real locks, both are correctly asserted, and both lose the same update — because the interval has a hole in it either way.

The test to apply to any scheme: list the clocks between the read's termination and the write's commit, and ask whether protection covers every one. An uncovered clock is the defect, and it may be entered only occasionally, which is why the failure is intermittent under load.

11. Understanding Check

Because it was released at the moment the protection needed to begin.

The lock covered the read half. While it was held, no other master could be granted the bus — and nothing needed to be prevented during a read.

It was released when the read was answered. From that clock the master held a captured value of 10 and had not yet written anything. The other master was then free to read the same 10.

So the lock protected an interval in which nothing could go wrong, and stopped protecting at the instant things could.

The general shape is worth remembering: the danger in a read-modify-write is never the read or the write individually. It is the span between them, and a lock that does not cover that span is covering the wrong thing however correctly it is implemented.

12. What's Next

The interval is defined and three ways of covering it wrongly have been measured. The one that works protects continuously from the read to the commit.

Every experiment so far has assumed the only thing that could change the counter was another bus master.

What exactly is the resource, and who else can reach it?

Chapter 15.3 — Shared Resources measures a lost update in a system with a perfect lock, an arbiter that honours it, and no second master at all. 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.