Skip to content

UVM RAL · Chapter 7 · RAL Sequences

Bit Bash Sequence

The bit-bash sequence is the workhorse of register verification, the built-in sequence that finds the most bugs. Its mechanic is simple. For every accessible bit of every register, it writes just that one bit, reads the whole register back, and checks two things: that the bit followed its own access policy, and that no other bit moved. The whole-register read-back is the point. Checking only the written bit finds stuck bits and wrong access policy, but reading everything back also catches bit bleed, where one write disturbs a neighbour, and offset overlaps, where a write reaches more than the addressed register. This lesson walks how bit-bash exercises a single bit and why the full read-back matters, then breaks a real bit-bleed defect hidden by wrongly excluding the register to quiet a failure.

Foundation12 min readUVM RALBit Bashuvm_reg_bit_bash_seqbit bleedstuck bits

Chapter 7 · Section 7.3 · RAL Sequences

1. Why Should I Learn This?

Bit-bash is the single highest-yield register test — one setup, and it exercises every writable bit of every register and checks not just that the bit works but that it works without disturbing its neighbours. Understanding its mechanic — especially why it reads the whole register back after touching one bit — is what lets you read its results correctly, know what it does and does not cover, and, critically, resist the temptation to silence its failures by excluding registers instead of investigating them.

Learning how bit-bash walks a single bit, and why the whole-register read-back is the point, is what turns 'I ran bit-bash and it passed' into a defensible claim about register correctness. It builds on the built-in-suite overview (7.2) and the access-policy semantics it checks against (1.5), and it sharpens the exclusion discipline of 3.5 by showing what a wrongful exclusion hides.

2. Industry Story — the failure that got excluded instead of fixed

Late in a project, bit-bash starts failing on one control register: writing bit 4 reads back with bit 5 also changed. Under schedule pressure, an engineer 'fixes' the failing test by adding NO_REG_TESTS to that register — the failure disappears, the regression goes green, and everyone moves on. The exclusion attribute (3.5), which exists to keep memory-like sequences off registers that legitimately are not memory-like, has been used instead to hide a real defect.

Because what bit-bash actually found was bit bleed: writing bit 4 disturbed bit 5, because in the RTL those two 'separate' control bits had been mistakenly mapped to overlapping logic — a real hardware bug that would misconfigure the block in the field. Bit-bash caught it precisely because it reads the whole register back after writing one bit, so it saw bit 5 move when only bit 4 was touched. Excluding the register did not make the hardware correct; it made the test stop looking. The bug shipped. The post-mortem finding: bit-bash's whole-register read-back caught a genuine bit-bleed defect; excluding the register with NO_REG_TESTS to quiet the failure did not fix the hardware, it hid the finding — exclusions are for registers that are legitimately not RW, never for silencing a failure you have not explained.

3. Concept — write one bit, read the whole register, check two things

For each register, and for each of its accessible bits (bit-bash consults the access policy and skips bits that are not writable — RO, reserved — 1.5), the bit-bash sequence does the following. It writes a pattern that toggles just that one bit (write it to 1, later to 0 — a walking pattern), and after each write it reads the entire register back and checks two independent things:

  1. The bit itself followed its access policy — a plain RW bit now holds what was written, a W1C bit cleared, a RO bit did not change (1.5). This catches stuck bits and wrong access policy (a bit the spec says is writable that is not, or vice-versa).
  2. No other bit moved — every bit except the one under test reads back unchanged. This is the subtle, high-value check: it catches bit bleed (writing one bit disturbed a neighbour) and offset overlaps (the write reached a register other than the one addressed — 1.2, 3.5).

The second check is why bit-bash reads the whole register, not just the bit it wrote — and it is what makes the sequence far more than a stuck-bit test. Here is the operation on a single RW bit:

