mirror of
https://github.com/NawfalMotii79/PLFM_RADAR.git
synced 2026-05-17 13:21:54 +00:00
fix(fpga): RX-NEW-2 — replace impossible peak/mean assertions with flatness bounds
The Group 3 (tone autocorrelation), Group 10 (golden DC autocorr), and
Group 11 (golden tone autocorr) tests asserted cap_max_abs > mean_abs * 2,
which is mathematically impossible for those stimuli regardless of FFT
precision:
- DC autocorrelation produces a constant-magnitude time-domain output
(peak/mean ≡ 1.0 by definition).
- Single-tone autocorrelation produces a constant-magnitude rotating
phasor; |I|+|Q| envelope varies in [|X|^2, sqrt(2)*|X|^2], so
peak/mean is bounded by ~1.41x.
Empirical RTL output ratios from this regression: DC=1.07x, Tone5=1.18x,
Chirp=3.14x, Impulse=2015x — confirming theory and confirming the FFT
engine is correct for narrow-spectrum inputs.
Replace each ">2x" check with mean>0 && peak<=mean*2 (flatness bound).
Still catches flat-zero output (mean=0) but admits the correct constant-
magnitude result.
Matched Filter Chain regression: 5 failures -> 2 failures.
This commit is contained in:
@@ -338,9 +338,13 @@ module tb_matched_filter_processing_chain;
|
||||
// not "behavioral noise". See project memory ledger entry RX-NEW-1.
|
||||
$display("[FAIL-INFO] Autocorrelation peak at bin %0d (expected 0) — fft_engine bug, see RX-NEW-1", cap_peak_bin);
|
||||
end
|
||||
// Behavioral Q15 FFT scatters the peak, so we cannot assert bin
|
||||
// location — but the peak MUST dominate the mean magnitude. This
|
||||
// catches an all-zero/flat output that the old tautology allowed.
|
||||
// RX-NEW-2: For autocorrelation of a *single complex tone*, the time-
|
||||
// domain output is a rotating phasor of constant complex magnitude.
|
||||
// Its |I|+|Q| envelope therefore stays bounded in [|X|^2, sqrt(2)*|X|^2]
|
||||
// — peak/mean is mathematically ~1.0..1.41x, never >2x. The earlier
|
||||
// ">2x" assertion was unsatisfiable regardless of FFT precision.
|
||||
// Correct invariant: output is non-zero and approximately constant-
|
||||
// magnitude (peak/mean <= 2x), which still catches flat-zero output.
|
||||
begin : p2m_grp3
|
||||
integer k, sum_abs, mean_abs;
|
||||
sum_abs = 0;
|
||||
@@ -353,8 +357,8 @@ module tb_matched_filter_processing_chain;
|
||||
$display(" Peak-to-mean |out|: peak=%0d mean=%0d ratio~%0dx",
|
||||
cap_max_abs, mean_abs,
|
||||
(mean_abs == 0) ? 999999 : cap_max_abs / mean_abs);
|
||||
check(cap_max_abs > mean_abs * 2,
|
||||
"Autocorrelation peak dominates mean (>2x)");
|
||||
check(mean_abs > 0 && cap_max_abs <= mean_abs * 2,
|
||||
"Tone autocorr: non-zero, approx constant-magnitude (ratio<=2x)");
|
||||
end
|
||||
check(cap_max_abs > 0, "Peak magnitude > 0");
|
||||
|
||||
@@ -502,6 +506,9 @@ module tb_matched_filter_processing_chain;
|
||||
if (!(cap_peak_bin <= 128 || cap_peak_bin >= FFT_SIZE - 128)) begin
|
||||
$display("[FAIL-INFO] Case 1: peak at bin %0d (expected 0) — fft_engine bug, see RX-NEW-1", cap_peak_bin);
|
||||
end
|
||||
// RX-NEW-2: DC autocorrelation produces a constant-magnitude output
|
||||
// in the time domain (peak == mean by definition). Use a flatness
|
||||
// bound (peak/mean <= 2x) instead of an unsatisfiable ">2x" check.
|
||||
begin : p2m_case1
|
||||
integer k, sum_abs, mean_abs;
|
||||
sum_abs = 0;
|
||||
@@ -511,8 +518,8 @@ module tb_matched_filter_processing_chain;
|
||||
+ (cap_out_q[k][15] ? -cap_out_q[k] : cap_out_q[k]);
|
||||
end
|
||||
mean_abs = sum_abs / FFT_SIZE;
|
||||
check(cap_max_abs > mean_abs * 2,
|
||||
"Case 1: Peak dominates mean (>2x, catches flat/zero output)");
|
||||
check(mean_abs > 0 && cap_max_abs <= mean_abs * 2,
|
||||
"Case 1: DC autocorr non-zero, approx constant (ratio<=2x)");
|
||||
end
|
||||
check(cap_max_abs > 0, "Case 1: Peak magnitude > 0");
|
||||
|
||||
@@ -544,6 +551,8 @@ module tb_matched_filter_processing_chain;
|
||||
if (!(cap_peak_bin <= 128 || cap_peak_bin >= FFT_SIZE - 128)) begin
|
||||
$display("[FAIL-INFO] Case 2: peak at bin %0d (expected near 0) — fft_engine bug, see RX-NEW-1", cap_peak_bin);
|
||||
end
|
||||
// RX-NEW-2: Tone autocorrelation is a rotating phasor — see Group 3
|
||||
// comment. peak/mean cannot exceed sqrt(2)x mathematically.
|
||||
begin : p2m_case2
|
||||
integer k, sum_abs, mean_abs;
|
||||
sum_abs = 0;
|
||||
@@ -553,8 +562,8 @@ module tb_matched_filter_processing_chain;
|
||||
+ (cap_out_q[k][15] ? -cap_out_q[k] : cap_out_q[k]);
|
||||
end
|
||||
mean_abs = sum_abs / FFT_SIZE;
|
||||
check(cap_max_abs > mean_abs * 2,
|
||||
"Case 2: Peak dominates mean (>2x, catches flat/zero output)");
|
||||
check(mean_abs > 0 && cap_max_abs <= mean_abs * 2,
|
||||
"Case 2: Tone autocorr non-zero, approx constant (ratio<=2x)");
|
||||
end
|
||||
check(cap_max_abs > 0, "Case 2: Peak magnitude > 0");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user