The idea
Peak arithmetic capacity tells only part of an accelerator’s story. This project explores how operands reach processing elements, where partial sums live, and how a finite tile uses a physical array.
The approach
Signed INT8 operands move right and down through an N×N array while INT32 accumulators remain stationary. Row and column skew aligns each product. A descriptor sets reduction length and active shape; a ready/valid stream drains results in row-major order.
Engineering work
- Implemented signed multiply-accumulate processing elements and a parameterized nearest-neighbor array.
- Built operand storage, descriptor validation, skew scheduling, active-shape masking, and stable result serialization.
- Checked 2×2, 4×4, and 8×8 arrays against independent Python matrix products using random data and signed extrema.
- Measured useful MACs, compute clocks, output stalls, and compute utilization with explicit transfer-time boundaries.
What the results show
A full 4×4 tile with K=16 performs 256 useful MACs in 22 compute clocks: 72.73% of the physical compute slots. Preload and result transfer add further cost. Larger arrays need sufficiently large workloads to amortize fill and drain.
Verification evidence
| Tile configurations | 48 |
|---|---|
| Matrix elements compared | 1,344 |
| 4×4, K=16 compute clocks | 22 |
| Compute utilization, same tile | 72.73% |
Each project includes a documented test plan and coverage gaps. Simulation checks the supplied workloads; generic cell counts are not physical area, timing, or power measurements.
Reproduce the result
Download the source, install the open-source tools, and run from the collection root:
make systolic
make lint
make synth
make report