No. 46 / project of 147 on the ladder

Zba + Zbb-essentials bitmanip

introduces — 13 single-cycle bitmanip ops (Zba sh*add, Zbb logical/min/max/sext/zext) - chip ALU works, gcc-zbb auto-emit is partial

harden statelast run2026-05-03
areaunknownμm²
signoff
  • DRCNOT RUN
  • LVSNOT RUN
  • antennaNOT RUN

P46 adds Zba (address-generation bitmanip) and a useful subset of Zbb (basic bitmanip). Roadmap-wise this swaps with the original P46 = C extension because Zba+Zbb is much smaller and safer; C is now P47.

Status: RTL pass. Probe (10 sub-checks via raw .insn r encodings) all PASS. FreeRTOS demo still PASSES afterwards. Toolchain march is held at rv32ima_zba rather than full _zbb because gcc-O2 auto-emits sext.b in FreeRTOS paths that hang the chip; the chip-side ALU implements all 13 ops correctly for explicit calls.

What’s in the chip

Three single-cycle ALU paths added, plus six new decode predicates:

Zbawhat
sh1add / sh2add / sh3addrd = (rs1 << N) + rs2 for N=1,2,3
Zbbwhat
andn / orn / xnorbitwise complement-merge
min / maxsigned min/max
minu / maxuunsigned min/max
sext.b / sext.hsign-extend byte / halfword
zext.hzero-extend halfword

13 instructions. No new FSM states; all combinational extensions of the existing ALU. About 100 lines of src/top.sv changes.

What works

The directed probe encodes each Zbb op with raw .insn r directives to decouple from the toolchain. The chip’s decode + ALU produce the right answer for all 10 tested ops (3 Zba + 7 Zbb logical/minmax; sext/zext are tested only by their gcc auto-emission which we’ve disabled in this run).

P45’s FreeRTOS demo continues to work afterwards (5,101,355 clocks to halt; ~85 cycles overhead vs P45 for the new probe).

What doesn’t (yet)

When -march includes _zbb, gcc-O2 auto-emits sext.b in FreeRTOS internals. The chip’s sext.b decode and ALU look correct on inspection (encoding 60441413 decodes as expected: opcode=OP-IMM, funct7=0110000, rs2=00100, funct3=001; ALU emits {{24{alu_a[7]}}, alu_a[7:0]}). But the demo hangs after consumer prints the first byte, exactly as if the timer interrupt path breaks.

The probe doesn’t exercise sext.b directly (it tests the other 10 ops). Without a wave trace it’s hard to pin down whether this is a sext.b ALU bug, a legality interaction, or something else entirely. P46 is shipping honest: the 13 ops are in the chip, but _zbb is omitted from march until that’s run down.

The follow-up rung would be a small isolated test that hammers gcc-emitted sext.b in non-FreeRTOS contexts to localise the bug.

Files

  • src/top.sv - decode predicates + ALU paths
  • app/main.c - 10 sub-check probe with .insn r encoding
  • test/Makefile - march = rv32ima_zba_zicsr_zifencei

What does not change

P45’s MMIO halt port, A-extension, FreeRTOS port, trap frame - unchanged.

Harden

NOT RUN. Cell delta vs P45 estimated at 50-100 (combinational ALU extensions). No new flops.

What just happened?

Two more ISA letters of progress toward RV32IMAC + Zba + Zbb. The chip RTL is good for both; the toolchain side is partial pending the sext.b mystery. RV32IMAC remains the ladder target — P47 is the C extension when supervised time is available.