mirror of
https://github.com/NawfalMotii79/PLFM_RADAR.git
synced 2026-06-10 23:41:18 +00:00
chirp-v2 PR-F: doppler/CFAR widen to 3 sub-frames + 2-class detect
Bumps RP_CHIRPS_PER_FRAME 32 -> 48 (= 3 sub-frames × 16 chirps), widens
doppler_bin from 5 to 6 bits ({sub_frame[1:0], bin[3:0]}), and replaces the
1-bit detect_flag rail with a 2-bit detect_class (NONE / CANDIDATE /
CONFIRMED) sourced from a soft+confirm CFAR threshold pair.
doppler_processor:
Generalised the 2-subframe FSM to NUM_SUBFRAMES = CHIRPS_PER_FRAME /
CHIRPS_PER_SUBFRAME (=3 in production, =2 when TBs override). S_OUTPUT
walks current_sub_frame 0..NUM_SUBFRAMES-1 then advances range_bin;
the chirp_base * CHIRPS_PER_SUBFRAME formula replaces the if/else split.
write_chirp_index, read_doppler_index, sub_frame, current_sub_frame all
widened to 6/2 bits accordingly. doppler_bin packing {current_sub_frame[1:0],
fft_sample_counter[3:0]} naturally yields 6 bits.
cfar_ca:
Adds cfg_alpha_soft input + r_alpha_soft register (default
RP_DEF_CFAR_ALPHA_SOFT = 0x18 ≈ 1.5 in Q4.4 → Pfa_soft ≈ 1e-5). ST_CFAR_MUL
computes both noise_product (alpha) and noise_product_soft (alpha_soft) in
parallel DSPs; ST_CFAR_CMP emits detect_class = CONFIRMED when cur > thr,
CANDIDATE when cur > thr_soft (and not CONFIRMED), NONE otherwise.
detect_flag is preserved as (class != NONE) for backward compat.
Address packing now pads doppler axis to next power-of-2 (DOPPLER_PAD =
1 << ceil(log2(NUM_DOPPLER))) so {range, doppler} packs contiguously
for both NUM_DOPPLER=32 (legacy TB) and NUM_DOPPLER=48 (production).
Mag-BRAM grows from ~16 to ~30 RAMB18 on 50T (acceptable on the budget).
usb_data_interface_ft2232h:
doppler_bin_in widened to 6 bits. FRAME_CELLS pads to next power of two
(32K) so {range, doppler[5:0]} concatenation lands cleanly. Address regs
bumped: mag_wr/rd_addr 14→15, detect_byte_addr 11→12, detect_clear bit-
counter 14→15. Detect-bit BRAM grows 2K→4K bytes. Wire-protocol byte
counts auto-scale with FRAME_CELLS / DOPPLER_MAG_SECTION_BYTES; PR-G
bumps the bulk-frame protocol version so the host parser knows.
Other:
- radar_params.vh: RP_CHIRPS_PER_FRAME 32→48, RP_NUM_DOPPLER_BINS 32→48,
RP_DOPPLER_MEM_ADDR_W 14→15 (50T) / 17→18 (200T), RP_CFAR_MAG_ADDR_W
likewise. Other macros (RP_DOPPLER_BIN_WIDTH=6, RP_DETECT_CLASS_WIDTH=2,
RP_DEF_CFAR_ALPHA_SOFT=0x18, RP_NUM_SUBFRAMES=3) were already in place
from PR-A.
- radar_system_top: rx_doppler_bin / dbg_doppler_bin widened. Adds
host_cfar_alpha_soft register (default RP_DEF_CFAR_ALPHA_SOFT). USB
opcode mapping deferred to PR-G.
- radar_system_top_50t: dbg_doppler_bin_nc width.
- radar_receiver_final: doppler_bin port width.
Test summary:
- tb_chirp_controller_v2: 43/43 PASS
- tb_chirp_contract: 10/10 PASS
- tb_cfar_ca: 24/0 PASS
- tb_mti_canceller: 43/43 PASS
- tb_rxb_fullchain: peak 24033 ~80x (parity with PR-D/E)
- tb_doppler_realdata: 2056/2056 PASS (had been broken pre-PR-F due
to missing RANGE_BINS=64 override; this PR fixes
the parameter override along with the widening)
- tb_system_e2e: 33/49 PASS — identical to PR-E baseline; the
one new fail vs PR-D (G2.2) carries over.
- tb_radar_receiver_final: still finishing in background (~10 min).
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
* T14: cfar_busy asserts during processing, deasserts after
|
||||
*/
|
||||
|
||||
`include "radar_params.vh"
|
||||
|
||||
module tb_cfar_ca;
|
||||
|
||||
// ============================================================================
|
||||
@@ -43,24 +45,28 @@ reg reset_n;
|
||||
|
||||
reg [31:0] doppler_data;
|
||||
reg doppler_valid;
|
||||
reg [4:0] doppler_bin_in;
|
||||
reg [5:0] range_bin_in;
|
||||
reg [`RP_DOPPLER_BIN_WIDTH-1:0] doppler_bin_in;
|
||||
reg [`RP_RANGE_BIN_WIDTH_MAX-1:0] range_bin_in;
|
||||
reg frame_complete;
|
||||
|
||||
reg [3:0] cfg_guard_cells;
|
||||
reg [4:0] cfg_train_cells;
|
||||
reg [ALPHA_W-1:0] cfg_alpha;
|
||||
reg [ALPHA_W-1:0] cfg_alpha_soft; // PR-F
|
||||
reg [1:0] cfg_cfar_mode;
|
||||
reg cfg_cfar_enable;
|
||||
reg [15:0] cfg_simple_threshold;
|
||||
|
||||
wire detect_flag;
|
||||
wire [`RP_DETECT_CLASS_WIDTH-1:0] detect_class; // PR-F
|
||||
wire detect_valid;
|
||||
wire [5:0] detect_range;
|
||||
wire [4:0] detect_doppler;
|
||||
wire [`RP_RANGE_BIN_WIDTH_MAX-1:0] detect_range;
|
||||
wire [`RP_DOPPLER_BIN_WIDTH-1:0] detect_doppler;
|
||||
wire [MAG_W-1:0] detect_magnitude;
|
||||
wire [MAG_W-1:0] detect_threshold;
|
||||
wire [MAG_W-1:0] detect_threshold_soft; // PR-F
|
||||
wire [15:0] detect_count;
|
||||
wire [15:0] detect_count_cand; // PR-F
|
||||
wire cfar_busy;
|
||||
wire [7:0] cfar_status;
|
||||
|
||||
@@ -84,8 +90,8 @@ reg [255:0] test_name;
|
||||
|
||||
// Detection capture (flagged detections only)
|
||||
integer det_cap_count;
|
||||
reg [5:0] det_cap_range [0:255];
|
||||
reg [4:0] det_cap_doppler[0:255];
|
||||
reg [`RP_RANGE_BIN_WIDTH_MAX-1:0] det_cap_range [0:255];
|
||||
reg [`RP_DOPPLER_BIN_WIDTH-1:0] det_cap_doppler[0:255];
|
||||
reg [MAG_W-1:0] det_cap_mag[0:255];
|
||||
reg [MAG_W-1:0] det_cap_thr[0:255];
|
||||
reg det_cap_flag [0:255];
|
||||
@@ -110,16 +116,20 @@ cfar_ca #(
|
||||
.cfg_guard_cells(cfg_guard_cells),
|
||||
.cfg_train_cells(cfg_train_cells),
|
||||
.cfg_alpha(cfg_alpha),
|
||||
.cfg_alpha_soft(cfg_alpha_soft), // PR-F
|
||||
.cfg_cfar_mode(cfg_cfar_mode),
|
||||
.cfg_cfar_enable(cfg_cfar_enable),
|
||||
.cfg_simple_threshold(cfg_simple_threshold),
|
||||
.detect_flag(detect_flag),
|
||||
.detect_class(detect_class), // PR-F
|
||||
.detect_valid(detect_valid),
|
||||
.detect_range(detect_range),
|
||||
.detect_doppler(detect_doppler),
|
||||
.detect_magnitude(detect_magnitude),
|
||||
.detect_threshold(detect_threshold),
|
||||
.detect_threshold_soft(detect_threshold_soft), // PR-F
|
||||
.detect_count(detect_count),
|
||||
.detect_count_cand(detect_count_cand), // PR-F
|
||||
.cfar_busy(cfar_busy),
|
||||
.cfar_status(cfar_status)
|
||||
);
|
||||
@@ -165,8 +175,8 @@ endtask
|
||||
|
||||
// Feed one Doppler sample (I/Q packed as {Q, I})
|
||||
task feed_sample;
|
||||
input [5:0] rbin;
|
||||
input [4:0] dbin;
|
||||
input [`RP_RANGE_BIN_WIDTH_MAX-1:0] rbin;
|
||||
input [`RP_DOPPLER_BIN_WIDTH-1:0] dbin;
|
||||
input signed [15:0] i_val;
|
||||
input signed [15:0] q_val;
|
||||
begin
|
||||
@@ -184,8 +194,8 @@ endtask
|
||||
// noise_level: base I value for all cells
|
||||
// num_targets: number of target cells
|
||||
// tgt_range[0..3], tgt_doppler[0..3], tgt_level[0..3]: target parameters
|
||||
reg [5:0] tgt_range [0:7];
|
||||
reg [4:0] tgt_doppler[0:7];
|
||||
reg [`RP_RANGE_BIN_WIDTH_MAX-1:0] tgt_range [0:7];
|
||||
reg [`RP_DOPPLER_BIN_WIDTH-1:0] tgt_doppler[0:7];
|
||||
reg [15:0] tgt_level [0:7];
|
||||
integer num_targets;
|
||||
|
||||
@@ -207,7 +217,9 @@ task feed_frame;
|
||||
i_val = tgt_level[t];
|
||||
end
|
||||
end
|
||||
feed_sample(r[5:0], d[4:0], $signed(i_val), 16'sd0);
|
||||
feed_sample(r[`RP_RANGE_BIN_WIDTH_MAX-1:0],
|
||||
d[`RP_DOPPLER_BIN_WIDTH-1:0],
|
||||
$signed(i_val), 16'sd0);
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -304,6 +316,11 @@ initial begin
|
||||
cfg_guard_cells = 4'd2;
|
||||
cfg_train_cells = 5'd8;
|
||||
cfg_alpha = 8'h30;
|
||||
// PR-F: pin alpha_soft to max so the candidate tier never triggers in
|
||||
// these tests — preserves the original "detect_flag means CONFIRMED"
|
||||
// semantics. The 2-class detection path is exercised by tb_system_e2e
|
||||
// (live data) rather than this unit test.
|
||||
cfg_alpha_soft = 8'hFF;
|
||||
cfg_cfar_mode = 2'b00;
|
||||
cfg_cfar_enable = 1'b1;
|
||||
cfg_simple_threshold = 16'd5000;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
* vvp tb/tb_doppler_realdata.vvp
|
||||
*/
|
||||
|
||||
`include "radar_params.vh"
|
||||
|
||||
module tb_doppler_realdata;
|
||||
|
||||
// ============================================================================
|
||||
@@ -56,16 +58,23 @@ reg data_valid;
|
||||
reg new_chirp_frame;
|
||||
wire [31:0] doppler_output;
|
||||
wire doppler_valid;
|
||||
wire [4:0] doppler_bin;
|
||||
wire [5:0] range_bin;
|
||||
wire [`RP_DOPPLER_BIN_WIDTH-1:0] doppler_bin;
|
||||
wire [`RP_RANGE_BIN_WIDTH_MAX-1:0] range_bin;
|
||||
wire processing_active;
|
||||
wire frame_complete;
|
||||
wire [3:0] dut_status;
|
||||
|
||||
// ============================================================================
|
||||
// DUT INSTANTIATION
|
||||
// DUT INSTANTIATION — override CHIRPS_PER_FRAME=32 to keep this TB compatible
|
||||
// with the legacy 2-subframe golden vectors (chirp-v2 production runs 3
|
||||
// sub-frames at 48 chirps/frame; the Doppler FSM is parameterised over
|
||||
// NUM_SUBFRAMES = CHIRPS_PER_FRAME / CHIRPS_PER_SUBFRAME).
|
||||
// ============================================================================
|
||||
doppler_processor_optimized dut (
|
||||
doppler_processor_optimized #(
|
||||
.CHIRPS_PER_FRAME(32),
|
||||
.CHIRPS_PER_SUBFRAME(16),
|
||||
.RANGE_BINS(64)
|
||||
) dut (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.range_data(range_data),
|
||||
@@ -109,8 +118,8 @@ end
|
||||
// ============================================================================
|
||||
reg signed [15:0] cap_out_i [0:TOTAL_OUTPUTS-1];
|
||||
reg signed [15:0] cap_out_q [0:TOTAL_OUTPUTS-1];
|
||||
reg [5:0] cap_rbin [0:TOTAL_OUTPUTS-1];
|
||||
reg [4:0] cap_dbin [0:TOTAL_OUTPUTS-1];
|
||||
reg [`RP_RANGE_BIN_WIDTH_MAX-1:0] cap_rbin [0:TOTAL_OUTPUTS-1];
|
||||
reg [`RP_DOPPLER_BIN_WIDTH-1:0] cap_dbin [0:TOTAL_OUTPUTS-1];
|
||||
integer out_count;
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
* vvp tb/tb_fullchain_realdata.vvp
|
||||
*/
|
||||
|
||||
`include "radar_params.vh"
|
||||
|
||||
module tb_fullchain_realdata;
|
||||
|
||||
// ============================================================================
|
||||
@@ -91,8 +93,8 @@ reg new_chirp_frame;
|
||||
|
||||
wire [31:0] doppler_output;
|
||||
wire doppler_valid;
|
||||
wire [4:0] doppler_bin;
|
||||
wire [5:0] range_bin;
|
||||
wire [`RP_DOPPLER_BIN_WIDTH-1:0] doppler_bin;
|
||||
wire [`RP_RANGE_BIN_WIDTH_MAX-1:0] range_bin;
|
||||
wire processing_active;
|
||||
wire frame_complete;
|
||||
wire [3:0] dut_status;
|
||||
@@ -122,7 +124,14 @@ range_bin_decimator #(
|
||||
// ============================================================================
|
||||
// DUT INSTANTIATION: Doppler Processor
|
||||
// ============================================================================
|
||||
doppler_processor_optimized doppler_proc (
|
||||
doppler_processor_optimized #(
|
||||
// Override CHIRPS_PER_FRAME / RANGE_BINS to keep this TB compatible with
|
||||
// the legacy 2-subframe golden vectors (chirp-v2 production uses 48
|
||||
// chirps × 512 ranges; this co-sim runs 32 × 64).
|
||||
.CHIRPS_PER_FRAME(32),
|
||||
.CHIRPS_PER_SUBFRAME(16),
|
||||
.RANGE_BINS(64)
|
||||
) doppler_proc (
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.range_data(range_data_32bit),
|
||||
@@ -174,8 +183,8 @@ reg signed [15:0] decim_cap_q [0:CHIRPS*RANGE_BINS-1];
|
||||
// ============================================================================
|
||||
reg signed [15:0] cap_out_i [0:TOTAL_OUTPUT_SAMPLES-1];
|
||||
reg signed [15:0] cap_out_q [0:TOTAL_OUTPUT_SAMPLES-1];
|
||||
reg [5:0] cap_rbin [0:TOTAL_OUTPUT_SAMPLES-1];
|
||||
reg [4:0] cap_dbin [0:TOTAL_OUTPUT_SAMPLES-1];
|
||||
reg [`RP_RANGE_BIN_WIDTH_MAX-1:0] cap_rbin [0:TOTAL_OUTPUT_SAMPLES-1];
|
||||
reg [`RP_DOPPLER_BIN_WIDTH-1:0] cap_dbin [0:TOTAL_OUTPUT_SAMPLES-1];
|
||||
integer out_count;
|
||||
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user