fix(fpga): move IBUF+BUFIO+BUFR into 50T wrapper (same scope as pad)

The previous attempt put BUFIO inside u_core/gen_ft_bufr, but the pad
(ft_clkout) and its inferred IBUF live at the top wrapper level. Vivado
shape-packs IBUF↔BUFIO into the same IOB tile, and it couldn't do that
across the wrapper→u_core hierarchy boundary — producing CRITICAL
WARNING [12-1411] "Illegal to place BUFIO on TIEOFF site" and WNS=-5.737
(worse than the CLOCK_DEDICATED_ROUTE=FALSE baseline).

Fix: instantiate IBUF+BUFIO+BUFR explicitly in radar_system_top_50t.v
and pass the BUFR output into u_core.ft601_clk_in. radar_system_top.v
now does a pass-through wire assign for USB_MODE=1 (no BUFG) so the
clock net doesn't get double-buffered.
This commit is contained in:
Jason
2026-04-20 21:02:56 +05:45
parent 30279e8c4d
commit 813ee4c962
2 changed files with 29 additions and 18 deletions
+8 -16
View File
@@ -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 IOBUFG" 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