Integrate MTI canceller and DC notch filter for ground clutter removal

MTI canceller (2-pulse, H(z)=1-z^{-1}) between range decimator and
Doppler processor. Subtracts previous chirp from current, nulling DC
Doppler (stationary clutter). Pass-through when host_mti_enable=0.

DC notch filter (post-Doppler, pre-CFAR) zeros bins within
+/-host_dc_notch_width of DC. Complements MTI for residual clutter.

New host registers: 0x26 (mti_enable), 0x27 (dc_notch_width).
Both default to 0 (disabled) - fully backward-compatible.

Verification: 23/23 regression, 29/29 MTI standalone, 3/3 real-data
co-sim (5137/5137 exact match) all PASS.
This commit is contained in:
Jason
2026-03-20 16:39:17 +02:00
parent 075ae1e77a
commit ed629e7559
5 changed files with 751 additions and 14 deletions
+38 -4
View File
@@ -51,7 +51,11 @@ module radar_receiver_final (
input wire stm32_new_azimuth_rx,
// CFAR integration: expose Doppler frame_complete to top level
output wire doppler_frame_done_out
output wire doppler_frame_done_out,
// Ground clutter removal controls
input wire host_mti_enable, // 1=MTI active, 0=pass-through
input wire [2:0] host_dc_notch_width // DC notch: zero Doppler bins within ±width of DC
);
// ========== INTERNAL SIGNALS ==========
@@ -102,6 +106,13 @@ wire signed [15:0] decimated_range_q;
wire decimated_range_valid;
wire [5:0] decimated_range_bin;
// ========== MTI CANCELLER SIGNALS ==========
wire signed [15:0] mti_range_i;
wire signed [15:0] mti_range_q;
wire mti_range_valid;
wire [5:0] mti_range_bin;
wire mti_first_chirp;
// ========== RADAR MODE CONTROLLER SIGNALS ==========
wire rmc_scanning;
wire rmc_scan_complete;
@@ -191,7 +202,7 @@ ddc_400m_enhanced ddc(
.baseband_valid_i(ddc_valid_i), // Valid at 100MHz
.baseband_valid_q(ddc_valid_q),
.mixers_enable(1'b1)
);
);
ddc_input_interface ddc_if (
.clk(clk),
@@ -328,6 +339,28 @@ range_bin_decimator #(
.watchdog_timeout() // Diagnostic unconnected (monitored via ILA if needed)
);
// ========== MTI CANCELLER (Ground Clutter Removal) ==========
// 2-pulse canceller: subtracts previous chirp from current chirp.
// H(z) = 1 - z^{-1} null at DC Doppler, removes stationary clutter.
// When host_mti_enable=0: transparent pass-through.
mti_canceller #(
.NUM_RANGE_BINS(64),
.DATA_WIDTH(16)
) mti_inst (
.clk(clk),
.reset_n(reset_n),
.range_i_in(decimated_range_i),
.range_q_in(decimated_range_q),
.range_valid_in(decimated_range_valid),
.range_bin_in(decimated_range_bin),
.range_i_out(mti_range_i),
.range_q_out(mti_range_q),
.range_valid_out(mti_range_valid),
.range_bin_out(mti_range_bin),
.mti_enable(host_mti_enable),
.mti_first_chirp(mti_first_chirp)
);
// ========== FRAME SYNC USING chirp_counter ==========
reg [5:0] chirp_counter_prev;
reg new_frame_pulse;
@@ -360,8 +393,9 @@ end
assign new_chirp_frame = new_frame_pulse;
// ========== DATA PACKING FOR DOPPLER ==========
assign range_data_32bit = {decimated_range_q, decimated_range_i};
assign range_data_valid = decimated_range_valid;
// Use MTI-filtered data (or pass-through if MTI disabled)
assign range_data_32bit = {mti_range_q, mti_range_i};
assign range_data_valid = mti_range_valid;
// ========== DOPPLER PROCESSOR ==========
doppler_processor_optimized #(