diff options
Diffstat (limited to 'fpga/usrp3/top/n3xx/dboards/rh/db_clocks.xdc')
-rw-r--r-- | fpga/usrp3/top/n3xx/dboards/rh/db_clocks.xdc | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/fpga/usrp3/top/n3xx/dboards/rh/db_clocks.xdc b/fpga/usrp3/top/n3xx/dboards/rh/db_clocks.xdc new file mode 100644 index 000000000..e78342849 --- /dev/null +++ b/fpga/usrp3/top/n3xx/dboards/rh/db_clocks.xdc @@ -0,0 +1,118 @@ +# +# Copyright 2017 Ettus Research, A National Instruments Company +# SPDX-License-Identifier: LGPL-3.0 +# +# Timing analysis is performed in "usrp3/top/n3xx/dboards/rh/doc/rh_timing.xlsx". +# See this spreadsheet for more details and explanations. + +#******************************************************************************* +## Daughterboard Clocks +# +# 122.88, 200, 245.76 and 250 MHz Sample Rates are allowable with 2:1/1:2 DSP and +# 2 samples/cycle arriving at the FPGA: +# +# <-- 2:1/1:2 --> +# | Supported | Sample rate | FPGA Clk | +# |sample rates | at JESD core | Frequency | +# | (MSPS) | (MSPS) | (MHz) | +# |-------------|--------------|-----------| +# | 122.88 | 491.52 | 245.76 | (uses DUC/DDC) +# | 200.00 | 400.00 | 200.00 | +# | 245.76 | 491.52 | 245.76 | +# | 250.00 | 500.00 | 250.00 | +# +# Therefore, supported sample clocks are: 122.88, 200, 245.76 and 250 MHz. +# Constrain the paths to the max rate to support all rates in a single FPGA image. +set SAMPLE_CLK_PERIOD 4.00 +create_clock -name fpga_clk_a -period $SAMPLE_CLK_PERIOD [get_ports DBA_FPGA_CLK_P] +create_clock -name fpga_clk_b -period $SAMPLE_CLK_PERIOD [get_ports DBB_FPGA_CLK_P] +create_clock -name mgt_clk_dba -period $SAMPLE_CLK_PERIOD [get_ports DBA_MGTCLK_P] +create_clock -name mgt_clk_dbb -period $SAMPLE_CLK_PERIOD [get_ports DBB_MGTCLK_P] + +# The Radio Clocks coming from the DBs are synchronized together (at the converters) to +# a typical value of less than 100ps. To give ourselves and Vivado some margin, we claim +# here that the DB-B Radio Clock can arrive 500ps before or after the DB-A clock at +# the FPGA (note that the trace lengths of the Radio Clocks coming from the DBs to the +# FPGA are about 0.5" different, thereby incurring ~80ps of additional skew at the FPGA). +# There is one spot in the FPGA where we cross domains between the DB-A and +# DB-B clock, so we must ensure that Vivado can analyze that path safely. +set FPGA_CLK_EARLY -0.5 +set FPGA_CLK_LATE 0.5 +set_clock_latency -source -early $FPGA_CLK_EARLY [get_clocks fpga_clk_b] +set_clock_latency -source -late $FPGA_CLK_LATE [get_clocks fpga_clk_b] + +# Virtual clocks for constraining I/O (used below) +create_clock -name fpga_clk_a_v -period $SAMPLE_CLK_PERIOD +create_clock -name fpga_clk_b_v -period $SAMPLE_CLK_PERIOD + +# The set_clock_latency constraints set on fpga_clk_b are problematic when used with +# I/O timing, since the analyzer gives us a double-hit on the latency. One workaround +# (used here) is to simply swap the early and late times for the virtual clock so that +# it cancels out the source latency during analysis. D. Jepson tested this by setting +# the early and late numbers to zero and then their actual value, running timing reports +# on each. The slack report matches for both cases, showing that the reversed early/late +# numbers on the virtual clock zero out the latency effects on the actual clock. +# +# Note this is not a problem for the fpga_clk_a, since no latency is added. So only apply +# it to fpga_clk_b_v. +set_clock_latency -source -early $FPGA_CLK_LATE [get_clocks fpga_clk_b_v] +set_clock_latency -source -late $FPGA_CLK_EARLY [get_clocks fpga_clk_b_v] + + + +#******************************************************************************* +## Aliases for auto-generated clocks + +create_generated_clock -name radio_clk_fb [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKFBOUT}] +create_generated_clock -name radio_clk [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKOUT0}] +create_generated_clock -name radio_clk_2x [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKOUT1}] + +create_generated_clock -name radio_clk_b_fb [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKFBOUT}] +create_generated_clock -name radio_clk_b [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKOUT0}] +create_generated_clock -name radio_clk_b_2x [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKOUT1}] + + + +#******************************************************************************* +## Generated clocks for output busses to the daughterboard +# +# These clock definitions need to come above the set_clock_groups commands below to work! + +# Define clocks on the PL SPI clock output pins for both DBs. Actual divider values are +# set by SW at run-time. Current divider value is 125 based on what radio clock +# rate is set. +# For the CPLD SPI endpoint alone, we need it to run at ~25 MHz (writes only), this means +# that at times, the PL SPI will have its divider set to 10 (radio_clock = 250 MHz) or 8 +# (radio_clock = 200 MHz). +# The readback clock is lower (~10 MHz), so create a separate clock for it. +# Use readback divide value of 24 for an even divider (and some overconstraining). +set PL_SPI_DIVIDE_VAL 10 +set PL_SPI_RB_DIVIDE_VAL 24 +set PL_SPI_CLK_A [get_ports DBA_CPLD_PL_SPI_SCLK] +create_generated_clock -name pl_spi_clk_a \ + -source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_A]/C] \ + -divide_by $PL_SPI_DIVIDE_VAL $PL_SPI_CLK_A +create_generated_clock -name pl_spi_rb_clk_a \ + -master_clock [get_clocks radio_clk] \ + -source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_A]/C] \ + -divide_by $PL_SPI_RB_DIVIDE_VAL -add $PL_SPI_CLK_A +set PL_SPI_CLK_B [get_ports DBB_CPLD_PL_SPI_SCLK] +create_generated_clock -name pl_spi_clk_b \ + -source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_B]/C] \ + -divide_by $PL_SPI_DIVIDE_VAL $PL_SPI_CLK_B +create_generated_clock -name pl_spi_rb_clk_b \ + -master_clock [get_clocks radio_clk] \ + -source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_B]/C] \ + -divide_by $PL_SPI_RB_DIVIDE_VAL -add $PL_SPI_CLK_B + +#******************************************************************************* +## JTAG +set DB_JTAG_DIVISOR 4 +create_generated_clock -name dba_jtag_tck -divide_by $DB_JTAG_DIVISOR \ + -source [get_pins {inst_n310_ps/jtag_0/U0/bitq_ctrl/bitq_state_reg[1]/C}] \ + [get_ports DBA_CPLD_JTAG_TCK] + +create_generated_clock -name dbb_jtag_tck -divide_by $DB_JTAG_DIVISOR \ + -source [get_pins {inst_n310_ps/jtag_1/U0/bitq_ctrl/bitq_state_reg[1]/C}] \ + [get_ports DBB_CPLD_JTAG_TCK] + |