aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/x400/constraints/timing/common.xdc
blob: 288465ad0375ceefc0e362ab4d68cb7723877d6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
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