Skip to content

BUG-001: INT16 instruction encoding bit-field overlap

Field Value
Severity CRITICAL
Component Testbench
File(s) tb/tb_server_dispatch_unit.pynpu_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.