Skip to content

BUG-011: cpu_peak_tests.asm INT16 NPU block's hex doesn't match its own comment

Field Value
Severity LOW
Component Testbench
File(s) tb/cpu_peak_tests.asm
Status Open (cosmetic — no test assertion is affected)
Date 2026-07-23

Symptom

None — this doesn't fail anything. Found by hand-deriving the correct bit-exact encoding for rtl/npu.sv's INT16 data field while writing scripts/riscv_asm.py's NPU pseudo-instruction encoder, and cross-checking it against every hand-encoded example already in the repo (see toolchain.md).

Root Cause

#  LOAD_W(0,0,data=100) INT16:   cmd=0, data[31:16]=100 → 0x0064006B
npu_load_w_int16_00_100     | 0x0064006B | npu |

rtl/npu.sv computes the INT16 value as {{2{instr[31]}}, instr[31:18]} — i.e. the raw 14-bit field is instr[31:18], sign-extended by 2 bits, not data<<18 the way the comment's arithmetic implies. Decoding 0x0064006B's actual instr[31:18] bits gives 25, not 100. The block has no register-check annotation (dest=npu entries in this file never carry a 4th "check" field), so nothing was ever positioned to catch the mismatch between the intended value and the encoded one.

Fix

Not applied. scripts/riscv_asm.py's npu.load_w/npu.load_a pseudo-instructions use the verified-correct formula ((data & 0x3FFF) << 18, matching rtl/npu.sv bit-exact — confirmed against every other hand-encoded example in this same file, which do match), so new NPU test code written through the assembler doesn't have this problem. Regenerating this specific line in cpu_peak_tests.asm was left undone because that file is wired into the default 15-test regression suite (unlike BUG-010's file) and the block in question is exercising pipeline/stall behavior, not asserting a specific numeric result — lower risk to leave as a documented, known discrepancy than to touch the suite's default fixture opportunistically.

Notes

Third instance in one session of the same structural problem: a hand-computed hex value drifting from the mnemonic/comment next to it, undetected because nothing re-derives one from the other. See BUG-010 and toolchain.md.