fix(fpga): IOB=TRUE on FT2232H pads to meet 5 ns FPGA launch budget

Post-route WNS = -5.355 ns on path group ft_clkout, net
  u_core/gen_ft2232h.usb_inst/ft_data_TRI[0]_repN_1

FT2232H 245-sync FIFO input setup (t_su = 11.667 ns on a 16.667 ns
CLKOUT) leaves the FPGA only ~5 ns from clock edge to pad. Without
IOB=TRUE, the output / tristate FFs live in fabric and FF→OBUFT
routing eats 2–3 ns, forcing Vivado to replicate the tristate
driver (ft_data_TRI[*]_repN) and still miss timing.

The FSM in usb_data_interface_ft2232h.v already registers
ft_data_out / ft_data_oe / ft_{rd,wr,oe}_n at the output boundary
in the ft_clk domain, so packing them into the IOB is safe with
no RTL change.
This commit is contained in:
Jason
2026-04-20 16:43:12 +05:45
parent 0067969ee7
commit 94bf6944a3
@@ -354,6 +354,18 @@ set_property DRIVE 8 [get_ports {ft_oe_n}]
set_property DRIVE 8 [get_ports {ft_siwu}]
set_property DRIVE 8 [get_ports {ft_data[*]}]
# IOB packing: force output/tristate FFs to pack into the IOB to meet the
# FT2232H 5 ns FPGA launch budget (period 16.667 ns t_su 11.667 ns ≈ 5 ns).
# Without this, fabric→OBUFT routing eats 2-3 ns and Vivado starts
# replicating the tristate driver (ft_data_TRI[*]_repN) trying to rescue
# timing. The FSM flops in usb_data_interface_ft2232h.v already sit at
# the output boundary, so packing is safe and does not require RTL change.
set_property IOB TRUE [get_ports {ft_data[*]}]
set_property IOB TRUE [get_ports {ft_rd_n}]
set_property IOB TRUE [get_ports {ft_wr_n}]
set_property IOB TRUE [get_ports {ft_oe_n}]
set_property IOB TRUE [get_ports {ft_siwu}]
# ft_clkout constrained above in CLOCK CONSTRAINTS section (C4, 60 MHz)
# --------------------------------------------------------------------------