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.
This commit is contained in:
@@ -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
|
# 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)
|
# Hold waiver for BUFIO→MMCM domain transfer (if Vivado flags hold violations)
|
||||||
|
|||||||
@@ -228,8 +228,6 @@ always @(posedge ft601_clk_in or negedge ft601_reset_n) begin
|
|||||||
doppler_real_cap <= 16'd0;
|
doppler_real_cap <= 16'd0;
|
||||||
doppler_imag_cap <= 16'd0;
|
doppler_imag_cap <= 16'd0;
|
||||||
cfar_detection_cap <= 1'b0;
|
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)
|
// Fix #5: Default to range-only on reset (prevents write FSM deadlock)
|
||||||
stream_ctrl_sync_0 <= 3'b001;
|
stream_ctrl_sync_0 <= 3'b001;
|
||||||
stream_ctrl_sync_1 <= 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
|
if (doppler_valid_sync[1] && !doppler_valid_sync_d) begin
|
||||||
doppler_real_cap <= doppler_real_hold;
|
doppler_real_cap <= doppler_real_hold;
|
||||||
doppler_imag_cap <= doppler_imag_hold;
|
doppler_imag_cap <= doppler_imag_hold;
|
||||||
doppler_data_pending <= 1'b1;
|
|
||||||
end
|
end
|
||||||
if (cfar_valid_sync[1] && !cfar_valid_sync_d) begin
|
if (cfar_valid_sync[1] && !cfar_valid_sync_d) begin
|
||||||
cfar_detection_cap <= cfar_detection_hold;
|
cfar_detection_cap <= cfar_detection_hold;
|
||||||
cfar_data_pending <= 1'b1;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -318,12 +314,22 @@ always @(posedge ft601_clk_in or negedge ft601_reset_n) begin
|
|||||||
cmd_opcode <= 8'd0;
|
cmd_opcode <= 8'd0;
|
||||||
cmd_addr <= 8'd0;
|
cmd_addr <= 8'd0;
|
||||||
cmd_value <= 16'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.
|
// 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.
|
// Do NOT assign it here (ft601_clk_in domain) — causes multi-driven net.
|
||||||
end else begin
|
end else begin
|
||||||
// Default: clear one-shot signals
|
// Default: clear one-shot signals
|
||||||
cmd_valid <= 1'b0;
|
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)
|
// READ FSM — host-to-FPGA command path (Gap 4)
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user