Skip to content

v2.0.0-fft2048 — AERIS-10 2048-pt FFT + Full Timing Closure

Choose a tag to compare

@JJassonn69 JJassonn69 released this 16 Apr 17:25
· 67 commits to main since this release

AERIS-10 2048-pt FFT Upgrade + Full Timing Closure

Complete cross-layer upgrade from 1024-pt to 2048-pt FFT with decimation=4, producing 512 output range bins at 6m spacing (was 64 bins at 24m). All 5 FPGA clock domains timing-closed on xc7a50tftg256-2 after 3 build iterations.

Timing (Build 19)

Clock Period WNS Failing Endpoints Previous (v1.1.0)
clk_mmcm_out0 (400 MHz) 2.5 ns +0.068 ns 0 +0.339 ns
clk_100m (100 MHz) 10.0 ns +0.156 ns 0 +0.080 ns
clk_120m_dac (120 MHz) 8.333 ns +0.627 ns 0
ft_clkout (60 MHz) 16.667 ns +9.887 ns 0
adc_dco_p (400 MHz) 2.5 ns +0.920 ns 0
Hold (WHS) +0.046 ns 0 +0.056 ns
Pulse width (WPWS) +0.361 ns 0 +0.361 ns
All constraints met Yes Yes

Utilization (xc7a50tftg256-2)

Resource Used Available Util% Previous (v1.1.0)
LUTs 21,735 32,600 66.67% 10,252 (31.4%)
Flip-Flops 14,579 65,200 22.36% 12,820 (19.7%)
BRAM 55.5 75 74.00% 17.5 (23.3%)
DSP48E1 112 120 93.33% 112 (93.3%)
F7 Muxes 7,849 16,300 48.15%
F8 Muxes 3,336 8,150 40.93%

What Changed (from v1.1.0-agc)

2048-pt FFT / 512-Bin DSP Pipeline

  • fft_engine.v: 2048-pt FFT with 11 butterfly stages (was 1024/10)
  • range_bin_decimator.v: 4x decimation (was 16x), 512 output bins at 6m spacing
  • doppler_processor.v: 16384-deep Doppler memory (was 2048), 14-bit addressing
  • chirp_memory_loader_param.v: 2-segment loader (was 4), 2048-sample arrays
  • matched_filter_multi_segment.v: 11-bit sample addressing, 2-segment processing
  • radar_receiver_final.v: 9-bit range bin width, sample_addr truncation fix
  • usb_data_interface_ft2232h.v: Bulk per-frame format with Manhattan magnitude
  • radar_params.vh: Single source of truth via include in all RTL modules

FPGA Timing Closure (Builds 17–19)

  • CFAR pipeline fix (cfar_ca.v): Pre-registered col_buf reads break 15-level mux tree critical path. clk_100m WNS: -0.331ns → +0.156ns
  • CIC reset path fix (cic_decimator_4x_enhanced.v, ddc_400m.v): Eliminated LUT1 inverter on reset fan-out to 8 DSP48E1 RSTB pins. Wired pre-registered reset_400m from DDC. clk_mmcm_out0 WNS: -0.074ns → +0.068ns

BRAM Inference Fixes (Build 16 → 17)

  • mti_canceller.v: prev_i/q arrays converted from async to sync reset → BRAM inference (saved ~16K fabric FFs)
  • matched_filter_multi_segment.v: overlap_cache sync-only write block → BRAM inference

Cross-Layer Updates

  • Python GUI: radar_protocol.py bulk frame parser for 512-bin arrays, 6m range scale, 6-bit stream control. Both tkinter and V7 PyQt6 dashboards updated
  • MCU firmware: RadarSettings.cpp max_distance 1536→3072m, map_size updated
  • Golden references: All .hex, .csv, .npy co-sim data regenerated for 2048/512 config
  • Stale cleanup: Deleted dead test classes, stale chirp segment files, dead utility functions

Test Suite

Layer Tests Status
Python (GUI) 172 (tkinter + PyQt6) Pass
MCU (C/C++) 22 Pass
FPGA (iverilog) 30 Pass
Cross-layer 61 Pass
Total 285 All pass, 0 skip

Assets

  • radar_system_top_50t.bit — Production bitstream (2,140 KB, program via Vivado/xsdb)
  • 02_timing_summary.rpt — Post-route timing report
  • 04_utilization.rpt — Post-route utilization report

Build Environment

  • Vivado 2025.2 (lin64)
  • Device: xc7a50tftg256-2 (speed grade -2, PRODUCTION)
  • Top module: radar_system_top_50t
  • Synth: 214s, Impl: 1631s, Bit: 38s
  • Build directives: ExtraNetDelay_high place, 3x AggressiveExplore phys_opt