Gap 7 MMCM jitter cleaner + CIC comb CREG pipeline + XDC clock-name fix
MMCM (Gap 7): - Add adc_clk_mmcm.v: MMCME2_ADV wrapper (VCO=800MHz, CLKOUT0=400MHz) - Modify ad9484_interface_400m.v: replace BUFG with MMCM path, gate reset on mmcm_locked - Add adc_clk_mmcm.xdc: CDC false paths for clk_mmcm_out0 <-> clk_100m XDC Fix (Build 19 WNS=-0.011 root cause): - Remove conflicting create_generated_clock -name clk_400m_mmcm - Replace all clk_400m_mmcm references with Vivado auto-generated clk_mmcm_out0 - CDC false paths now correctly apply to actual timing paths CIC CREG Pipeline (Build 18 critical path fix): - Explicit DSP48E1 for comb[0] with CREG=1/AREG=1/BREG=1/PREG=1 - Absorbs integrator_sampled_comb fabric FDRE into DSP48 C-port register - Eliminates 0.643ns fabric->DSP routing delay (Build 18 tightest path) - +1 cycle comb latency via data_valid_comb_0_out pipeline - Move shared register declarations above ifndef SIMULATION (iverilog fix) - Update golden data for +1 cycle CIC pipeline shift Build scripts: build19_mmcm.tcl, build20_mmcm_creg.tcl Regression: 18/18 FPGA pass, 20/20 MCU pass Build 20 launched on remote Vivado (pending results)
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# ============================================================================
|
||||
# adc_clk_mmcm.xdc — Supplementary constraints for MMCM ADC clock path
|
||||
#
|
||||
# These constraints augment the existing adc_dco_p clock definitions when the
|
||||
# adc_clk_mmcm module is integrated into ad9484_interface_400m.v.
|
||||
#
|
||||
# USAGE:
|
||||
# Add this file to the Vivado project AFTER the main production XDC.
|
||||
# The main XDC still defines create_clock on adc_dco_p (the physical input).
|
||||
# Vivado automatically creates a generated clock on the MMCM output;
|
||||
# these constraints handle CDC paths for the new clock topology.
|
||||
#
|
||||
# HIERARCHY: rx_inst/adc/mmcm_inst/...
|
||||
# ============================================================================
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# MMCM Output Clock — use Vivado's auto-generated clock name
|
||||
# --------------------------------------------------------------------------
|
||||
# Vivado auto-creates a generated clock named 'clk_mmcm_out0' on the MMCM
|
||||
# CLKOUT0 net. We do NOT create_generated_clock here (that would create a
|
||||
# second clock on the same net, causing the CDC false paths below to bind
|
||||
# to the wrong clock and leave clk_mmcm_out0 uncovered — exactly the bug
|
||||
# that caused Build 19's -0.011 ns WNS on the CDC_FIR gray-code path).
|
||||
# All constraints below reference 'clk_mmcm_out0' directly.
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# CDC: BUFIO domain (adc_dco_p) ↔ MMCM output domain (clk_mmcm_out0)
|
||||
# --------------------------------------------------------------------------
|
||||
# The IDDR outputs are captured by BUFIO (adc_dco_p clock), then re-registered
|
||||
# into the MMCM BUFG domain in ad9484_interface_400m.v.
|
||||
# These clocks are frequency-matched and phase-related (MMCM is locked to
|
||||
# adc_dco_p), so the single register transfer is safe. We use max_delay
|
||||
# (one period) to ensure the tools verify the transfer fits within one cycle
|
||||
# without over-constraining with full inter-clock setup/hold analysis.
|
||||
set_max_delay -datapath_only -from [get_clocks adc_dco_p] \
|
||||
-to [get_clocks clk_mmcm_out0] 2.500
|
||||
|
||||
set_max_delay -datapath_only -from [get_clocks clk_mmcm_out0] \
|
||||
-to [get_clocks adc_dco_p] 2.500
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# CDC: MMCM output domain ↔ other clock domains
|
||||
# --------------------------------------------------------------------------
|
||||
# The existing false paths in the production XDC reference adc_dco_p, which
|
||||
# now only covers the BUFIO/IDDR domain. The MMCM output clock (which drives
|
||||
# all fabric 400 MHz logic) needs its own false path declarations.
|
||||
set_false_path -from [get_clocks clk_100m] -to [get_clocks clk_mmcm_out0]
|
||||
set_false_path -from [get_clocks clk_mmcm_out0] -to [get_clocks clk_100m]
|
||||
|
||||
set_false_path -from [get_clocks clk_mmcm_out0] -to [get_clocks ft601_clk_in]
|
||||
set_false_path -from [get_clocks ft601_clk_in] -to [get_clocks clk_mmcm_out0]
|
||||
|
||||
set_false_path -from [get_clocks clk_mmcm_out0] -to [get_clocks clk_120m_dac]
|
||||
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]
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Hold waiver for BUFIO→MMCM domain transfer (if Vivado flags hold violations)
|
||||
# --------------------------------------------------------------------------
|
||||
# The existing hold waiver for BUFIO source-synchronous capture stays:
|
||||
# set_false_path -hold -from [get_ports {adc_d_p[*]}] -to [get_clocks adc_dco_p]
|
||||
#
|
||||
# The MMCM BUFG re-registration of IDDR outputs: since BUFIO and MMCM output
|
||||
# are derived from the same IBUFDS source, hold is inherently met (MMCM adds
|
||||
# insertion delay). If Vivado flags hold violations on this transfer, uncomment:
|
||||
# set_false_path -hold -from [get_clocks adc_dco_p] -to [get_clocks clk_mmcm_out0]
|
||||
Reference in New Issue
Block a user