The hardware computes one 8×8 int8 product at a time:
(each of 64 PEs holds one int32 accumulator). Larger products are done in software tiling on the Zynq A9.
For
-
$M$ — rows of$A$ / rows of$C$ -
$N$ — columns of$B$ / columns of$C$ -
$K$ — inner dimension: columns of$A$ and rows of$B$ . Each output element is a dot product of length$K$ :
On NpuKit,
With VERSION ≥ 0x302, the host can preload a full K×N weight matrix into on-chip BRAM (LOAD_W) and stream only A tiles (FEAT_WMEM). VERSION ≥ 0x301 also supports tile-level B-only / A-only loads and A ping-pong. See weight_stationary.md.
Split the output into
| Loop | Role |
|---|---|
|
|
which row-block of |
|
|
which column-block of |
|
|
partial products that sum into that |
So:
-
$i_0, j_0$ place the result in the big$C$ -
$k_0$ walks the inner dimension — this is “what$K$ means” for tiling: how many 8-wide chunks of the dot-product to accumulate
Hardware CTRL:
- First
$k_0$ for a given$(i_0,j_0)$ :CLEAR|START(zero PE accumulators, then run) - Later
$k_0$ :STARTonly (keep accumulating) - After the last
$k_0$ : read the 8×8$C$ tile (DMA or MMIO)
Output has 2×2 spatial tiles. Each needs 2
A (16×16) B (16×16)
┌────────┬────────┐ ┌────────┬────────┐
│ A00 │ A01 │ │ B00 │ B01 │
│ 8×8 │ 8×8 │ │ 8×8 │ 8×8 │
├────────┼────────┤ ├────────┼────────┤
│ A10 │ A11 │ │ B10 │ B11 │
└────────┴────────┘ └────────┴────────┘
C (16×16)
┌─────────────────┬─────────────────┐
│ C00 = A00·B00 │ C01 = A00·B01 │
│ + A01·B10 │ + A01·B11 │
├─────────────────┼─────────────────┤
│ C10 = A10·B00 │ C11 = A10·B01 │
│ + A11·B10 │ + A11·B11 │
└─────────────────┴─────────────────┘
Host sequence for C00 (top-left 8×8 of
| Step | CTRL | Load A tile | Load B tile | Accumulators |
|---|---|---|---|---|
| 1 | CLEAR|START | A[0:8, 0:8] = A00 |
B[0:8, 0:8] = B00 |
← A00·B00 |
| 2 | START | A[0:8, 8:16] = A01 |
B[8:16, 0:8] = B10 |
← previous + A01·B10 |
| 3 | (read C) | — | — | write into C[0:8, 0:8] |
Then the same pattern for C01, C10, C11 (four output tiles × two
For 32×32×32:
Demo case rows×ones (also in the host suite):
Row
- Math / loops:
npu_matmul()inhost/npukit_matmul.py - Printed plans + matrices:
describe_tiling(),run_case(..., verbose=True) - Narrative in Jupyter: cells that call the same helpers so saved outputs keep A/B/C visible
The checked-in host/npukit_matmul.ipynb includes a PYNQ-Z2 DMA run with those dumps for the classic 8×8 suite plus tiled 16×16 and 32×32×32 (12/12 PASS).