diff options
author | Wade Fife <wade.fife@ettus.com> | 2021-06-08 19:40:46 -0500 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2021-06-10 11:56:58 -0500 |
commit | 6d3765605262016a80f71e36357f749ea35cbe5a (patch) | |
tree | 7d62d6622befd4132ac1ee085effa1426f7f53e5 /fpga/usrp3/top/x400/constraints/timing/common.xdc | |
parent | f706b89e6974e28ce76aadeeb06169becc86acba (diff) | |
download | uhd-6d3765605262016a80f71e36357f749ea35cbe5a.tar.gz uhd-6d3765605262016a80f71e36357f749ea35cbe5a.tar.bz2 uhd-6d3765605262016a80f71e36357f749ea35cbe5a.zip |
fpga: x400: Add support for X410 motherboard FPGA
Co-authored-by: Andrew Moch <Andrew.Moch@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Javier Valenzuela <javier.valenzuela@ni.com>
Co-authored-by: Joerg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Kumaran Subramoniam <kumaran.subramoniam@ni.com>
Co-authored-by: Max Köhler <max.koehler@ni.com>
Co-authored-by: Michael Auchter <michael.auchter@ni.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>
Co-authored-by: Hector Rubio <hrubio@ni.com>
Diffstat (limited to 'fpga/usrp3/top/x400/constraints/timing/common.xdc')
-rw-r--r-- | fpga/usrp3/top/x400/constraints/timing/common.xdc | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/fpga/usrp3/top/x400/constraints/timing/common.xdc b/fpga/usrp3/top/x400/constraints/timing/common.xdc new file mode 100644 index 000000000..288465ad0 --- /dev/null +++ b/fpga/usrp3/top/x400/constraints/timing/common.xdc @@ -0,0 +1,415 @@ +# +# Copyright 2021 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: LGPL-3.0-or-later +# +# Description: +# Common timing constraints for X410. +# + +############################################################################### +# Motherboard Clocks +############################################################################### + +# 10/25 MHz reference clock from rear panel connector. +# Constrain to the fastest possible clock rate. +set ref_clk_period 40.00 +create_clock -name ref_clk -period $ref_clk_period [get_ports BASE_REFCLK_FPGA_P] + +# PLL Reference Clock. Used to derive data clocks. +# Constrain to the fastest possible clock rate supported in the driver. +# MPM supports 61.44 / 62.5 / 64.0 MHz. +set pll_ref_clk_period 15.625 +create_clock -name pll_ref_clk -period $pll_ref_clk_period [get_ports PLL_REFCLK_FPGA_P] + +# MGT Clocks +# Clock Reference | Frequency | Purpose +# MGT_REFCLK_LMK0 | 156.25/125 MHz | 10 GbE +# MGT_REFCLK_LMK1 | 100.00 MHz | Reserved +# MGT_REFCLK_LMK2 | 100.00 MHz | Reserved +# MGT_REFCLK_LMK3 | 156.25/125 MHz | 10 GbE +create_clock -name mgt_ref_0 -period 6.400 [get_ports MGT_REFCLK_LMK0_P] +create_clock -name mgt_ref_1 -period 10.000 [get_ports MGT_REFCLK_LMK1_P] +create_clock -name mgt_ref_2 -period 10.400 [get_ports MGT_REFCLK_LMK2_P] +create_clock -name mgt_ref_3 -period 6.400 [get_ports MGT_REFCLK_LMK3_P] + +# Virtual clocks for constraining misc. I/Os. +create_clock -name async_in_clk -period 50.00 +create_clock -name async_out_clk -period 50.00 + + +############################################################################### +# Aliases for auto-generated clocks +############################################################################### + +# Name the PS clocks. These are originally declared in the PS8 IP block. +# Create the clocks based on the PS PLCLK pins. +# This generates critical warnings in the OSS flow because the clocks were already +# define and we are completely rewriting the old clock definition... this is OK. +create_clock -name clk100 -period 10.000 \ + [get_pins -of_objects [get_cells -hierarchical {*PS8_i}] -filter {NAME =~ *PLCLK[0]}] + +create_clock -name clk40 -period 25.000 \ + [get_pins -of_objects [get_cells -hierarchical {*PS8_i}] -filter {NAME =~ *PLCLK[1]}] + +create_clock -name clk166 -period 6.000 \ + [get_pins -of_objects [get_cells -hierarchical {*PS8_i}] -filter {NAME =~ *PLCLK[2]}] + +create_clock -name clk200 -period 5.000 \ + [get_pins -of_objects [get_cells -hierarchical {*PS8_i}] -filter {NAME =~ *PLCLK[3]}] + + +############################################################################### +# Sync to DB synthesizer sync CPLD input +############################################################################### + +# synth_sync_hold_requirement and synth_sync_setup_requirement are shared +# between the FPGA and DB CPLD. The values are set in shared_constants.sdc +set synth_sync_ports [get_ports {DB0_SYNTH_SYNC DB1_SYNTH_SYNC}] +set_output_delay -clock [get_clocks pll_ref_clk] -min -$synth_sync_hold_requirement $synth_sync_ports +set_output_delay -clock [get_clocks pll_ref_clk] -max $synth_sync_setup_requirement $synth_sync_ports + + +############################################################################### +# SPI to MB CPLD (PL) +# This interface is defined as system synchronous to pll_ref_clk. +############################################################################### + +# The output delays are chosen to allow a large time window of valid data for +# the MB CPLD logic. +set spi_min_out_delay 0.000 +set spi_max_out_delay 11.000 + +# Set output constraints for all ports. +set spi_out_ports [get_ports {PL_CPLD_SCLK PL_CPLD_MOSI PL_CPLD_CS0_n PL_CPLD_CS1_n}] +set_output_delay -clock [get_clocks pll_ref_clk] -min $spi_min_out_delay $spi_out_ports +set_output_delay -clock [get_clocks pll_ref_clk] -max $spi_max_out_delay $spi_out_ports + +# Both CPLD and FPGA use PLL reference clock from a common clock chip. +# The traces from that clock chip to the ICs are not length matched. Assume a +# worst case clock difference of 0.5 ns at the IC inputs. There is no direction +# defined. The clock can arrive faster or slower at one IC. +set pl_clock_diff 0.500 + +# The longest trace on the PL SPI interface is (assuming 170.0 ps/in) +# Longest trace | Trace length | Trace delay +# PL_CPLD_MISO | 3.863 in | 0.657 ns +set pl_spi_board_delay 0.657 + +# Output delay timings of the MB CPLD design, which still meet timing +set pl_spi_cpld_min_out -1.000 +set pl_spi_cpld_max_out 8.000 + +set spi_in_port [get_ports {PL_CPLD_MISO}] +set_input_delay -clock [get_clocks pll_ref_clk] \ + -min [expr {- $pl_spi_cpld_min_out - $pl_clock_diff}] \ + $spi_in_port +set_input_delay -clock [get_clocks pll_ref_clk] \ + -max [expr {$pll_ref_clk_period - $pl_spi_cpld_max_out + $pl_spi_board_delay + $pl_clock_diff}] \ + $spi_in_port + + +############################################################################### +# 10 GbE +############################################################################### + +# These are the exceptions from "xge_pcs_pma_exceptions.xdc" which are to be +# used when not using the example design. +# +# "clk100" used here is the clock that's connected to the "dclk" input in the core. +set_max_delay -from [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/RXOUTCLK}]] -to [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/TXOUTCLK}]] -datapath_only 6.40 +set_max_delay -from [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/TXOUTCLK}]] -to [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/RXOUTCLK}]] -datapath_only 6.40 +set_max_delay -from [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/RXOUTCLK}]] -to [get_clocks clk100] -datapath_only 6.40 +set_max_delay -from [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/TXOUTCLK}]] -to [get_clocks clk100] -datapath_only 6.40 +set_max_delay -from [get_clocks clk100] -to [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/TXOUTCLK}]] -datapath_only 10.000 +set_max_delay -from [get_clocks clk100] -to [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/RXOUTCLK}]] -datapath_only 10.000 + + +############################################################################### +# DIO +# Those GPIO pins are considered asynchronous paths. The user has to add +# constraints in case required. Therefore not setting false_paths from / to +# user logic to allow user generated timing constraints to be applied. +############################################################################### + +# Ignore paths from "slow" PS interface to not interfere with user constraints. +set dio_ports [get_ports {DIOA_FPGA[*] DIOB_FPGA[*]}] +set dio_registers [get_cells -hierarchical -filter {NAME =~ *x4xx_dio_i* && IS_SEQUENTIAL && IS_PRIMITIVE}] +set_false_path -from $dio_registers -to $dio_ports +set_false_path -from $dio_ports -to $dio_registers + + +############################################################################### +# PPS +############################################################################### + +# The TRIG_IO port may be driven by either the PPS in BRC domain to +# enable direct sync between 2 devices, or by any other user logic. +# When PPS is exported through Trigger I/O, timing must be analyzed +# to ensure determinism in the PPS exporting. +# But, when other user logic drives TRIG_IO, then the port should be +# treated as asynchronous (or close to async. at least). +# To achieve this conditional timing analysis, the following trick is +# used: +# 1. A virtual copy of ref_clk is created for I/O timing - virtual_ref_clk +# 2. Set output_delay constraints to assign a clock to the TRIG_IO port. +# 3. A set_max_delay constraint is used to time the output path to TRIG_IO +# set_max_delay makes the timing constraint driver agnostic, and as long +# as the critical output delay is met for driving PPS through TRIG_IO, +# we should be fine as this requirement is relatively loose. + +# 1) Creating copy of ref_clk to only analyze timing to TRIG_IO port (output) +# when output is driven by ref_clk (PPS generation in ref_clk domain). +create_clock -name virtual_ref_clk -period $ref_clk_period + +# Trigger IO port is used as output for the PPS signal +# TRIG_IO_1V8 trace length MB = 4.050 + 1.190 inch = 5.240 inch +# TRIG_IO_1V8 trace length DB = 2.401 + 0.120 + 0.457 + 0.261 inch = 3.239 inch +# TRIG_IO buffer max switching time = 3.3 +set trig_max_out_delay [expr {8.479 * 0.17 + 3.3}] + +# Set minimum output delay hold time to a small amount to grant external +# devices some hold time. Delay should be simple to achieve as there is no PLL +# in the clocking path and some combinatorial logic. +set trig_min_out_delay 2.000 + +# 2) set_output_delay for assigning clocks to TRIG_IO. Use zero for delay to +# avoid adding extra delay requirements on top of the set_max|min_delay +# constraints below. +set_output_delay -clock [get_clocks virtual_ref_clk] 0.0 [get_ports {TRIG_IO}] + +# 3) Min and max delays make constraining driver agnostic. We just make sure +# the critical timing for PPS export is met though. +set_max_delay -through [get_port {TRIG_IO}] -to [get_clocks {virtual_ref_clk}] \ + [expr {$ref_clk_period - $trig_max_out_delay}] +set_min_delay -through [get_port {TRIG_IO}] -to [get_clocks {virtual_ref_clk}] \ + $trig_min_out_delay + +# Treat TRIG_IO input as asynchronous. +set_false_path -from [get_ports {TRIG_IO}] +# For documentation purposes, these are the input max/min delays for TRIG_IO: +# - Input delay assuming zero trace delay and TRIG_IO buffer min switching +# time (B->A) = 0.1 ns. +# - TRIG_IO buffer max switching time (B->A = input) = 3.7 ns + same trace +# length as for output (8.479). + +# Assuming no delay on external clock distribution. + +# Account for the PPS min output delay only (for the case two X410 are directly +# connected to each other). +set pps_min_in_delay $trig_min_out_delay + +# PPS_IN trace length DB = 0.535 + 0.133 + 0.117 + 0.061 + 2.745 inch = 3.591 inch +# PPS_IN trace length MB = 5.726 inch +# PPS switch max propagation delay = 3.6 + +# Assume 50% of the clock period is used for external PPS clock distribution as +# the PPS out is used to synchronize one X410 (master) with another X410 +# (slave) the PPS out (trig_io) delay is added to the PPS input. +set pps_max_in_delay [expr {9.317 * 0.17 + 3.6 + 0.5 * $ref_clk_period + $trig_max_out_delay}] + +# Apply PPS input constraints. +set_input_delay -clock [get_clocks ref_clk] -min $pps_min_in_delay [get_ports {PPS_IN}] +set_input_delay -clock [get_clocks ref_clk] -max $pps_max_in_delay [get_ports {PPS_IN}] + +# PPS clock domain crossing BRC -> PRC on the aligned edge. +# Use a data path of half PLL reference clock period to make sure the value is +# captured without metastability. +set_max_delay -from [get_cells -hierarchical pps_delayed_brc_reg] \ + -to [get_clocks pll_ref_clk*] [expr {$pll_ref_clk_period/2}] + + +############################################################################### +# LMK sync +############################################################################### + +# The timings are derived from simulation. + +# Clock Buffer ADCLK944 -> FPGA. +set buffer_to_fpga_min_clk_delay 0.997 +set buffer_to_fpga_max_clk_delay 1.154 + +# Clock Buffer ADCLK944 -> Sample clock PLL (LMK04832). +set buffer_to_spll_min_clk_delay 0.000 +set buffer_to_spll_max_clk_delay 0.014 + +# FPGA -> Sample clock PLL SYNC input. +set fpga_to_spll_min_clk_delay 0.381 +set fpga_to_spll_max_clk_delay 0.460 + +# Sample clock PLL requirements. +set lmk_sync_input_hold 4.000 +set lmk_sync_input_setup 4.000 + +set lmk_sync_output_max_delay [expr {$fpga_to_spll_max_clk_delay + $buffer_to_fpga_max_clk_delay + \ + $lmk_sync_input_setup - $buffer_to_spll_min_clk_delay}] +set lmk_sync_output_min_delay [expr {$fpga_to_spll_min_clk_delay + $buffer_to_fpga_min_clk_delay - \ + $buffer_to_spll_max_clk_delay - $lmk_sync_input_hold}] +set_output_delay -clock ref_clk -max $lmk_sync_output_max_delay [get_ports {LMK_SYNC}] +set_output_delay -clock ref_clk -min $lmk_sync_output_min_delay [get_ports {LMK_SYNC}] + + +############################################################################### +# SPLL SYSREF Capture +############################################################################### + +# SYSREF is generated by the LMK04832 clocking chip (SPLL), which also produces +# the PLL reference clock (PRC) used to generate data clocks with a MMCM. Both +# SYSREF and PLL reference clock are directly fed into the RFSoC. +# SYSREF is captured by the FPGA fabric in the PRC clock domain (MMCM's PRC +# output) with a double synchronizer and then transfered to the RFDC clock +# domain. Both SYSREF versions (PRC and RFDC) are used by downstream logic for +# sync. purposes. +# SYSREF is a continuous signal running at PRC freq. / 25, and it is +# intentionally shifted in the LMK chip to align it closer to the +# PRC's falling edge. +# The added delay follows the formula: +# SYSREF LMK delay = 22 * sample clock period +# The highest sampling frequency supported in MPM (3.072 GHz) is used for +# timing constrains. Therefore, SYSREF LMK's delay = 22 * (1 / 3.072e9). +set sysref_lmk_delay 7.161 +# +# These are the signals' lengths and corresponding delays (assuming 170 ps/in): +# - SYSREF --> 5794 mils (5.794 inches) = 0.985 ns +# - PRC --> 5668 mils (5.668 inches) = 0.964 ns +# +# For min/max input delay calculations, it is assumed min prop. delay of 0 ns, +# which essentially over-constrains SYSREF. +# +# The max input delay is the latest that SYSREF may arrive w.r.t PRC, and it is +# calculated as follows: +# Input delay (max) = SYSREF's LMK delay + SYSREF prop. delay (max) +# - PRC prop. delay (min) +set sysref_max_input_delay [expr {$sysref_lmk_delay + 0.985 - 0}] +# +# The min input delay is the earliest that SYSREF may arrive w.r.t PRC, and it +# is calculated as follows: +# Input delay (min) = SYSREF's LMK delay + SYSREF prop. delay (min) +# - PRC prop. delay (min) +set sysref_min_input_delay [expr {$sysref_lmk_delay + 0 - 0.964}] + +set_input_delay -clock pll_ref_clk -max $sysref_max_input_delay [get_ports {SYSREF_FABRIC_P}] +set_input_delay -clock pll_ref_clk -min $sysref_min_input_delay [get_ports {SYSREF_FABRIC_P}] + + +############################################################################### +# DB GPIO +# This interface is defined as system synchronous to pll_ref_clk. +# Some timing constants in this section are declared in +# <repo>/fpga/usrp3/top/x400/constraints/timing/shared_constants.sdc +############################################################################### + +# Set output constraints for all ports. +set db_gpio_ports [get_ports {DB0_GPIO[*] DB1_GPIO[*]}] +set_output_delay -clock [get_clocks pll_ref_clk] -min $db_gpio_fpga_min_out $db_gpio_ports +set_output_delay -clock [get_clocks pll_ref_clk] -max $db_gpio_fpga_max_out $db_gpio_ports + +# Output enable signal is available one clock cycle ahead of valid data, this +# enables the use of multi-cycle paths. +set db_gpio_out_en_regs [get_cells -hierarchical -filter \ + {PRIMITIVE_TYPE =~ REGISTER.*.* && NAME =~ "*bytestream_output_enable*"}] +set_multicycle_path 2 -setup -from $db_gpio_out_en_regs -to $db_gpio_ports +set_multicycle_path 1 -hold -from $db_gpio_out_en_regs -to $db_gpio_ports + +# Calculate output delays back from capturing edge, add board delay and clock +# difference. +# Assume worst case as data being generated late and receiving an early clock: +# - Max CPLD TCO +# - Max data propagation delay +# - Max CPLD clock propagation delay and minimum FPGA clock propagation delay +# - Maximum delay from MC100EPT23 clock buffer +set_input_delay -clock pll_ref_clk \ + -max [expr {$pll_ref_clk_period - $db_gpio_cpld_max_out + $db_gpio_board_max_delay \ + + $db_cpld_prc_clock_prop_max - $fpga_prc_clock_prop_min + $clock_translate_max}] \ + $db_gpio_ports + +# Negate minimum output delay as it is defined from the change to the start +# clock edge. +# Assume worst case as data being generated early and receiving an late clock: +# - Min CPLD TCO +# - Min data propagation delay (0) +# - Min CPLD clock propagation delay and max FPGA clock propagation delay +set_input_delay -clock pll_ref_clk \ + -min [expr {- $db_gpio_cpld_min_out \ + - $db_gpio_board_min_delay \ + - $db_cpld_prc_clock_prop_min + $fpga_prc_clock_prop_max}] \ + $db_gpio_ports + + +############################################################################### +# x4xx_ps_rfdc_bd +############################################################################### + +# The calibration_muxes component contains a clock crossing from some GPIO +# component instances that are synchronous to a configuration clock and ending +# in some AXI registers synchronous to data clock. The GPIO registers are +# essentially constant. When they are changing (due to a register write), the +# latching registers can definitely become metastable, so the software must +# ensure that the corrupted data appears at a safe time. +set gpio_regs [get_pins -of [get_cells -filter {IS_SEQUENTIAL && NAME =~ *rfdc/calibration_muxes/axi_gpio*} -hier] -filter {IS_CLOCK}] +set mux_regs [get_cells -hier -filter {IS_SEQUENTIAL && NAME =~ *rfdc/calibration_muxes/gpio_to_axis_mux*}] +set_false_path -from $gpio_regs -to $mux_regs + +# This property tells Vivado that we require these clocks to be well aligned. +# We have synchronous clock domain crossings between these clocks that can have +# large hold violations after placement due to uneven clock loading. +set_property CLOCK_DELAY_GROUP DataClkGroup [get_nets -hier -filter {\ + NAME=~*/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/data_clk ||\ + NAME=~*/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/data_clk_2x ||\ + NAME=~*/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/pll_ref_clk_out ||\ + NAME=~*/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/rfdc_clk_2x ||\ + NAME=~*/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/rfdc_clk \ +}] + +# We treat rfdc_clk and data_clk buffers as asynchronous, with knowledge that +# code clocked in this domain will be reset after this clocked is enabled. This +# will make timing easier to meet on these clock domains. +set_false_path -from [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*rEnableRfdcBufg1x*/C}] \ + -to [get_pins -hierarchical -filter {NAME =~ */rfdc/rf_clock_buffers/rfdc_clk_1x_buf/*BUFGCE*/CE}] + +set_false_path -from [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*rEnableRfdcBufg2x*/C}] \ + -to [get_pins -hierarchical -filter {NAME =~ */rfdc/rf_clock_buffers/rfdc_clk_2x_buf/*BUFGCE*/CE}] + +set_false_path -from [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*rEnableDataBufg1x*/C}] \ + -to [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*DataClk1xSafeBufg/CE}] + +set_false_path -from [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*rEnableDataBufg2x*/C}] \ + -to [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*DataClk2xSafeBufg/CE}] + + +############################################################################### +# Misc Constraints +############################################################################### + +# Double synchronizer false paths. +set_false_path -to [get_pins -hierarchical -filter {NAME =~ */synchronizer_false_path/stages[0].value_reg[0][*]/D}] +set_false_path -to [get_pins -hierarchical -filter {NAME =~ */rf_reset_controller*/*_ms_reg/D}] +set_false_path -to [get_pins -hierarchical -filter {NAME =~ */rfdc/rf_nco_reset_0/*_ms*/D}] + +# GTY_RCV_CLK_* is driven by a OBUFDS_GTE4 buffer, which has an asynchronous +# clock-enable pin. +# By experimentation, it was observed that explicitly setting a false_path to +# this pin improved timing. +set gty_rcv_clk_buff_ceb [get_pins -of_objects [get_cells -of_objects [all_fanin -flat -startpoints_only [get_ports {GTY_RCV_CLK_P}]]] -filter {NAME=~ "*CEB"}] +set_false_path -from [get_clocks {clk40}] -through $gty_rcv_clk_buff_ceb + + +############################################################################### +# Asynchronous / misc. I/O constraints +# Loosely constrain these to prevent warnings in Vivado. +# Using set_input_delay associates the I/Os to a clock group, but +# set_(min|max)_delay overwrites the setup/hold analysis values. +############################################################################### + +set async_inputs [get_ports {FPGA_AUX_REF}] + +set_input_delay -clock [get_clocks async_in_clk] 0.000 $async_inputs +set_max_delay -from $async_inputs 50.000 +set_min_delay -from $async_inputs 0.000 + + +set async_outputs [get_ports {FABRIC_CLK_OUT_P PPS_LED}] + +set_output_delay -clock [get_clocks async_out_clk] 0.000 $async_outputs +set_max_delay -to $async_outputs 50.000 +set_min_delay -to $async_outputs 0.000 |