P33 keeps the P32 RV32IM platform and fixes the setup timing failure by making
multiply multi-cycle. P32 already moved divide/remainder out of the single-cycle
path; P33 does the same kind of thing for MUL, MULH, MULHSU, and MULHU.
Status: hardened, with residual electrical DRV cleanup left. LibreLane run
RUN_2026-05-01_13-44-20produced final GDS and passed Magic DRC, KLayout DRC, LVS, antenna, setup timing, and hold timing. Max slew and max cap still report violations, so this is not a perfectly clean electrical checkpoint.
The Result
Run it:
make -C projects/33_rv32im_timing_fix/test clean all
Result: PASS
| check | result |
|---|---|
Build linked rv32im_zicsr runtime ELF | PASS |
| UART-load compiled image | PASS |
Execute C *, /, and % through RV32M | PASS |
Execute mulh, mulhsu, and mulhu | PASS |
| Check divide-by-zero and overflow edge cases | PASS |
MMIO UART writes M, T, E | PASS |
| MMIO timer interrupt visible to C | PASS |
| External interrupt visible to C | PASS |
Halt with x5 = 1 | PASS |
ACT4/Sail rv32i/I: PASS=39 FAIL=0 NOT RUN=0
ACT4/Sail rv32i/M: PASS=8 FAIL=0 NOT RUN=0
Harden Result
LibreLane flow: PASS
| harden check | result |
|---|---|
| Run directory | projects/33_rv32im_timing_fix/librelane/runs/RUN_2026-05-01_13-44-20 |
| Final GDS | projects/33_rv32im_timing_fix/librelane/runs/RUN_2026-05-01_13-44-20/final/gds/top.gds |
| Metrics | projects/33_rv32im_timing_fix/librelane/runs/RUN_2026-05-01_13-44-20/final/metrics.json |
| Magic DRC | PASS (0 errors) |
| KLayout DRC | PASS (0 errors) |
| LVS | PASS (0 errors) |
| Antenna | PASS (0 violations) |
| Setup timing | PASS (0 violations, worst setup slack 4.031 ns) |
| Hold timing | PASS (0 violations, worst hold slack 0.110 ns) |
| Max slew | FAIL (2241 violations, only slow corners) |
| Max cap | FAIL (291 violations) |
For comparison, P32 hardened with worst setup slack -7.798 ns and 474
setup violations. P33 closes setup at the same 40 ns clock target.
What Changed
The supported instruction set did not expand; the implementation changed:
| instruction | P33 implementation |
|---|---|
MUL | 32-cycle shift/add, low 32 bits |
MULH | 32-cycle shift/add, high signed x signed word |
MULHSU | 32-cycle shift/add, high signed x unsigned word |
MULHU | 32-cycle shift/add, high unsigned x unsigned word |
DIV, DIVU | 32-cycle restoring divider |
REM, REMU | 32-cycle restoring divider remainder |
RISC-V edge cases are included: divide by zero, signed overflow on
0x80000000 / -1, and the corresponding remainder behavior.
misa still reports IM: 0x40001100.
Runtime Shape
The runtime is the same RV32IM probe shape from P32. Ordinary C operators force
mul, div, divu, rem, and remu into the compiler output. Inline
assembly covers mulh, mulhsu, and mulhu, because C has no direct 32-bit
high-product operator.
The generated runtime binary is 888 bytes in the current build.
Scope
This is not a full RISC-V compliance claim. The recorded official-test coverage
is the scoped ACT4/Sail rv32i/I and rv32i/M batches listed above.
Still unsupported: atomics, compressed instructions, supervisor mode, vectored
mtvec, delegation CSRs, satp, an MMU, and official full compliance
packaging.