mirror of
https://github.com/NawfalMotii79/PLFM_RADAR.git
synced 2026-06-08 22:47:16 +00:00
AUDIT-C7: document GO/SO edge-bin Pfa drift in cfar_ca header
cfar_ca.v's GO/SO modes correctly cross-multiply to pick the side with the greater (GO) or lesser (SO) per-cell average, but return that side's RAW SUM as the noise estimate -- not the average. Combined with alpha being pre-baked for the interior training-cell count, this means at edges where the picked side is truncated, effective Pfa shifts by the count ratio (up to ~2x in the first/last r_train bins). CA mode's edge behavior was already documented; GO/SO's was not. Documentation only -- no RTL behavior change. The audit's preferred fix (divide noise_sum by selected_count) is explicitly NOT applied: per-CUT integer divide is expensive in 50T fabric and the affected bins are platform clutter (0..60 m) or noise floor (3012..3072 m) where edge errors are masked by other effects. Operators tuning Pfa have three documented options: (a) accept the asymmetry, (b) host-side skip GO/SO outside r_train..NRANGE-r_train and fall back to CA there, (c) hand-tune alpha per-mode based on observed Pfa drift. Changes: - cfar_ca.v header "CFAR Modes" table: GO/SO now explicitly note that selection is by average but return value is raw sum. - cfar_ca.v header "Edge handling": new GO/SO caveat paragraph. - cfar_ca.v ST_CFAR_THR mode 2'b01/2'b10 selectors: inline AUDIT-C7 comment pointing to header. Verification: full regression 41/41 PASS, 0 lint regressions.
This commit is contained in:
@@ -27,9 +27,11 @@
|
||||
*
|
||||
* CFAR Modes (cfg_cfar_mode):
|
||||
* 2'b00 = CA-CFAR: noise = leading_sum + lagging_sum
|
||||
* 2'b01 = GO-CFAR: noise = max(leading_sum * lag_cnt, lagging_sum * lead_cnt)
|
||||
* normalized — picks larger average
|
||||
* 2'b10 = SO-CFAR: noise = min(leading_sum * lag_cnt, lagging_sum * lead_cnt)
|
||||
* 2'b01 = GO-CFAR: pick side with greater PER-CELL AVERAGE (compare via
|
||||
* cross-multiply: leading_sum*lag_cnt vs lagging_sum*lead_cnt),
|
||||
* then return that side's RAW SUM (NOT divided by its
|
||||
* count — see GO/SO edge caveat in "Edge handling" below)
|
||||
* 2'b10 = SO-CFAR: pick side with smaller per-cell average, return its raw sum
|
||||
* 2'b11 = Reserved (falls back to CA-CFAR)
|
||||
*
|
||||
* Threshold computation:
|
||||
@@ -46,6 +48,25 @@
|
||||
* false alarm rate at edges — acceptable for radar (edge bins are
|
||||
* typically clutter).
|
||||
*
|
||||
* GO/SO edge caveat (AUDIT-C7): the cross-multiply correctly picks the
|
||||
* side with the greater (GO) or lesser (SO) per-cell average, but the
|
||||
* returned noise_sum is the raw SUM from the selected side, not the
|
||||
* average. Combined with `alpha` being pre-baked for the interior
|
||||
* training-cell count, this means at edges where the picked side has
|
||||
* fewer than `train` cells the effective Pfa shifts by the same factor
|
||||
* as the cell count (up to ~2x at the first/last `r_train` bins). For
|
||||
* the typical config (r_train=8, r_guard=2) the asymmetry only affects
|
||||
* the first/last ~10 of 512 range bins — for production 3 km mode that
|
||||
* is 0..60 m (platform clutter) and 3012..3072 m (noise floor) where
|
||||
* edge errors are masked by other effects.
|
||||
*
|
||||
* The fix — divide by selected_count — is explicitly NOT applied:
|
||||
* per-CUT integer divide is expensive in fabric and the affected
|
||||
* bins are clutter/noise. Operators tuning Pfa at edges should either
|
||||
* (a) accept the asymmetry, (b) host-side skip GO/SO outside
|
||||
* r_train..NRANGE-r_train and fall back to CA there, or (c) hand-tune
|
||||
* alpha per-mode based on observed Pfa drift.
|
||||
*
|
||||
* Timing:
|
||||
* Phase 2 takes ~(514 + T + 3*512) * 32 ≈ 55000 cycles per frame @ 100 MHz
|
||||
* = 0.55 ms. Frame period @ PRF=1932 Hz, 32 chirps = 16.6 ms. Fits easily.
|
||||
@@ -263,6 +284,11 @@ always @(*) begin
|
||||
noise_sum_comb = leading_sum + lagging_sum;
|
||||
end
|
||||
2'b01: begin // GO-CFAR: pick sum from side with greater average
|
||||
// AUDIT-C7: cross-multiply chooses by per-cell AVERAGE, but we return
|
||||
// the raw SUM (not divided by selected count). At range edges where
|
||||
// the picked side is truncated, effective Pfa shifts by the count
|
||||
// ratio. Trade-off accepted; per-CUT divide is too expensive in
|
||||
// 50T fabric. See module header "Edge handling / GO/SO edge caveat".
|
||||
if (leading_count > 0 && lagging_count > 0) begin
|
||||
// leading_avg > lagging_avg ↔ leading_sum * lagging_count > lagging_sum * leading_count
|
||||
if (leading_sum * lagging_count > lagging_sum * leading_count)
|
||||
@@ -275,6 +301,7 @@ always @(*) begin
|
||||
noise_sum_comb = lagging_sum;
|
||||
end
|
||||
2'b10: begin // SO-CFAR: pick sum from side with smaller average
|
||||
// AUDIT-C7: same selection-vs-normalization asymmetry as GO above.
|
||||
if (leading_count > 0 && lagging_count > 0) begin
|
||||
if (leading_sum * lagging_count < lagging_sum * leading_count)
|
||||
noise_sum_comb = leading_sum;
|
||||
|
||||
Reference in New Issue
Block a user