diff --git a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp b/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp index b1d3964..16c6954 100644 --- a/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp +++ b/9_Firmware/9_1_Microcontroller/9_1_3_C_Cpp_Code/main.cpp @@ -1181,8 +1181,8 @@ static int configure_ad9523(void) int32_t init_ret = ad9523_init(&init_param); DIAG("CLK", "ad9523_init() returned %ld", (long)init_ret); if (init_ret != 0) { - DIAG_ERR("CLK", "ad9523_init() FAILED (ret=%ld) -- calling Error_Handler()", (long)init_ret); - Error_Handler(); + DIAG_ERR("CLK", "ad9523_init() FAILED (ret=%ld)", (long)init_ret); + return -1; } } diff --git a/9_Firmware/9_2_FPGA/radar_receiver_final.v b/9_Firmware/9_2_FPGA/radar_receiver_final.v index 4560026..e86c34d 100644 --- a/9_Firmware/9_2_FPGA/radar_receiver_final.v +++ b/9_Firmware/9_2_FPGA/radar_receiver_final.v @@ -11,8 +11,10 @@ module radar_receiver_final ( input wire adc_dco_n, // Data Clock Output N (400MHz LVDS) output wire adc_pwdn, - // Chirp counter from transmitter (for frame sync and matched filter) + // Chirp counter from transmitter (for matched filter indexing) input wire [5:0] chirp_counter, + // Frame-start pulse from transmitter (CDC-synchronized, 1 clk_100m cycle) + input wire tx_frame_start, output wire [31:0] doppler_output, output wire doppler_valid, @@ -392,30 +394,31 @@ mti_canceller #( .mti_first_chirp(mti_first_chirp) ); -// ========== FRAME SYNC USING chirp_counter ========== -reg [5:0] chirp_counter_prev; +// ========== FRAME SYNC FROM TRANSMITTER ========== +// [FPGA-001 FIXED] Use the authoritative new_chirp_frame signal from the +// transmitter (via plfm_chirp_controller_enhanced), CDC-synchronized to +// clk_100m in radar_system_top. Previous code tried to derive frame +// boundaries from chirp_counter == 0, but that counter comes from the +// transmitter path (plfm_chirp_controller_enhanced) which does NOT wrap +// at chirps_per_elev — it overflows to N and only wraps at 6-bit rollover +// (64). This caused frame pulses at half the expected rate for N=32. +reg tx_frame_start_prev; reg new_frame_pulse; always @(posedge clk or negedge reset_n) begin if (!reset_n) begin - chirp_counter_prev <= 6'd0; + tx_frame_start_prev <= 1'b0; new_frame_pulse <= 1'b0; end else begin - // Default: no pulse new_frame_pulse <= 1'b0; - // [FPGA-001 FIXED] Detect frame boundary when chirp_counter wraps to 0. - // The chirp_counter (driven by radar_mode_controller) counts 0..N-1 - // and wraps back to 0 at the start of each new frame. Previous code - // also checked (== host_chirps_per_elev) and (== 2*host_chirps_per_elev) - // which were unreachable dead conditions for any N, since the counter - // never reaches N. Now works correctly for any chirps_per_elev value. - if (chirp_counter != chirp_counter_prev && chirp_counter == 6'd0) begin + // Edge detect: tx_frame_start is a toggle-CDC derived pulse that + // may be 1 clock wide. Capture rising edge for clean 1-cycle pulse. + if (tx_frame_start && !tx_frame_start_prev) begin new_frame_pulse <= 1'b1; end - // Store previous value - chirp_counter_prev <= chirp_counter; + tx_frame_start_prev <= tx_frame_start; end end @@ -481,14 +484,6 @@ always @(posedge clk or negedge reset_n) begin `endif chirps_in_current_frame <= 0; end - - // Monitor chirp counter pattern - if (chirp_counter != chirp_counter_prev) begin - `ifdef SIMULATION - $display("[TOP] chirp_counter: %0d ? %0d", - chirp_counter_prev, chirp_counter); - `endif - end end end diff --git a/9_Firmware/9_2_FPGA/radar_system_top.v b/9_Firmware/9_2_FPGA/radar_system_top.v index dfafa65..a133453 100644 --- a/9_Firmware/9_2_FPGA/radar_system_top.v +++ b/9_Firmware/9_2_FPGA/radar_system_top.v @@ -505,6 +505,8 @@ radar_receiver_final rx_inst ( // Chirp counter from transmitter (CDC-synchronized from 120 MHz domain) .chirp_counter(tx_current_chirp_sync), + // Frame-start pulse from transmitter (CDC-synchronized toggle→pulse) + .tx_frame_start(tx_new_chirp_frame_sync), // ADC Physical Interface .adc_d_p(adc_d_p), diff --git a/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v b/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v index adc78e7..2f8ef37 100644 --- a/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v +++ b/9_Firmware/9_2_FPGA/tb/tb_radar_receiver_final.v @@ -96,15 +96,31 @@ end reg [5:0] chirp_counter; reg mc_new_chirp_prev; +// Frame-start pulse: mirrors the real transmitter's new_chirp_frame signal. +// In the real system this fires on IDLE→LONG_CHIRP transitions in the chirp +// controller. Here we derive it from the mode controller's chirp_count +// wrapping back to 0 (which wraps correctly at cfg_chirps_per_elev). +reg tx_frame_start; +reg [5:0] rmc_chirp_prev; + always @(posedge clk_100m or negedge reset_n) begin if (!reset_n) begin chirp_counter <= 6'd0; mc_new_chirp_prev <= 1'b0; + tx_frame_start <= 1'b0; + rmc_chirp_prev <= 6'd0; end else begin mc_new_chirp_prev <= dut.mc_new_chirp; if (dut.mc_new_chirp != mc_new_chirp_prev) begin chirp_counter <= chirp_counter + 1; end + + // Detect when the internal mode controller's chirp_count wraps to 0 + tx_frame_start <= 1'b0; + if (dut.rmc_chirp_count == 6'd0 && rmc_chirp_prev != 6'd0) begin + tx_frame_start <= 1'b1; + end + rmc_chirp_prev <= dut.rmc_chirp_count; end end @@ -128,6 +144,7 @@ radar_receiver_final dut ( .adc_pwdn(), .chirp_counter(chirp_counter), + .tx_frame_start(tx_frame_start), .doppler_output(doppler_output), .doppler_valid(doppler_valid),