5 Commits

Author SHA1 Message Date
Jason
5617d552df fix(fpga): frame-boundary atomic commit for USB timing regs
C-4: GUI Waveform Timing opcodes (0x10..0x14) write one parameter per
USB packet with arbitrary inter-opcode latency. Previously each opcode
landed directly on a live register consumed by radar_mode_controller,
so a mid-scan reconfiguration exposed the RX FSM to torn sets (e.g.
new long_chirp with old long_listen), and a value below the running
timer truncated the current chirp and corrupted one range-Doppler
frame.

Fix: split each of the five timing regs into pending (USB write target)
and live (FSM consumer). radar_mode_controller exports a new
cfg_commit_strobe that is HIGH while scanning is idle (S_IDLE) and
pulses for 1 cycle at every elevation/azimuth boundary in S_ADVANCE.
radar_system_top snapshots pending -> live on the strobe, guaranteeing
the FSM always sees a self-consistent set. No CDC added: strobe is in
clk_100m same as the USB-cmd path.

Regression: tb_radar_mode_controller adds 3 checks for strobe
semantics (idle-HIGH, scanning-LOW, one pulse per elevation boundary).
32/32 full regression PASS; Radar Mode Controller TB grows from 78 to
81 checks.
2026-04-23 04:43:02 +05:45
Jason
60e49c7da6 feat(fpga): integrate 2048-pt FFT upgrade — non-conflicting RTL (wave 1/3)
File-scoped cherry-pick from feat/fft-2048-upgrade (e9705e4) for modules
that only the fft branch modified:

  RTL:
    cfar_ca.v                        512-row CFAR
    chirp_memory_loader_param.v      2-segment × 2048-sample loader
    doppler_processor.v              16384-deep doppler memory
    fft_engine.v                     2048-pt FFT
    matched_filter_multi_segment.v   2-seg overlap-save, BRAM overlap_cache
    matched_filter_processing_chain.v
    radar_mode_controller.v          XOR edge detector
    radar_params.vh                  (new) single source of truth
    range_bin_decimator.v            2048 -> 512 output bins
    rx_gain_control.v

  Memory:
    fft_twiddle_2048.mem             (new) 2048-pt FFT twiddles
    long_chirp_seg0_{i,q}.mem        2048-sample seg 0 (was 1024)
    long_chirp_seg1_{i,q}.mem        2048-sample seg 1 (was 1024)
    long_chirp_seg{2,3}_{i,q}.mem    deleted (4-seg -> 2-seg collapse)

  Gen:
    tb/cosim/gen_chirp_mem.py        regen script for mem files above

Waves 2 and 3 follow: manual merge for dual-modified files
(radar_system_top, usb_data_interface_ft2232h, mti_canceller,
radar_receiver_final), and CFAR pipeline from 2401f5f keeping p0's
CIC/DDC reset strategy.
2026-04-21 01:52:32 +05:45
Jason
7cdfa486e5 Gap 2 GUI Settings: runtime chirp timing, stream control gating, status readback (18/18 FPGA, 20/20 MCU)
Register map: 0x10-0x15 chirp timing overrides, 0xFF status readback,
0x03 CFAR threshold now wired to actual compare, 0x04 stream control
gates USB write FSM. Status readback sends 7-word packet (0xBB header,
5 status words, 0x55 footer) via toggle CDC.

radar_mode_controller: 6 cfg_* input ports replace hardcoded parameters.
usb_data_interface: stream_control CDC, status_request toggle CDC,
  SEND_STATUS state (3'd7), stream gating in IDLE/HEADER/RANGE/DOPPLER.
radar_system_top: 6 host registers + command decode for 0x10-0x15/0xFF.
radar_receiver_final: 6 host_* timing passthrough ports.

Testbench coverage: RMC 81 checks (+TG16 runtime reconfig), USB 77
checks (+TG15 stream gating, TG16 status readback, TG17 chirp opcodes).
Fixed iverilog 13.0 forward-ref for status_req_toggle_100m.
2026-03-19 23:54:48 +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
f5a3394f23 Add 3 missing FPGA modules with enhanced testbenches (168/168 pass)
Implement the 3 modules identified as missing during repo audit:
- matched_filter_processing_chain: behavioral FFT-based pulse compression
- range_bin_decimator: 1024→64 bin decimation with 3 modes + start_bin
- radar_mode_controller: 4-mode beam/chirp controller

Wire radar_mode_controller into radar_receiver_final.v to drive the
previously-undriven use_long_chirp and mc_new_* signals.

Implement start_bin functionality in range_bin_decimator (was dead code
in the original interface contract — now skips N input bins before
decimation for region-of-interest selection).

Add comprehensive testbenches with Tier 1 confidence improvements:
- Golden reference co-simulation (Python FFT → hex → bin comparison)
- Saturation boundary tests (0x7FFF / 0x8000 extremes)
- Reset mid-operation recovery tests
- Valid-gap / stall handling tests
- Mode switching and counter persistence tests
- Accumulator overflow stress tests

Test counts: matched_filter 40/40, range_bin_decimator 55/55,
radar_mode_controller 73/73 — all passing with iverilog -g2001.
2026-03-15 13:37:10 +02:00