diff --git a/9_Firmware/9_2_FPGA/radar_system_top.v b/9_Firmware/9_2_FPGA/radar_system_top.v index 56161f4..7a77a74 100644 --- a/9_Firmware/9_2_FPGA/radar_system_top.v +++ b/9_Firmware/9_2_FPGA/radar_system_top.v @@ -329,22 +329,14 @@ BUFG bufg_120m ( // USB clock buffering: // USB_MODE=0 (200T/FT601): pin is MRCC (D17) → BUFG, global clock network. -// USB_MODE=1 (50T/FT2232H): pin is SRCC (C4, non-MRCC) → BUFIO + BUFR for -// regional dedicated routing. SRCC can drive BUFIO/BUFR but not BUFG -// directly (the "poor placement IO→BUFG" CLOCK_DEDICATED_ROUTE=FALSE -// override was burning ~5 ns in fabric routing on the ft_clkout path). -// All ft_clkout-domain logic (FT2232H FSM, FIFO flops, toggle CDCs) is -// contained in bank 35 / one clock region, so regional distribution -// is sufficient. See UG472 §3 BUFIO/BUFR. -generate if (USB_MODE == 1) begin : gen_ft_bufr - wire ft_clk_bufio; - BUFIO bufio_ft (.I(ft601_clk_in), .O(ft_clk_bufio)); - BUFR #(.BUFR_DIVIDE("BYPASS"), .SIM_DEVICE("7SERIES")) bufr_ft ( - .I(ft_clk_bufio), - .O(ft601_clk_buf), - .CE(1'b1), - .CLR(1'b0) - ); +// USB_MODE=1 (50T/FT2232H): pin is SRCC (C4, non-MRCC). The wrapper +// radar_system_top_50t.v instantiates IBUF+BUFIO+BUFR on the pin +// and passes the already-buffered clock into ft601_clk_in. We only +// pass it through here — inserting a BUFG would create a second +// buffer on an already-clock-network net and break the BUFIO/BUFR +// shape packing. See UG472 §3 BUFIO/BUFR. +generate if (USB_MODE == 1) begin : gen_ft_passthru + assign ft601_clk_buf = ft601_clk_in; end else begin : gen_ft_bufg BUFG bufg_ft601 (.I(ft601_clk_in), .O(ft601_clk_buf)); end endgenerate diff --git a/9_Firmware/9_2_FPGA/radar_system_top_50t.v b/9_Firmware/9_2_FPGA/radar_system_top_50t.v index 1842f96..13d8988 100644 --- a/9_Firmware/9_2_FPGA/radar_system_top_50t.v +++ b/9_Firmware/9_2_FPGA/radar_system_top_50t.v @@ -71,7 +71,7 @@ module radar_system_top_50t ( input wire stm32_mixers_enable, // ===== FT2232H USB 2.0 Interface (Bank 35: 3.3V) ===== - input wire ft_clkout, // 60 MHz from FT2232H CLKOUT (MRCC pin C4) + input wire ft_clkout, // 60 MHz from FT2232H CLKOUT (SRCC pin C4 — not MRCC) inout wire [7:0] ft_data, // 8-bit bidirectional data bus input wire ft_rxf_n, // RX FIFO not empty (active low) input wire ft_txe_n, // TX FIFO not full (active low) @@ -86,6 +86,25 @@ module radar_system_top_50t ( output wire gpio_dig7 // DIG_7 (H12→PD15): reserved ); + // ===== FT2232H clock buffering — IBUF → BUFIO → BUFR ===== + // C4 is SRCC (IS_CLK_CAPABLE=1, IS_MASTER=0). SRCC cannot drive BUFG + // with dedicated routing, but can drive BUFIO → BUFR regionally. All + // ft_clkout-domain logic fits in Bank 35's clock region. All three + // primitives must live in the same hierarchical scope so Vivado can + // shape-pack IBUF↔BUFIO correctly — that's why this lives here in the + // wrapper and not inside u_core. + wire ft_clkout_ibuf; + wire ft_clkout_bufio; + wire ft_clkout_bufr; + IBUF ibuf_ft (.I(ft_clkout), .O(ft_clkout_ibuf)); + BUFIO bufio_ft (.I(ft_clkout_ibuf), .O(ft_clkout_bufio)); + BUFR #(.BUFR_DIVIDE("BYPASS"), .SIM_DEVICE("7SERIES")) bufr_ft ( + .I(ft_clkout_bufio), + .O(ft_clkout_bufr), + .CE(1'b1), + .CLR(1'b0) + ); + // ===== Tie-off wires for unconstrained FT601 inputs (inactive with USB_MODE=1) ===== wire ft601_txe_tied = 1'b0; wire ft601_rxf_tied = 1'b0; @@ -123,7 +142,7 @@ module radar_system_top_50t ( // ----- Clocks & Reset ----- .clk_100m (clk_100m), .clk_120m_dac (clk_120m_dac), - .ft601_clk_in (ft_clkout), // FT2232H 60 MHz CLKOUT → shared USB clock port + .ft601_clk_in (ft_clkout_bufr), // Pre-buffered via IBUF+BUFIO+BUFR above (SRCC fix) .reset_n (reset_n), // ----- DAC -----