From 2efab23cd90b766a172fcd46591e351634846922 Mon Sep 17 00:00:00 2001 From: Jason <83615043+JJassonn69@users.noreply.github.com> Date: Fri, 20 Mar 2026 01:56:20 +0200 Subject: [PATCH] Fix Vivado DRC: consolidate data_pending flags into single always block, fix MMCM LOCKED false_path usb_data_interface.v: doppler_data_pending and cfar_data_pending were driven by two always blocks (CDC sync block set them, write FSM cleared them). Vivado DRC MDRV-1 flagged this as multiple drivers. Moved all set/clear logic into the write FSM always block using doppler_valid_ft and cfar_valid_ft edge wires. adc_clk_mmcm.xdc: changed set_false_path -from to -through for MMCM LOCKED pin (not a valid timing startpoint). Eliminates CRITICAL WARNING from Builds 19/20/21. 19/19 FPGA regression pass. --- 9_Firmware/9_2_FPGA/constraints/adc_clk_mmcm.xdc | 5 ++++- 9_Firmware/9_2_FPGA/usb_data_interface.v | 14 ++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) 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) //