P36 keeps the P35 RV32IM platform and changes one thing: signed divider
writeback gets its own state. The divider now stores the raw final
quotient-or-remainder, then applies the final sign correction in S_DIV_SIGN
one cycle later.
Status: hardened and DRV-clean. LibreLane run
RUN_2026-05-02_21-18-57produced final GDS and passed Magic DRC, KLayout DRC, LVS, antenna, routing DRC, setup timing, hold timing, max slew, max cap, and max fanout in the recorded metrics.
The Result
Run it:
make -C projects/36_rv32im_divider_sign_stage/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
ACT4/Sail rv32i/Zicsr: FAIL (PASS=0 FAIL=6 NOT RUN=0)
ACT4/Sail rv32i/Zifencei: FAIL (PASS=0 FAIL=1 NOT RUN=0)
Full RISC-V compliance: PARTIAL
Harden Result
LibreLane flow: PASS
| harden check | result |
|---|---|
| Run directory | projects/36_rv32im_divider_sign_stage/librelane/runs/RUN_2026-05-02_21-18-57 |
| Final GDS | projects/36_rv32im_divider_sign_stage/librelane/runs/RUN_2026-05-02_21-18-57/final/gds/top.gds |
| Metrics | projects/36_rv32im_divider_sign_stage/librelane/runs/RUN_2026-05-02_21-18-57/final/metrics.json |
| Magic DRC | PASS (0 errors) |
| KLayout DRC | PASS (0 errors) |
| LVS | PASS (0 errors) |
| Antenna | PASS (0 net violations, 0 pin violations) |
| Routing DRC | PASS (0 errors) |
| Setup timing | PASS (0 violations, worst setup slack 5.903 ns) |
| Hold timing | PASS (0 violations, worst hold slack 0.070 ns) |
| Max slew | PASS (0 violations) |
| Max cap | PASS (0 violations) |
| Max fanout | PASS (0 violations against signoff limit 13) |
The comparison to P35 is the useful bit:
| metric | P35 | P36 |
|---|---|---|
| Worst setup slack | 8.048 ns | 5.903 ns |
| Worst hold slack | 0.100 ns | 0.070 ns |
| Max slew violations | 13 | 0 |
| Max cap violations | 1 | 0 |
| Max fanout violations | 0 | 0 |
| Standard-cell area | 188652 um^2 | 191659 um^2 |
| Standard-cell count | 26883 | 27223 |
The fanout cleanup is backend-only. Place-and-route reads p36.sdc with a
fanout target of 12, nudging OpenROAD to split high-load nets earlier.
Post-PnR STA reads p36_signoff.sdc with a fanout limit of 13, matching the
P35 signoff target. That removes the previous 14-load branch without changing
the RTL or the instruction behavior.
What Changed
The supported instruction set is the same as P35:
| instruction family | status |
|---|---|
| RV32I base integer instructions | PASS in scoped ACT4/Sail rv32i/I |
MUL, MULH, MULHSU, MULHU | PASS in scoped ACT4/Sail rv32i/M |
DIV, DIVU, REM, REMU | PASS in scoped ACT4/Sail rv32i/M |
| Zicsr machine-mode CSR subset | runtime subset works, ACT4 rv32i/Zicsr is FAIL |
| Zifencei | ACT4 rv32i/Zifencei is FAIL |
The implementation adds S_DIV_SIGN after the final divider iteration. That
state writes alu_y_q from registered raw divide output plus a registered
sign-correction bit, instead of doing the sign fix in the same cycle that the
divider decides it is done.
The behavioral cost is tiny but visible: the directed runtime takes 1620
clocks instead of P35’s 1616, and the four ACT4 divide/remainder tests each
pick up one extra cycle. Multiply tests are unchanged.
Scope
This is not a full RISC-V compliance claim. The recorded official-test coverage
is now a partial ACT4/Sail sweep: rv32i/I and rv32i/M pass, while the first
CSR and instruction-fence extension probes fail.
Still unsupported: atomics, compressed instructions, supervisor mode, vectored
mtvec, delegation CSRs, satp, an MMU, and official full compliance
packaging.
The point of the addendum is to set up the next projects. Zicsr is the first
real closure target: the ACT4 tests for csrrw, csrrs, csrrc, and their
immediate forms all time out in the self-check harness. Zifencei is the next
small extension-level failure: fence.i needs an explicit architectural answer
instead of riding along with the base fence pass.
What We Learned
P36 confirms that the P35 slew/cap tail was sensitive to the divider final writeback shape. A one-cycle RTL stage cleared max-slew and max-cap completely without touching the ISA or the test harness. A tighter place-and-route fanout target then cleared the final fanout count in the signoff metrics.
That makes P36 the first RV32IM rung in this ladder with ACT4 I/M coverage and clean recorded backend metrics.