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.
RTL fix: matched_filter_multi_segment.v ST_WAIT_FFT now waits for
processing chain to complete ALL 1024 outputs and return to IDLE
before advancing to next segment. Previously, it transitioned on the
first fft_pc_valid edge, causing the chain to still be outputting
while multi-seg started collecting data for the next segment. This
broke the handshake and caused permanent deadlock after segment 0.
Also fixes forward reference of sample_addr_from_chain in
radar_receiver_final.v (declaration moved before first use).
New files:
- tb/tb_radar_receiver_final.v: P0 integration test for full RX
pipeline (ADC->DDC->MF->range_bin_decimator->doppler), 10 checks
- tb/ad9484_interface_400m_stub.v: behavioral ADC stub for iverilog
All existing tests still pass: multi-seg 32/32, MF co-sim 3/3,
Doppler co-sim 14/14.
Bug: rounding logic 'adc_i <= ddc_i[17:2] + ddc_i[1]' overflows when
ddc_i[17:2]=0x7FFF and ddc_i[1]=1, causing 0x7FFF+1=0x8000 (sign flip
from max positive to most negative value).
Fix: add explicit saturation — clamp to 0x7FFF when truncated value is
max positive and round bit is set. Negative values cannot overflow since
rounding only moves toward zero.
New testbench: tb_ddc_input_interface.v with 26 tests covering rounding,
truncation, overflow saturation at positive boundary, negative full scale,
valid synchronization, and sync error detection.
Bit-accurate Python model (fpga_model.py) mirrors full DDC RTL chain:
NCO -> mixer -> CIC -> FIR with exact fixed-point arithmetic matching
RTL DSP48E1 pipeline behavior including CREG=1 delay on CIC int_0.
Synthetic radar scene generator (radar_scene.py) produces ADC test
vectors for 5 scenarios: DC, single target (500m), multi-target (5),
noise-only, and 1 MHz sine wave.
DDC co-sim testbench (tb_ddc_cosim.v) feeds hex vectors through RTL
DDC and exports baseband I/Q to CSV. All 5 scenarios compile and run
with Icarus Verilog (iverilog -g2001 -DSIMULATION).
Comparison framework (compare.py) validates Python vs RTL using
statistical metrics (RMS ratio, DC offset, peak ratio) rather than
exact sample match due to RTL LFSR phase dithering. Results: 5/5 PASS.