BUG-001: INT16 instruction encoding bit-field overlap
| Field | Value |
|---|---|
| Severity | CRITICAL |
| Component | Testbench |
| File(s) | tb/tb_server_dispatch_unit.py — npu_instr_int16() |
| Status | Fixed |
| Date | 2025-06 |
Symptom
NPU INT16 LOAD_W and LOAD_A instructions produced wrong weight/activation values.
Data loaded with INT16 precision was silently corrupted, causing incorrect MAC results
in all INT16-mode inference tests.
Root Cause
The 32-bit NPU instruction layout is:
[31:18] data (14-bit INT16, sign-extended to 16 by RTL)
[17:14] col (4-bit column index)
[13:10] row (4-bit row index)
[9:7] cmd (3-bit opcode)
[6:0] 0x6B (RISC-V custom-1 opcode)
npu_instr_int16() encoded data at [31:16], which overlaps col at [17:14]
via bits [17:16]. Writing any non-zero data value corrupted the column index.
Fix
Move the INT16 data field from [31:16] to [31:18].
- data_clipped = clamp(val, -32768, 32767)
- word = (data_clipped & 0xFFFF) << 16 # bits [31:16] — overlaps col at [17:16]
+ data_clipped = clamp(val, -8192, 8191) # 14-bit range
+ data14 = data_clipped & 0x3FFF
+ word = data14 << 18 # bits [31:18] — no overlap with col [17:14]
The RTL already read data_int16 = npu_instruction[31:18]; only the testbench encoding was wrong.
Values in [-8192, 8191] encode losslessly. The test range [-100, 100] is exact.