Home > EulerNPU > Tutorials > 07. FPGA / Zynq Overview

07. FPGA / Zynq Overview

This page covers the general flow of taking a graph that's been validated on cpu_ref / npu_sim and putting it onto real FPGA silicon. The pattern established here is what 08. kws_silicon executes concretely.

Why FPGA / Zynq

What FPGA buys you over CPU/GPU:

eulernpu's primary target board is QMTECH XC7Z020 CLG484-1 (Zynq-7000):

ResourceValueImplication
LUT53 KSmall IPs fit comfortably
DSP slices220~50 float MAC units possible
BRAM 36k280 (~140 KB usable)Small model weights cache on-chip
DDR3512 MBBigger weights need DDR streaming
ARM Cortex-A9666 MHz × 2 (PS)Embedding/sample/non-PL work
EMIO UARTMIO 48/49Bare-metal printf channel
PL Fmax~90–115 MHz measuredBound by float MAC placement

Zynq Architecture at a Glance

┌─────────────────────────────────────────┐
│ PS (Processing System)                   │
│  ┌──────────────┐    ┌──────────────┐   │
│  │ ARM A9 #0    │    │ ARM A9 #1    │   │
│  │ 666 MHz      │    │ 666 MHz      │   │
│  └──────┬───────┘    └──────┬───────┘   │
│         │   L1 32K + L2 512K            │
│         │   DDR3 controller             │
└─────────┼─────────────────────────────────┘
          │   GP0 (32-bit AXI, control)
          │   HP0–3 (64-bit AXI, data)
          │   EMIO (GPIO/UART routing)
┌─────────┼─────────────────────────────────┐
│ PL (Programmable Logic)                  │
│  ┌──────▼───────────────────────────┐    │
│  │ NPU IP                            │    │
│  │  s_axilite (control reg)          │    │
│  │  m_axi    (data via HP slave)     │    │
│  └───────────────────────────────────┘    │
└─────────────────────────────────────────┘

Standard Flow — 7 Stages

1. Train + INT8 quantize  →  weights.npz / weights.h
2. Host CPU smoke         →  compile same C with host gcc, verify accuracy
3. HLS C-synth            →  C++ → RTL IP, Fmax / DSP / BRAM report
4. Vivado BD + impl       →  IP + PS + AXI wiring → bitstream
5. Vitis platform + ELF   →  SDT platform + BSP + bare-metal C ELF
6. xsdb silicon run       →  JTAG bitstream load + ELF download + UART capture
7. Measure + regression   →  cycle count / accuracy / reproducibility auto-checked

All 7 stages should live in automated scripts — silicon reproducibility should not be a cliff edge every time.

PL Offload Candidates (Spec → Hardware)

Which ops are worth putting on PL fabric?

Which ops are NOT worth offloading:

The equivalent analysis is now automatic via eulernpu profile --roofline.

Board Bring-up Checklist

If you have a fresh XC7Z020 board:

  1. Power + USB-JTAG connected (QMTECH does both via a single USB-C)
  2. Check /dev/ttyUSBn — typically two ports (JTAG + UART)
  3. Vivado 2025.1 + Vitis 2025.1 installed
  4. USB Blaster cable driverlsusb to confirm Xilinx is recognised
  5. 115200-8N1 UART terminalpicocom, tio, pyserial, etc.

The shortest board bring-up walkthrough is the P05 sanity check: the FPGA sanity-check demo tutorial (shipped with the internal bring-up repo). Once that passes you can move to P06.

Per-Board Resource Limits (capability matrix)

eulernpu profile --all-boards /tmp/sim.profile.json

A single table tells you which board the graph fits on:

BoardLUTDSPBRAM 36kDDRNote
XC7Z02053 K220280DDR3 512 MBP06/07/08 silicon-validated
XC7Z045218 K900545DDR3 1 GBMidrange
XCZU7EV230 K1728312DDR4 4 GBZU+ entry
XCZU9EG274 K2520912DDR4 4 GBLarger models
XCK26(Kria)1248varies4 GBModule form factor

Next

The full silicon flow on the actual P06 KWS demo08. kws_silicon.