The PR-Z A6 e2e test (tb_e2e_dsp_to_host) exposed that the wire-format
cfar_dense map emitted by usb_data_interface_ft2232h was all-zero for
our deterministic single-target stimulus, even though cfar_ca's
in-flight outputs showed CONFIRMED at the expected cells (verified via
in-TB capture, E5/E6 PASS).
Deep instrumented debug (BRAM-WRITE, BRAM-READ, EGRESS-CAP probes)
revealed THREE independent bugs that combined to produce the all-zero
wire output. Each bug alone would have been visible; the way they
compounded made the symptom look like a single coarse failure.
Bug A — stale write address (radar_system_top.v):
usb_inst.range_bin_in/doppler_bin_in were tied to notched_*_bin
(= rx_*_bin = doppler_processor outputs). After doppler returns to
S_IDLE its `output reg`s hold their last-driven values (511, 47).
cfar_ca's CMP-phase emit (cycles ~520..73520 after frame_complete)
fires cfar_valid with detect_range/detect_doppler set to its own
per-cell scan counters, but those outputs were dangling — usb's
RMW saw the doppler stale (511, 47) and slammed every cfar write
to byte_addr {511, 47[5:2]} = bram[8187], past the 6144-byte wire
range entirely.
Fix: register cfar_detect_range/doppler in lockstep with the existing
rx_detect_valid/rx_detect_class registration block (clk_100m_buf
domain), then mux them into usb_inst.range_bin_in/doppler_bin_in on
rx_detect_valid. doppler-magnitude write path is unaffected because
doppler_valid and rx_detect_valid are mutually exclusive (BUFFER vs
CMP phases of cfar_ca).
Bug B — BRAM read pipeline lag (usb_data_interface_ft2232h.v):
The detect_rd_data <= detect_bram[detect_rd_addr] BRAM read port has
1-cycle latency. WR_DETECT_DATA's emit FSM advanced detect_rd_addr
and read detect_rd_data in the SAME edge — so cycle K read bram[K-2]
(the addr from cycle K-1's commit) instead of bram[K-1]. Result:
every cfar wire byte = bram[N-1] instead of bram[N], shifting the
entire 6144-byte detect section +1 byte = +4 doppler bins. Doppler
hides this naturally because its 2-byte-per-cell rhythm gives BRAM a
free settling cycle between addr-set and emit-read.
Fix: pre-load detect_rd_addr <= 1 and det_doppler_byte_idx <= 1 at
every WR_DETECT_DATA entry transition (HDR direct, RANGE direct,
DOPPLER → DETECT). BRAM produces bram[0] for the first emit cycle
(settled since reset because detect_rd_addr was 0 throughout the
preceding section) while the addr advance schedules bram[1] for the
second emit cycle — and from then on the FSM's natural advance
pattern keeps the pipeline aligned, including across the per-range
boundary (det_doppler_byte_idx == DET_BYTE_LAST_PER_RANGE).
Bug C — detect_clearing window overlaps cfar's first 4 columns:
detect_clearing fired 1 cycle after frame_complete and ran for 8192
clk cycles (1 byte/cycle). cfar_valid writes were gated on
`!detect_clearing` (line 512). cfar's CMP-phase emits start at
frame_complete + ~520 cycles and run for ~73000 cycles, so the
first ~7672 cycles (≈ 4 doppler columns) of cfar pulses were
silently dropped. Test stimulus lit (67, 2/3) for sub-frame 0, all
inside the clearing window → bytes lost. (67, 18/19) and (67, 34/35)
for SF1/SF2 fell after clearing → captured correctly. Visible as
one-byte mismatch (0x0A expected, 0x00 captured) at offset 49965
(= cfar byte 804 = range 67, doppler 0..3) once Bugs A and B were
fixed.
Fix: move detect_clearing trigger from "1 cycle after frame_complete"
to wr_done_pulse (USB-transfer-complete edge already CDC'd into clk
via the AUDIT-C12 wr_done_sync chain). Clearing now runs in the dead
zone after USB has finished reading frame N's BRAM, well before
frame N+1's cfar starts CMP (~480k cycles of margin at 178 fps).
First frame after reset relies on BRAM init=0 — added explicit
initial block under `ifdef SIMULATION so iverilog matches Vivado's
synthesis default.
Test infrastructure:
- tb/tb_e2e_dsp_to_host.v new — deterministic single-target stimulus
fed through the back-half of the radar pipeline (range_decim → MTI
→ doppler → DC-notch → cfar → registered sync → usb), 16 in-TB
asserts + bit-exact byte capture.
- tb/cosim/gen_e2e_stimulus.py / gen_e2e_expected.py new — Python
deterministic stim + bit-exact frame golden.
- tb/cosim/tb_e2e_dsp_to_host_parse.py new — parses captured frame
via radar_protocol, runs 12 strict-bit-equality checks plus 16
semantic checks (target == CONFIRMED, neighbors == NONE,
DC-notched bins == NONE, etc).
- run_regression.sh — A6 hookup + retired the two zero-assertion
radar_system_tb USB_MODE=0/1 smoke runs and the 3-liveness-only
tb_system_dataflow (subsumed by A6's stronger checks). Saves
~7 min wall.
Verification:
- Local iverilog: in-TB 16/16 PASS, parser strict 28/28 PASS.
- Remote Vivado 2025.2 xsim (Artix-7 target): in-TB 16/16 PASS,
parser strict 28/28 PASS.
- Full regression: 41 / 0 / 0.
The MODEL_USB_CFAR_BUG bug-model flag (used to keep the regression
green during development against buggy production) is removed — the
test is now strict bit-exact against the post-fix wire format.
AERIS-10: Open Source Pulse Linear Frequency Modulated Phased Array Radar
AERIS-10 is an open-source, low-cost 10.5 GHz phased array radar system featuring Pulse Linear Frequency Modulated (LFM) modulation. Available in two versions (3km and 20km range), it's designed for researchers, drone developers, and serious SDR enthusiasts who want to explore and experiment with phased array radar technology.
📡 Overview
The AERIS-10 project aims to democratize radar technology by providing a fully open-source, modular, and hackable radar system. Whether you're a university researcher, a drone startup, or an advanced maker, AERIS-10 offers a platform for experimenting with beamforming, pulse compression, Doppler processing, and target tracking.
🔬 Key Features
- Open Source Hardware & Software - Complete schematics, PCB layouts, firmware, and software available
- Dual Version Availability:
- AERIS-10N (Nexus): 3km range with 8x16 patch antenna array
- AERIS-10E (Extended): 20km range with 32x16 dielectric-filled slotted waveguide array
- Full Electronic Beam Steering - ±45° electronic steering in elevation and azimuth
- Advanced Signal Processing - On-board FPGA handles pulse compression, Doppler FFT, MTI, and CFAR
- Python GUI - User-friendly interface with map integration
- GPS/IMU Integration - Real-time position and attitude correction
- Modular Design - Separate power management, frequency synthesis, and RF boards
🏗️ System Architecture
Hardware Components
The AERIS-10 main sub-systems are:
-
Power Management Board - Supplies all necessary voltage levels to the electronics components with proper filtering and sequencing (sequencing ensured by the microcontroller)
-
Frequency Synthesizer Board - Uses a high-performance Low Jitter Clock Generator (AD9523-1) that supplies phase-aligned clock references for:
- RX and TX Frequency Synthesizers (ADF4382)
- DAC
- ADC
- FPGA
-
Main Board containing:
- DAC - Generates the RADAR Chirps
- 2x Microwave Mixers (LTC5552) - For up-conversion and IF-down-conversion
- 4x 4-Channel Phase Shifters (ADAR1000) - For RX and TX chain beamforming
- 16x Front End Chips (ADTR1107) - Used for both Low Noise Amplifying (RX) and Power Amplifying (TX) stages
- XC7A50T FPGA - Handles RADAR Signal Processing on the upstream FTG256 board:
- PLFM Chirps generation via the DAC
- Raw ADC data read
- Hybrid Automatic Gain Control (AGC) — cross-layer FPGA/STM32/GUI loop
- I/Q Baseband Down-Conversion
- Decimation
- Filtering
- Forward FFT
- Pulse Compression
- Doppler, MTI and CFAR processing
- USB Interface
- STM32F746xx Microcontroller - Used for:
- Power-up and power-down sequencing (see Power Management Excel File)
- FPGA communication
- Setup and Interface with:
- Clock Generator (AD9523-1)
- 2x Frequency Synthesizers (ADF4382)
- 4x 4-Channel Phase Shifters (ADAR1000) for RADAR pulse sequencing
- 2x ADS7830 8-channel I²C ADCs (Main Board, U88 @ 0x48 / U89 @ 0x4A) for 16x Idq measurement, one per PA channel, each sensed through a 5 mΩ shunt on the PA board and an INA241A3 current-sense amplifier (x50) on the Main Board
- 2x DAC5578 8-channel I²C DACs (Main Board, U7 @ 0x48 / U69 @ 0x49) for 16x Vg control, one per PA channel; closed-loop calibrated at boot to the target Idq
- GPS module (UM982) for GUI map centering and per-detection position tagging
- GY-85 IMU for pitch/roll correction of target coordinates
- BMP180 Barometer
- Stepper Motor
- 1x ADS7830 8-channel I²C ADC (Main Board, U10) reading 8 thermistors for thermal monitoring; a single GPIO (EN_DIS_COOLING) switches the cooling fans on when any channel exceeds the threshold
- RF switches
-
16x Power Amplifier Boards - Used only for AERIS-10E version, featuring 10Watt QPA2962 GaN amplifier for extended range
-
Antenna Arrays:
- AERIS-10N (Nexus) - 8x16 patch antenna array
- AERIS-10X (Extended) - 32x16 dielectric-filled slotted waveguide antenna array
-
Miscellaneous Components:
- Slip-Ring
- Stepper Motor and drivers
- Cooling Fans
- Enclosure
Processing Pipeline
- Waveform Generation - DAC creates LFM chirps
- Up/Down Conversion - LTC5552 mixers handle frequency translation
- Beam Steering - ADAR1000 phase shifters control 16 elements
- Signal Processing (FPGA):
- Raw ADC data capture
- I/Q baseband down-conversion
- Decimation & filtering (CIC/FIR)
- Pulse compression
- Doppler FFT processing
- MTI & CFAR detection
- System Management (STM32):
- Power sequencing
- Peripheral configuration
- GPS/IMU integration
- Stepper motor control
- Visualization (Python GUI):
- Real-time target plotting
- Map integration
- Radar control interface
📊 Technical Specifications
| Parameter | AERIS-10N (Nexus) | AERIS-10X (Extended) |
|---|---|---|
| Frequency | 10.5 GHz | 10.5 GHz |
| Max Range | 3 km | 20 km |
| Antenna | 8x16 Patch Array | 32x16 Slotted Waveguide |
| Beam Steering | Electronic (±45°) | Electronic (±45°) |
| Mechanical Scan | 360° (stepper motor) | 360° (stepper motor) |
| Output Power | ~1W×16 | 10W×16 (GaN amplifier) |
| Processing | FPGA + STM32 | FPGA + STM32 |
🚀 Getting Started
🧹 Repository File Placement Policy
To keep the repository root clean and make artifacts easy to find, place generated files in the following locations:
- Published reports (tracked, GitHub Pages):
docs/- Example:
docs/AERIS_Simulation_Report_v2.pdf
- Example:
- Simulation-generated outputs (local, gitignored):
5_Simulations/generated/- Plots, scenario outputs, temporary analysis directories
- FPGA/Vivado generated artifacts (local, gitignored):
9_Firmware/9_2_FPGA/reports/- VCD/VVP dumps, temporary CSVs, local report snapshots
- Reusable FPGA automation scripts (tracked):
9_Firmware/9_2_FPGA/scripts/- TCL flows, helper scripts used by build/bring-up
Do not leave generated artifacts in the repository root.
Prerequisites
- Basic understanding of radar principles
- Experience with PCB assembly (for hardware build)
- Python 3.8+ for the GUI software
- FPGA development tools (Vivado) for signal processing modifications
Hardware Assembly
- Order PCBs: Production outputs are under
/4_Schematics and Boards Layout/4_7_Production Files - Source Components: BOM/CPL files are co-located under
/4_Schematics and Boards Layout/4_7_Production Files - Assembly: Use the schematics in
/4_Schematics and Boards Layout/4_6_Schematicstogether with the production outputs above; a standalone assembly guide is not currently tracked - Antenna: Choose appropriate array files for your target variant
- Enclosure: Mechanical drawings currently live in
/8_Utils/Mechanical_Drawings
📜 License
This project is open-source but uses different licenses for hardware and software to ensure proper legal coverage.
Hardware Documentation
The hardware design files—including:
- Schematics and PCB layouts (in
/4_Schematics and Boards Layout) - Bill of Materials (BOM) files
- Gerber files and manufacturing outputs
- Mechanical drawings and enclosure designs
are licensed under the CERN Open Hardware Licence Version 2 – Permissive (CERN-OHL-P) .
This is a hardware-specific license that:
- ✅ Clearly defines "Hardware," "Documentation," and "Products"
- ✅ Includes explicit patent protection for contributors and users
- ✅ Provides stronger liability limitations (important for high-power RF)
- ✅ Aligns with professional open-hardware standards (CERN, OSHWA)
You may use, modify, and sell products based on these designs, provided you:
- Maintain the original copyright notices
- Distribute any modified designs under the same license
- Make your modifications available in Source format
Software and Firmware
The software components—including:
- FPGA code (VHDL/Verilog in
/9_Firmware) - Microcontroller firmware (STM32)
- Python GUI and utilities
remain under the MIT License for maximum flexibility.
Full License Texts
- The complete CERN-OHL-P license text is in the
LICENSEfile - MIT license terms apply to software where not otherwise specified
Why This Change?
Originally, the entire project used the MIT license. The community (special thanks to gmaynez!) pointed out that MIT lacks legal protections needed for physical hardware. The switch to CERN-OHL-P ensures the project is properly protected while maintaining the same permissive spirit.
📚 Documentation
Comprehensive documentation is available in the /docs folder and served via GitHub Pages at https://NawfalMotii79.github.io/PLFM_RADAR/docs/:
🤝 Contributing
We welcome contributions! Please see our Contributing Guidelines for details on repo layout, branch workflow, and basic PR checks.
Areas where help is especially appreciated:
- RF Engineers: Review designs, optimize antenna performance
- FPGA Developers: Optimize signal processing pipeline
- Software Developers: Enhance Python GUI and SDK
- Beta Testers: University researchers, drone startups, advanced makers
📞 Contact & Collaboration
I welcome serious inquiries from researchers, engineers, and potential collaborators. However, due to the high volume of interest in this project, please understand that I cannot guarantee a response to every message.
- Technical questions or bug reports: Please open a GitHub issue so the whole community can benefit from the discussion.
- Collaboration, licensing, or business inquiries: 📧 nawfal.motii.33 [at] gmail [dot] com
💰 Sponsors
Star ⭐ this repository if you're interested in open-source radar technology!
Note: This is an active development project. Some features are still in progress. Check the issues page for known limitations and upcoming features.



