Repository navigation
Performance Measurement
FINN+ reports how fast a design is at four increasing levels of fidelity and cost. Use the cheapest one that answers your question.
| Level | Cost | Tells you |
|---|---|---|
| Estimates | seconds | Predicted cycles and resources, per layer |
| RTL simulation | minutesโhours | Real throughput and latency, cycle-accurate |
| Synthesis reports | hours | Actual resources, timing, power |
| On hardware | needs a board | End-to-end throughput, latency, bandwidth |
Note
For the analysis-pass API behind the estimates, see Analysis Passes; for the simulation machinery, Simulation Internals.
An estimates-only build takes seconds and writes into <output_dir>/report/:
| File | Contents |
|---|---|
estimate_layer_cycles.json |
Predicted cycles per sample, per layer |
estimate_layer_resources.json |
LUT / BRAM / URAM / DSP per layer, plus a total
|
estimate_layer_config_alternatives.json |
Resources per resType / ram_style alternative |
estimate_network_performance.json |
Whole-network throughput and latency |
op_and_param_counts.json |
MAC and parameter counts |
This is where all folding exploration should happen. The largest entry in
estimate_layer_cycles.json is your bottleneck.
Note
estimate_network_performance.json is not produced for MLO designs.
Per-layer estimates still work.
step_measure_rtlsim_performance writes measured โ not predicted โ numbers into
report/rtlsim_performance.json. Each entry reports the initiation interval in cycles and a
derived throughput_fps that already accounts for synth_clk_period_ns.
Note
This step is in the default step list and runs whenever it is reached. Despite the name,
the rtlsim_performance entry in generate_outputs does not control it โ that value is
currently unused. To skip the measurement, remove step_measure_rtlsim_performance from steps.
This is the number to trust before committing to synthesis. A large gap between the estimate and the measured interval usually means FIFO starvation rather than a folding mistake.
Important
Size your FIFOs first. The measurement reads each layer's configured FIFO depths. A depth of
2 is the unconfigured default and triggers a warning that the simulation may deadlock. Run
FIFO sizing or supply a fifo_config_file before measuring.
For diagnosing where a pipeline stalls, verify_save_rtlsim_waveforms: true writes
report/rtlsim_perf_trace.wdb with per-layer visibility, including FIFO count signals.
Estimates rank configurations well, but the authoritative resource and timing numbers come from the
tools, after out_of_context_synth or a full bitfile build.
generate_outputs: [..., out_of_context_synth]
vivado_power_simulate_activity: true # default
vivado_power_simulation_type: functional # or "timing"Power estimation requires out-of-context synthesis and fails with
Vivado power estimation needs OOC synth otherwise. Simulating switching activity is considerably
more accurate than assuming defaults.
The generated PYNQ driver measures a deployed accelerator:
driver.run_throughput_test(report_dir="...") # writes report_throughput_test.json| Metric | Meaning |
|---|---|
runtime[ms], throughput[images/s]
|
Wall-clock performance for the configured batch size |
DRAM_in_bandwidth[MB/s], DRAM_out_bandwidth[MB/s]
|
Achieved hostโaccelerator bandwidth |
DRAM_extw_<name>_bandwidth[MB/s] |
Per-stream bandwidth for external weights |
fclk[mhz] |
Actual clock, read back from the platform |
Because it reports DRAM bandwidth, this measurement reveals when a design is I/O-bound rather than compute-bound โ a case no amount of folding will fix.
throughput_test includes host and DMA overhead. To measure the accelerator itself, enable the
hardware instrumentation wrapper:
enable_instrumentation: true
instrumentation_avg_n: 64 # averaging window, in frames
instrumentation_no_dma: false # true to exclude the DMA from the measurementThe design then generates its own input stream and counts cycles on-chip. The driver reports:
| Field | Meaning |
|---|---|
min_latency, latency, avg_latency
|
Latency in cycles, averaged over avg_n frames |
interval, avg_interval
|
Initiation interval in cycles โ the hardware counterpart of the rtlsim figure |
checksum, frame
|
Per-frame checksum and frame counter |
overflow_err, underflow_err
|
Stream over/underflow flags |
The error flags are the fastest check that a design is keeping up with its input stream. The
driver's throttle_interval lets you sweep the input rate to find true saturation throughput rather
than just the free-running figure.
Warning
Instrumentation is Zynq-only. Enabling it on an Alveo/Vitis build fails with
Instrumentation is not yet implemented for Alveo/Vitis flow.
A related facility for correctness rather than speed: FINN+ can insert checksum nodes after selected layers, computing a running checksum over the stream without altering it. This answers "at which layer does the hardware start disagreeing with the reference?" when a design passes simulation but fails on the board.
Set the output_hook node attribute to "checksum" on the layers of interest (via your
folding config).
- Iterate on folding using estimates alone.
- Size FIFOs, then confirm the design hits its predicted interval in rtlsim.
- Synthesize for real resource, timing and power numbers.
- On hardware, use the throughput test for end-to-end numbers, and instrumentation when you need the accelerator isolated from host overhead.
- Folding โ what determines the throughput being measured
- FIFO Sizing โ a prerequisite for meaningful rtlsim numbers
- Functional Verification โ correctness rather than speed
- Benchmarking โ automating measurement across many configurations
- Deployment โ getting the design onto a board
๐ Home
Using FINN+ to compile a network.
Getting started
Building
Tuning
Checking
Reference
Working on the FINN+ compiler itself.
Getting started
Extending FINN+
Compiler internals
- Network Preparation
- Hardware Build
- Folding
- FIFO Sizing
- Multi-Layer Offload
- Simulation & Verification
Testing
Reference
- FINN+ Repository
- Brevitas - Quantization library
- QONNX - Model format
- finn-examples - Pre-built accelerators