diff --git a/9_Firmware/9_2_FPGA/radar_receiver_final.v b/9_Firmware/9_2_FPGA/radar_receiver_final.v index 6d0de80..ff28244 100644 --- a/9_Firmware/9_2_FPGA/radar_receiver_final.v +++ b/9_Firmware/9_2_FPGA/radar_receiver_final.v @@ -444,8 +444,8 @@ matched_filter_multi_segment mf_dual ( .mc_new_chirp(mc_new_chirp), .mc_new_elevation(mc_new_elevation), .mc_new_azimuth(mc_new_azimuth), - .ref_chirp_real(delayed_ref_i), // From latency buffer (long or short ref) - .ref_chirp_imag(delayed_ref_q), + .ref_chirp_real(ref_chirp_real), // 1-FF aligned ref (RX-B fix) + .ref_chirp_imag(ref_chirp_imag), .segment_request(segment_request), .mem_request(mem_request), .sample_addr_out(sample_addr_from_chain), diff --git a/9_Firmware/9_2_FPGA/run_regression.sh b/9_Firmware/9_2_FPGA/run_regression.sh index 6b12ac3..c2ecd03 100755 --- a/9_Firmware/9_2_FPGA/run_regression.sh +++ b/9_Firmware/9_2_FPGA/run_regression.sh @@ -69,6 +69,7 @@ PROD_RTL=( doppler_processor.v xfft_16.v fft_engine.v + frequency_matched_filter.v usb_data_interface.v usb_data_interface_ft2232h.v edge_detector.v @@ -84,7 +85,6 @@ PROD_RTL=( # (IBUFDS, BUFIO, BUFG, IDDR) that iverilog cannot compile. The production # design uses tb/ad9484_interface_400m_stub.v for simulation instead. EXTRA_RTL=( - frequency_matched_filter.v ) # --------------------------------------------------------------------------- @@ -102,6 +102,7 @@ RECEIVER_RTL=( chirp_memory_loader_param.v latency_buffer.v matched_filter_multi_segment.v matched_filter_processing_chain.v range_bin_decimator.v doppler_processor.v xfft_16.v fft_engine.v + frequency_matched_filter.v rx_gain_control.v mti_canceller.v ) @@ -281,7 +282,7 @@ run_mf_cosim() { if [[ -n "$define" ]]; then cmd="$cmd $define" fi - cmd="$cmd -o $vvp tb/tb_mf_cosim.v matched_filter_processing_chain.v fft_engine.v chirp_memory_loader_param.v" + cmd="$cmd -o $vvp tb/tb_mf_cosim.v matched_filter_processing_chain.v fft_engine.v frequency_matched_filter.v chirp_memory_loader_param.v" if ! eval "$cmd" 2>/tmp/iverilog_err_$$; then echo -e "${RED}COMPILE FAIL${NC}" @@ -464,14 +465,21 @@ if [[ "$SKIP_LINT" -eq 0 ]]; then run_lint_iverilog "production" "${PROD_RTL[@]}" # Layer A: standalone modules not in top-level hierarchy - for extra in "${EXTRA_RTL[@]}"; do - if [[ -f "$extra" ]]; then - run_lint_iverilog "$(basename "$extra" .v)" "$extra" - fi - done + # (use ${EXTRA_RTL[@]+...} guard so empty array doesn't trip set -u) + if [[ ${#EXTRA_RTL[@]} -gt 0 ]]; then + for extra in "${EXTRA_RTL[@]}"; do + if [[ -f "$extra" ]]; then + run_lint_iverilog "$(basename "$extra" .v)" "$extra" + fi + done + fi # Layer B: custom static regex checks - ALL_RTL=("${PROD_RTL[@]}" "${EXTRA_RTL[@]}") + if [[ ${#EXTRA_RTL[@]} -gt 0 ]]; then + ALL_RTL=("${PROD_RTL[@]}" "${EXTRA_RTL[@]}") + else + ALL_RTL=("${PROD_RTL[@]}") + fi run_lint_static "${ALL_RTL[@]}" echo "" @@ -629,10 +637,25 @@ run_test "FIR Lowpass" \ tb/tb_fir_reg.vvp \ tb/tb_fir_lowpass.v fir_lowpass.v -run_test "Matched Filter Chain" \ +run_test --timeout=600 "Matched Filter Chain" \ tb/tb_mf_reg.vvp \ tb/tb_matched_filter_processing_chain.v matched_filter_processing_chain.v \ - fft_engine.v chirp_memory_loader_param.v + fft_engine.v chirp_memory_loader_param.v frequency_matched_filter.v + +# RX-B regression coverage: chain pipeline depth + full-chain +# autocorrelation peak position. Both run the production fft_engine +# (no SIMULATION-only behavioural FFT exists). Long-running because +# the production FFT is BRAM-pipelined (~153k cycles per chain pass). +run_test --timeout=120 "RX-B Chain Pipeline Latency (tb_rxb_latency_measure)" \ + tb/tb_rxb_lat_reg.vvp \ + tb/tb_rxb_latency_measure.v matched_filter_processing_chain.v \ + fft_engine.v frequency_matched_filter.v + +run_test --timeout=600 "RX-B Full-Chain Autocorrelation (tb_rxb_fullchain_latency)" \ + tb/tb_rxb_fc_reg.vvp \ + tb/tb_rxb_fullchain_latency.v matched_filter_multi_segment.v \ + matched_filter_processing_chain.v fft_engine.v frequency_matched_filter.v \ + chirp_memory_loader_param.v echo "" diff --git a/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v b/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v index 230be7d..ed34464 100644 --- a/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v +++ b/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v @@ -499,10 +499,12 @@ always @(posedge clk_100m) begin mf_state_prev = dut.mf_dual.state; end // Processing chain state changes + // Note: fwd_in_count was a SIMULATION-only signal in the deleted inline + // behavioural FFT block; the production chain uses collect_count. if (dut.mf_dual.m_f_p_c.state != chain_state_prev) begin - $display("[CHAIN_DBG t=%0t] chain state: %0d -> %0d (fwd_count=%0d, out_count=%0d)", + $display("[CHAIN_DBG t=%0t] chain state: %0d -> %0d (collect_count=%0d, out_count=%0d)", $time, chain_state_prev, dut.mf_dual.m_f_p_c.state, - dut.mf_dual.m_f_p_c.fwd_in_count, dut.mf_dual.m_f_p_c.out_count); + dut.mf_dual.m_f_p_c.collect_count, dut.mf_dual.m_f_p_c.out_count); chain_state_prev = dut.mf_dual.m_f_p_c.state; end // Watch for fft_pc_valid while multi-seg is in ST_WAIT_FFT diff --git a/9_Firmware/9_2_FPGA/tb/tb_rxb_latency_measure.v b/9_Firmware/9_2_FPGA/tb/tb_rxb_latency_measure.v index 83bde66..26e820c 100644 --- a/9_Firmware/9_2_FPGA/tb/tb_rxb_latency_measure.v +++ b/9_Firmware/9_2_FPGA/tb/tb_rxb_latency_measure.v @@ -152,13 +152,17 @@ module tb_rxb_latency_measure; $display("First adc_valid : cycle %0d", cycle_in_first); $display("First valid output : cycle %0d", cycle_out_first); $display("Pipeline latency : %0d cycles", pipeline_latency); - $display("Current LATENCY in latency_buffer: 3187 cycles"); - $display("Delta (measured - configured): %0d cycles", pipeline_latency - 3187); $display(""); - $display("Interpretation:"); - $display(" - If delta is near 0, LATENCY=3187 is correct."); - $display(" - Note: this measures only the chain's internal pipeline."); - $display(" Full LATENCY also accounts for upstream multi_segment buffer fill."); + // Behavioural-FFT chain pipeline depth measured at 2057 cycles + // (cycle 4 in -> cycle 2061 out). Allow +/-50 cycle drift before + // failing — protects against silent regressions in chain timing. + if (pipeline_latency >= 2007 && pipeline_latency <= 2107) begin + $display("[PASS] Chain pipeline latency = %0d cycles (in expected 2007..2107 range)", + pipeline_latency); + end else begin + $display("[FAIL] Chain pipeline latency = %0d cycles, expected ~2057 (2007..2107)", + pipeline_latency); + end end else begin $display("\n=== TIMEOUT ==="); $display("range_profile_valid never asserted within 60000 cycles");