9 Commits

Author SHA1 Message Date
Jason a577b7628b Fix staggered-PRF Doppler processing with dual 16-point FFTs 2026-03-27 23:05:28 +02:00
Jason 49c9aa28ad Fix Bug #11 (platform SPI transmit-only), FPGA B2 (chirp BRAM migration), FPGA B3 (DSP48 pipelining)
Bug #11: platform_noos_stm32.c used HAL_SPI_Transmit instead of
HAL_SPI_TransmitReceive — reads returned garbage. Changed to in-place
full-duplex. Dead code (never called), fixed per audit recommendation.
Test added: test_bug11_platform_spi_transmit_only.c. Mock infrastructure
updated with SPI spy types. All 11 firmware tests pass.

FPGA B2: Migrated long_chirp_lut[0:3599] from ~700 lines of hardcoded
assignments to BRAM with (* ram_style = "block" *) attribute and
$readmemh("long_chirp_lut.mem"). Added sync-only read block for proper
BRAM inference. 1-cycle read latency introduced. short_chirp_lut left
as distributed RAM (60 entries, too small for BRAM).

FPGA B3: Added BREG (window_val_reg) and MREG (mult_i_raw/mult_q_raw)
pipeline stages to doppler_processor.v. Eliminates DPIP-1 and DPOP-2
DRC warnings. S_LOAD_FFT retimed: fft_input_valid starts at sub=2,
+1 cycle total latency. BREG primed in S_PRE_READ at no extra cost.
Both FPGA files compile clean with Icarus Verilog.
2026-03-19 10:31:16 +02:00
Jason 254c0e6f03 Improve timing margins with targeted datapath register tuning
Reduce routing pressure on CIC/NCO critical paths and move Doppler BRAM read-address registers to sync-reset datapath logic so Build 13 closes with stronger setup/hold slack while preserving functional behavior.
2026-03-17 23:51:04 +02:00
Jason 1558f17d05 Convert async→sync reset on DSP/BRAM datapath registers for timing closure
P1-CRITICAL: doppler_processor.v — split FSM into control (async reset)
and BRAM/DSP datapath (sync reset) blocks. Fixes REQP-1839/1840 BRAM
address register corruption risk; enables DSP48 absorption of window
multipliers (mult_i/q).

P1-CRITICAL: frequency_matched_filter.v — convert all 4 pipeline stages
(input capture, multiply, add, saturate) from async to sync reset.
Enables DSP48E1 absorption of complex multiplier registers.

P1-HIGH: fir_lowpass.v — convert adder tree (L0-L4), output stage, and
valid pipeline from async to sync reset. Fixes 856 DPOR-1 warnings
(428 per FIR instance × 2 I/Q channels), enabling DSP48 absorption
of the entire pipelined adder tree.

Expected impact: eliminate ~1000 DRC warnings, improve WNS from +0.019ns
by enabling Vivado to absorb hundreds of registers into DSP48E1/BRAM
hard blocks. Full regression: 13/13 test suites pass (257+ assertions).
2026-03-17 20:11:13 +02:00
Jason fb59e98737 Add SymbiYosys formal verification for 6 modules, fix 2 doppler bugs
Formal verification (SymbiYosys + smtbmc/z3):
- cdc_single_bit: BMC PASS depth 80, cover PASS 3/3
- cdc_handshake: BMC PASS depth 100, cover PASS 4/4
- cdc_adc_to_processing: BMC PASS depth 80, cover PASS
- radar_mode_controller: BMC PASS depth 200, cover PASS 8/8
- range_bin_decimator: cover PASS 7/7, BMC running (step 61+)
- doppler_processor: cover running (step 133/150), BMC running (step 35+)

DUT bug fixes found by formal:
- doppler_processor: write_chirp_index overflow past CHIRPS_PER_FRAME-1
  in S_ACCUMULATE frame-complete branch (reset to 0)
- doppler_processor: read_doppler_index unclamped prefetch in S_LOAD_FFT
  causing OOB BRAM reads (clamped to DOPPLER_FFT_SIZE-1)

CDC fix (prior session, included):
- cdc_modules: async reset changed to sync reset on all CDC sync chains
  to prevent metastability on reset deassertion

RTL changes for formal observability:
- Added ifdef FORMAL output ports to cdc_handshake (6), cdc_adc (2),
  radar_mode_controller (2), range_bin_decimator (5), doppler_processor (11)
2026-03-17 12:47:22 +02:00
Jason 39f78d4349 Fix RTL Bug #3: S_IDLE->S_ACCUMULATE now writes first sample immediately
Previously the S_IDLE->S_ACCUMULATE transition consumed one data_valid
cycle without writing to BRAM, losing the first sample. The testbench
worked around this by sending sample[0] twice.

Fix: drive mem_we + data capture in S_IDLE on the transition cycle and
advance write_range_bin to 1. Testbench workaround removed.

Verified: 3/3 Doppler co-sim BIT-PERFECT, integration test 10/10 PASS.
2026-03-16 19:08:16 +02:00
Jason 17731dd482 Fix doppler_processor windowing pipeline bugs + multi-segment buffer_write_ptr bug, add co-sim suites
RTL bug fixes:
- doppler_processor.v: Add S_PRE_READ state to prime BRAM pipeline, restructure
  S_LOAD_FFT with sub-counter staging, fix BRAM address off-by-one
  (read_doppler_index <= fft_sample_counter + 2, was +1). All 3 Doppler
  co-sim scenarios now achieve BIT-PERFECT match (correlation=1.0, energy=1.0).
- matched_filter_multi_segment.v: Move buffer_write_ptr >= SEGMENT_ADVANCE check
  outside if(ddc_valid) block to prevent FSM deadlock. 32/32 tests PASS.

New co-simulation infrastructure:
- Doppler co-sim: tb_doppler_cosim.v (14/14 structural checks),
  gen_doppler_golden.py (3 scenarios: stationary/moving/two_targets),
  compare_doppler.py (bit-perfect thresholds)
- Multi-segment co-sim: tb_multiseg_cosim.v (32/32), gen_multiseg_golden.py
  with short and long test vector suites
2026-03-16 18:09:26 +02:00
Jason 692b6a3bfa Replace FFT stubs with synthesizable radix-2 DIT engine, fix BRAM inference
Implement iterative single-butterfly FFT engine (fft_engine.v) supporting
1024-pt and 32-pt transforms with quarter-wave twiddle ROM, XPM_MEMORY_TDPRAM
for guaranteed BRAM mapping in Vivado, and behavioral model for simulation.

Add xfft_32.v AXI-Stream wrapper for doppler_processor integration and
dual-branch matched_filter_processing_chain.v (behavioral + synthesis paths).

Fix placement failure caused by 68K+ registers from dissolved memory arrays:
- doppler_processor.v: extract mem writes to sync-only always block for BRAM
- xfft_32.v: extract buffer writes to sync-only always block for LUTRAM

Post-implementation: 37K regs (29%), 23K LUTs (37%), 10 BRAM (7%), fully routed.
All testbenches pass: fft_engine 12/12, xfft_32 10/10, mf_chain 27/27.
2026-03-16 10:25:07 +02:00
NawfalMotii79 5fbe97fa5f Add files via upload 2026-03-09 00:17:39 +00:00