Bit-bash on one bit: write bit=1, read whole register, check bit and neighbours; write bit=0, read, checkbit_bash sequvm_reg (model)DUT registerwrite bit i = 1 (others held)write bit i =1 (others…frontdoor writeread WHOLEregisterall bitscheck bit i == 1 AND every other bit unchangedcheck bit i == 1 ANDevery other bit…write bit i = 0read WHOLEregistercheck bit i == 0 AND others unchangedcheck bit i == 0AND others…
Figure 1 — bit-bash on one RW bit i of a register. Write bit i = 1 (others held), read the WHOLE register back, check bit i == 1 AND every other bit unchanged; then write bit i = 0, read the whole register, check bit i == 0 AND others unchanged. The 'others unchanged' check on a whole-register read-back is the point: it catches bit bleed (a neighbour moving) and offset overlaps, not just stuck bits. Repeat for every accessible bit of every register.

4. Mental Model — writing one bit while watching all the others

5. Working Example — running bit-bash and reading its check

Running bit-bash is a few lines (7.2); the value is in understanding the check it performs:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Run the bit-bash sequence over the whole model (after excluding genuinely non-RW registers, 3.5).
uvm_reg_bit_bash_seq bash = uvm_reg_bit_bash_seq::type_id::create("bash");
bash.model = reg_model;
bash.start(bus_sqr);
// For every accessible bit of every register, bit-bash internally does the equivalent of:
//   write ONE bit, read the WHOLE register, check that bit followed policy AND no other bit moved.
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// What the whole-register read-back check is doing, conceptually, for bit i of register R:
foreach (bit_i) begin
  R.write(status, (current_value ^ (1 << bit_i)), UVM_FRONTDOOR); // toggle just bit i
  R.read(status, readback, UVM_FRONTDOOR);                        // read the WHOLE register
  // check 1: bit i changed per its access policy (RW toggled, W1C cleared, RO held) -> stuck-bit / wrong-access
  // check 2: readback ^ expected has ZERO bits set OUTSIDE bit i        -> bit-bleed / offset-overlap
end
// A failure in check 2 means writing bit i disturbed another bit -> a SIDE EFFECT to explain, not to exclude.

The whole-register read-back is the sequence's signature: it is why bit-bash finds not just stuck bits but collateral movement — and why a failure deserves an explanation, not an exclusion.

6. Debugging Session — a real defect hidden by a wrongful exclusion

1

Bit-bash's whole-register read-back caught real bit bleed; excluding the register to quiet the failure hid a hardware defect instead of fixing it

EXCLUDE HIDES A REAL BUG
Buggy Code
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// bit-bash failed on ctrl_reg: writing bit 4 read back with bit 5 also set. Under pressure, someone
// 'fixed' the failing regression by excluding the register:
uvm_resource_db#(bit)::set({"REG::", ctrl_reg.get_full_name()}, "NO_REG_TESTS", 1, this);
// BUG: NO_REG_TESTS is for registers that are legitimately not RW (W1C/RC/WO/volatile, 3.5).
// ctrl_reg is a plain RW control register -- the failure was REAL. Excluding it hides a hardware defect.
Symptom

Before the exclusion: bit-bash reports a failure on ctrl_reg — writing bit 4 reads the register back with bit 5 also changed, even though bit 5 was never written. After the exclusion: the failure vanishes, the regression goes green, and ctrl_reg is silently no longer tested at all. The 'symptom' after the wrongful fix is the absence of a symptom — a real defect made invisible. In silicon (or later integration), the block misconfigures because setting control bit 4 also flips bit 5, a behaviour no test now covers.

Root Cause

Two layers. The hardware root cause is bit bleed: in the RTL, control bits 4 and 5 of ctrl_reg were mistakenly mapped to overlapping logic (a shared flop, or a decode that sets both), so writing bit 4 disturbs bit 5. Bit-bash caught it because it reads the whole register back after writing one bit — its 'no other bit moved' check saw bit 5 move when only bit 4 was written; a per-bit-only test would have missed it entirely. The process root cause is the misuse of the exclusion mechanism: NO_REG_TESTS exists to keep memory-like sequences off registers that are legitimately not RW (W1C/RC/WO/volatile — 3.5), where a bit-bash failure would be a false failure. ctrl_reg is a plain RW register, so its bit-bash failure was true. Excluding it did not make the hardware correct — it made the sequence stop looking, converting a caught defect into a shipped one.

Fix

Remove the exclusion, treat the bit-bash failure as the real finding it is, and explain the collateral movement: trace in the RTL why writing bit 4 disturbs bit 5, and fix the shared logic / decode so the two bits are independent (or, if the spec genuinely intends them coupled, correct the spec and the model — but that is rare and must be deliberate, not silent). Re-run bit-bash to confirm the register now passes with the two bits independent. The rule the bug teaches: a bit-bash failure on an RW register is a real defect — usually bit bleed or an offset overlap, surfaced by the whole-register read-back — and the response is to explain and fix it, never to quiet it with an exclusion. Reserve NO_REG_TESTS strictly for registers that are legitimately not RW (3.5); every other exclusion is a finding you chose not to look at.

7. Common Mistakes

  • Excluding a register to silence a bit-bash failure. On an RW register the failure is real — usually bit bleed or overlap. Explain it; do not hide it with NO_REG_TESTS.
  • Thinking bit-bash only finds stuck bits. Its whole-register read-back also finds bit bleed and offset overlaps — the collateral-movement checks.
  • Forgetting to exclude genuinely non-RW registers. W1C/RC/WO/volatile registers do false-fail bit-bash and should be excluded (3.5) — the honest use of exclusion.
  • Reading a failure as 'this bit is broken' only. Often it is 'writing this bit moved another bit' — a side effect pointing at shared logic or an overlap.
  • Running bit-bash frontdoor with a broken map. Overlaps show up as bit-bash failures; that is bit-bash doing its job (3.5), not a sequence bug.

8. Industry Best Practices

  • Run bit-bash as core register verification. It is the highest-yield built-in sequence; one setup covers every writable bit of every register.
  • Treat every bit-bash failure on an RW register as a real defect. Explain the collateral movement (bit bleed, overlap) before doing anything else.
  • Reserve exclusions for legitimately non-RW registers. NO_REG_TESTS for W1C/RC/WO/volatile (3.5); never to quiet an unexplained failure.
  • Review exclusion lists as spec claims. Every excluded register asserts 'this is not RW' — audit that the claim is true, not a hidden failure.
  • Add targeted policy tests for excluded registers. Bit-bash skips them, so cover W1C/RC/WO behaviour with dedicated sequences (3.5).

9. Interview / Review Questions

10. Key Takeaways

  • The bit-bash sequence (uvm_reg_bit_bash_seq) writes one accessible bit of a register, reads the whole register back, and checks two things: the bit followed its access policy and no other bit moved.
  • The whole-register read-back is the point — it catches not just stuck bits and wrong access policy but bit bleed (a write disturbing a neighbour) and offset overlaps, defects a per-bit-only test misses.
  • Read a bit-bash failure as a side-effect story — 'writing bit i moved bit j' points at shared RTL logic or an address overlap; a failure on an RW register is a real defect to explain and fix.
  • Never silence a bit-bash failure with an exclusion. NO_REG_TESTS is only for legitimately non-RW registers (W1C/RC/WO/volatile, 3.5); using it to quiet an unexplained failure hides a real bug.
  • Bit-bash is the highest-yield built-in sequence for RW storage and bit-independence, but is blind by design to side-effecting semantics, functional effect, reset values, and addressing cross-checks — those are other members of the suite (7.2).