diff --git a/9_Firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc b/9_Firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc index f24ab2c..cb9651d 100644 --- a/9_Firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc +++ b/9_Firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc @@ -56,7 +56,10 @@ set_false_path -from [get_clocks clk_120m_dac] -to [get_clocks clk_mmcm_out0] # -------------------------------------------------------------------------- # MMCM Locked — asynchronous status signal, no timing paths needed # -------------------------------------------------------------------------- -set_false_path -from [get_pins rx_inst/adc/mmcm_inst/mmcm_adc_400m/LOCKED] +# LOCKED is not a valid timing startpoint (it's a combinational output of the +# MMCM primitive). Use -through instead of -from to waive all paths that pass +# through the LOCKED net. This avoids the CRITICAL WARNING from Build 19/20. +set_false_path -through [get_pins rx_inst/adc/mmcm_inst/mmcm_adc_400m/LOCKED] # -------------------------------------------------------------------------- # Hold waiver for BUFIO→MMCM domain transfer (if Vivado flags hold violations) diff --git a/9_Firmware/9_2_FPGA/usb_data_interface.v b/9_Firmware/9_2_FPGA/usb_data_interface.v index 760d265..6f744f5 100644 --- a/9_Firmware/9_2_FPGA/usb_data_interface.v +++ b/9_Firmware/9_2_FPGA/usb_data_interface.v @@ -228,8 +228,6 @@ always @(posedge ft601_clk_in or negedge ft601_reset_n) begin doppler_real_cap <= 16'd0; doppler_imag_cap <= 16'd0; cfar_detection_cap <= 1'b0; - doppler_data_pending <= 1'b0; - cfar_data_pending <= 1'b0; // Fix #5: Default to range-only on reset (prevents write FSM deadlock) stream_ctrl_sync_0 <= 3'b001; stream_ctrl_sync_1 <= 3'b001; @@ -280,11 +278,9 @@ always @(posedge ft601_clk_in or negedge ft601_reset_n) begin if (doppler_valid_sync[1] && !doppler_valid_sync_d) begin doppler_real_cap <= doppler_real_hold; doppler_imag_cap <= doppler_imag_hold; - doppler_data_pending <= 1'b1; end if (cfar_valid_sync[1] && !cfar_valid_sync_d) begin cfar_detection_cap <= cfar_detection_hold; - cfar_data_pending <= 1'b1; end end end @@ -318,12 +314,22 @@ always @(posedge ft601_clk_in or negedge ft601_reset_n) begin cmd_opcode <= 8'd0; cmd_addr <= 8'd0; cmd_value <= 16'd0; + doppler_data_pending <= 1'b0; + cfar_data_pending <= 1'b0; // NOTE: ft601_clk_out is driven by the clk-domain always block below. // Do NOT assign it here (ft601_clk_in domain) — causes multi-driven net. end else begin // Default: clear one-shot signals cmd_valid <= 1'b0; + // Data-pending flag management: set on valid edge, cleared when + // consumed or skipped by write FSM. Must be in this always block + // (not the CDC sync block) to avoid Vivado multiple-driver DRC error. + if (doppler_valid_ft) + doppler_data_pending <= 1'b1; + if (cfar_valid_ft) + cfar_data_pending <= 1'b1; + // ================================================================ // READ FSM — host-to-FPGA command path (Gap 4) //