CIC comb pipeline registers, BUFG sim guard, system TB fix, regression runner
- cic_decimator_4x_enhanced.v: Add integrator_sampled_comb and data_valid_comb_pipe pipeline stages between integrator sampling and comb computation to break the critical path (matches remote 40cda0f) - radar_system_top.v: Wrap 3 BUFG instances in ifdef SIMULATION guard with pass-through assigns for iverilog compatibility - radar_system_tb.v: Convert generate_radar_echo function to task and move sin_lut declaration before task (iverilog declaration-order fix), add modular index clamping to prevent LUT out-of-bounds - run_regression.sh: Automated regression runner for all 18 FPGA testbenches with --quick mode. Results: 17 pass, 1 pre-existing fail - .gitignore: Exclude *.vvp, *.vcd simulation artifacts
This commit is contained in:
Executable
+245
@@ -0,0 +1,245 @@
|
||||
#!/bin/bash
|
||||
# ===========================================================================
|
||||
# FPGA Regression Test Runner for AERIS-10 Radar
|
||||
# Runs all verified iverilog testbenches and reports pass/fail summary.
|
||||
#
|
||||
# Usage: ./run_regression.sh [--quick]
|
||||
# --quick Skip long-running integration tests (receiver golden, system TB)
|
||||
#
|
||||
# Exit code: 0 if all tests pass, 1 if any fail
|
||||
# ===========================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
QUICK=0
|
||||
if [[ "${1:-}" == "--quick" ]]; then
|
||||
QUICK=1
|
||||
fi
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
SKIP=0
|
||||
ERRORS=""
|
||||
|
||||
# Colors (if terminal supports it)
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helper: compile and run a single testbench
|
||||
# run_test <name> <vvp_path> <iverilog_args...>
|
||||
# ---------------------------------------------------------------------------
|
||||
run_test() {
|
||||
local name="$1"
|
||||
local vvp="$2"
|
||||
shift 2
|
||||
local args=("$@")
|
||||
|
||||
printf " %-45s " "$name"
|
||||
|
||||
# Compile
|
||||
if ! iverilog -g2001 -DSIMULATION -o "$vvp" "${args[@]}" 2>/tmp/iverilog_err_$$; then
|
||||
echo -e "${RED}COMPILE FAIL${NC}"
|
||||
ERRORS="$ERRORS\n $name: compile error ($(head -1 /tmp/iverilog_err_$$))"
|
||||
FAIL=$((FAIL + 1))
|
||||
return
|
||||
fi
|
||||
|
||||
# Run
|
||||
local output
|
||||
output=$(timeout 120 vvp "$vvp" 2>&1) || true
|
||||
|
||||
# Count PASS/FAIL in output (testbenches use explicit [PASS]/[FAIL] markers)
|
||||
local test_pass test_fail
|
||||
test_pass=$(echo "$output" | grep -ci '\bPASS\b' || true)
|
||||
test_fail=$(echo "$output" | grep -ci '\bFAIL\b' || true)
|
||||
|
||||
if [[ "$test_fail" -gt 0 ]]; then
|
||||
echo -e "${RED}FAIL${NC} (pass=$test_pass, fail=$test_fail)"
|
||||
ERRORS="$ERRORS\n $name: $test_fail failure(s)"
|
||||
FAIL=$((FAIL + 1))
|
||||
elif [[ "$test_pass" -gt 0 ]]; then
|
||||
echo -e "${GREEN}PASS${NC} ($test_pass checks)"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
# No PASS/FAIL markers — check for clean completion
|
||||
if echo "$output" | grep -qi 'finish\|complete\|done'; then
|
||||
echo -e "${GREEN}PASS${NC} (completed)"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo -e "${YELLOW}UNKNOWN${NC} (no PASS/FAIL markers)"
|
||||
ERRORS="$ERRORS\n $name: no pass/fail markers in output"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "$vvp"
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
echo "============================================"
|
||||
echo " AERIS-10 FPGA Regression Test Suite"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "Date: $(date)"
|
||||
echo "iverilog: $(iverilog -V 2>&1 | head -1)"
|
||||
echo ""
|
||||
|
||||
# ===========================================================================
|
||||
# UNIT TESTS — Changed Modules (HIGH PRIORITY)
|
||||
# ===========================================================================
|
||||
echo "--- HIGH PRIORITY: Changed Modules ---"
|
||||
|
||||
run_test "CIC Decimator" \
|
||||
tb/tb_cic_reg.vvp \
|
||||
tb/tb_cic_decimator.v cic_decimator_4x_enhanced.v
|
||||
|
||||
run_test "Chirp Controller (BRAM)" \
|
||||
tb/tb_chirp_reg.vvp \
|
||||
tb/tb_chirp_controller.v plfm_chirp_controller.v
|
||||
|
||||
run_test "Chirp Contract" \
|
||||
tb/tb_chirp_ctr_reg.vvp \
|
||||
tb/tb_chirp_contract.v plfm_chirp_controller.v
|
||||
|
||||
run_test "Doppler Processor (DSP48)" \
|
||||
tb/tb_doppler_reg.vvp \
|
||||
tb/tb_doppler_cosim.v doppler_processor.v xfft_32.v fft_engine.v
|
||||
|
||||
echo ""
|
||||
|
||||
# ===========================================================================
|
||||
# INTEGRATION TESTS
|
||||
# ===========================================================================
|
||||
echo "--- INTEGRATION TESTS ---"
|
||||
|
||||
run_test "DDC Chain (NCO→CIC→FIR)" \
|
||||
tb/tb_ddc_reg.vvp \
|
||||
tb/tb_ddc_cosim.v ddc_400m.v nco_400m_enhanced.v \
|
||||
cic_decimator_4x_enhanced.v fir_lowpass.v cdc_modules.v
|
||||
|
||||
if [[ "$QUICK" -eq 0 ]]; then
|
||||
# Golden generate
|
||||
run_test "Receiver (golden generate)" \
|
||||
tb/tb_rx_golden_reg.vvp \
|
||||
-DGOLDEN_GENERATE \
|
||||
tb/tb_radar_receiver_final.v radar_receiver_final.v \
|
||||
radar_mode_controller.v tb/ad9484_interface_400m_stub.v \
|
||||
ddc_400m.v nco_400m_enhanced.v cic_decimator_4x_enhanced.v \
|
||||
cdc_modules.v fir_lowpass.v ddc_input_interface.v \
|
||||
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_32.v fft_engine.v
|
||||
|
||||
# Golden compare
|
||||
run_test "Receiver (golden compare)" \
|
||||
tb/tb_rx_compare_reg.vvp \
|
||||
tb/tb_radar_receiver_final.v radar_receiver_final.v \
|
||||
radar_mode_controller.v tb/ad9484_interface_400m_stub.v \
|
||||
ddc_400m.v nco_400m_enhanced.v cic_decimator_4x_enhanced.v \
|
||||
cdc_modules.v fir_lowpass.v ddc_input_interface.v \
|
||||
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_32.v fft_engine.v
|
||||
|
||||
# Full system top
|
||||
run_test "System Top (radar_system_tb)" \
|
||||
tb/tb_system_reg.vvp \
|
||||
tb/radar_system_tb.v radar_system_top.v \
|
||||
radar_transmitter.v dac_interface_single.v plfm_chirp_controller.v \
|
||||
radar_receiver_final.v tb/ad9484_interface_400m_stub.v \
|
||||
ddc_400m.v nco_400m_enhanced.v cic_decimator_4x_enhanced.v \
|
||||
cdc_modules.v fir_lowpass.v ddc_input_interface.v \
|
||||
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_32.v fft_engine.v \
|
||||
usb_data_interface.v edge_detector.v radar_mode_controller.v
|
||||
else
|
||||
echo " (skipped receiver golden + system top — use without --quick)"
|
||||
SKIP=$((SKIP + 3))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# ===========================================================================
|
||||
# UNIT TESTS — Signal Processing
|
||||
# ===========================================================================
|
||||
echo "--- UNIT TESTS: Signal Processing ---"
|
||||
|
||||
run_test "FFT Engine" \
|
||||
tb/tb_fft_reg.vvp \
|
||||
tb/tb_fft_engine.v fft_engine.v
|
||||
|
||||
run_test "XFFT-32 Wrapper" \
|
||||
tb/tb_xfft_reg.vvp \
|
||||
tb/tb_xfft_32.v xfft_32.v fft_engine.v
|
||||
|
||||
run_test "NCO 400MHz" \
|
||||
tb/tb_nco_reg.vvp \
|
||||
tb/tb_nco_400m.v nco_400m_enhanced.v
|
||||
|
||||
run_test "FIR Lowpass" \
|
||||
tb/tb_fir_reg.vvp \
|
||||
tb/tb_fir_lowpass.v fir_lowpass.v
|
||||
|
||||
run_test "Matched Filter Chain" \
|
||||
tb/tb_mf_reg.vvp \
|
||||
tb/tb_matched_filter_processing_chain.v matched_filter_processing_chain.v \
|
||||
xfft_32.v fft_engine.v chirp_memory_loader_param.v
|
||||
|
||||
echo ""
|
||||
|
||||
# ===========================================================================
|
||||
# UNIT TESTS — Infrastructure
|
||||
# ===========================================================================
|
||||
echo "--- UNIT TESTS: Infrastructure ---"
|
||||
|
||||
run_test "CDC Modules (3 variants)" \
|
||||
tb/tb_cdc_reg.vvp \
|
||||
tb/tb_cdc_modules.v cdc_modules.v
|
||||
|
||||
run_test "Edge Detector" \
|
||||
tb/tb_edge_reg.vvp \
|
||||
tb/tb_edge_detector.v edge_detector.v
|
||||
|
||||
run_test "USB Data Interface" \
|
||||
tb/tb_usb_reg.vvp \
|
||||
tb/tb_usb_data_interface.v usb_data_interface.v
|
||||
|
||||
run_test "Range Bin Decimator" \
|
||||
tb/tb_rbd_reg.vvp \
|
||||
tb/tb_range_bin_decimator.v range_bin_decimator.v
|
||||
|
||||
run_test "Radar Mode Controller" \
|
||||
tb/tb_rmc_reg.vvp \
|
||||
tb/tb_radar_mode_controller.v radar_mode_controller.v
|
||||
|
||||
echo ""
|
||||
|
||||
# ===========================================================================
|
||||
# SUMMARY
|
||||
# ===========================================================================
|
||||
TOTAL=$((PASS + FAIL + SKIP))
|
||||
echo "============================================"
|
||||
echo " RESULTS: $PASS passed, $FAIL failed, $SKIP skipped / $TOTAL total"
|
||||
echo "============================================"
|
||||
|
||||
if [[ -n "$ERRORS" ]]; then
|
||||
echo ""
|
||||
echo "Failures:"
|
||||
echo -e "$ERRORS"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Exit with error if any failures
|
||||
if [[ "$FAIL" -gt 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user