fpga: x400: refactor RFDC block diagrams and timing constraints
Original-commit: a7bce74be154de9a68d6bdf2f9a6651b480b6dfa
This commit is contained in:
committed by
Wade Fife
parent
f480008cf9
commit
3ed06cc861
@@ -56,31 +56,28 @@ set_input_delay -clock pll_ref_clk \
|
||||
# x410_ps_rfdc_bd
|
||||
###############################################################################
|
||||
|
||||
# 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
|
||||
# This property tells Vivado that we require the clocks generated by the RFDC MMCM 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 \
|
||||
}]
|
||||
# The constraint CLOCK_DELAY_GROUP has to be applied on the clock nets.
|
||||
# These nets are connected to the outputs of the clock buffers, which are driven by the MMCM.
|
||||
# Search the nets begining from the MMCM outputs to find the clock buffers outputs.
|
||||
set rfdc_mmcm [get_cells -hierarchical -filter { PRIMITIVE_TYPE == CLOCK.PLL.MMCME4_ADV && NAME =~ *rfdc/data_clock_mmcm* } ]
|
||||
set mmcm_clkout_pins [get_pins -of_objects $rfdc_mmcm -regexp -filter {NAME =~ ".*CLKOUT[0-4]"}]
|
||||
set mmcm_clkout_nets [get_nets -of_objects $mmcm_clkout_pins]
|
||||
set clkbuf_in_pins [get_pins -leaf -of_objects $mmcm_clkout_nets -filter {DIRECTION == IN}]
|
||||
set clkbuf_cells [get_cells -of_objects $clkbuf_in_pins]
|
||||
set clkbuf_out_pins [get_pins -of_objects $clkbuf_cells -filter {DIRECTION == OUT}]
|
||||
set clkbuf_out_nets [get_nets -of_objects $clkbuf_out_pins]
|
||||
set_property CLOCK_DELAY_GROUP DataClkGroup $clkbuf_out_nets
|
||||
|
||||
# We treat rfdc_clk and data_clk buffers as asynchronous, with knowledge that
|
||||
|
||||
# We treat rfdc_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}]
|
||||
# set_false_path -from [get_cells -hierarchical -regexp -filter {NAME =~ .*/rfdc/clock_gates_0/.*rEnableRfdc\dBufg.*_reg}]
|
||||
set_false_path -from [get_cells -hierarchical -regexp -filter {NAME =~ .*/rfdc/clock_gates_0/.*rEnableDataBufg\dx.*_reg}]
|
||||
set_false_path -from [get_cells -hierarchical -regexp -filter {NAME =~ .*/rfdc/clock_gates_0/.*rEnableRfdcBufg\dx.*_reg}]
|
||||
|
||||
|
||||
###############################################################################
|
||||
@@ -138,3 +135,6 @@ set spi_max_out_delay 11.000
|
||||
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
|
||||
# Force SPI registers into IOB.
|
||||
set_property IOB TRUE [get_cells "cpld_interface_i/ctrlport_spi_master_i/simple_spi_core_64bit_i/sclk_reg"]
|
||||
set_property IOB TRUE [get_cells "cpld_interface_i/ctrlport_spi_master_i/simple_spi_core_64bit_i/mosi_reg"]
|
||||
|
||||
@@ -40,33 +40,26 @@ set_multicycle_path -end -hold 7 -from [get_pins db_gpio_gen[*].db_gpio_interfac
|
||||
# x440_ps_rfdc_bd
|
||||
###############################################################################
|
||||
|
||||
# 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
|
||||
# This property tells Vivado that we require the clocks generated by the RFDC MMCM 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/radio0_rfdc_clk ||\
|
||||
NAME=~*/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/radio0_rfdc_clk_2x ||\
|
||||
NAME=~*/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/radio1_rfdc_clk ||\
|
||||
NAME=~*/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/radio1_rfdc_clk_2x \
|
||||
}]
|
||||
# The constraint CLOCK_DELAY_GROUP has to be applied on the clock nets.
|
||||
# These nets are connected to the outputs of the clock buffers, which are driven by the MMCM.
|
||||
# Search the nets begining from the MMCM outputs to find the clock buffers outputs.
|
||||
set rfdc_mmcm [get_cells -hierarchical -filter { PRIMITIVE_TYPE == CLOCK.PLL.MMCME4_ADV && NAME =~ *rfdc/data_clock_mmcm* } ]
|
||||
set mmcm_clkout_pins [get_pins -of_objects $rfdc_mmcm -regexp -filter {NAME =~ ".*CLKOUT[0-6]"}]
|
||||
set mmcm_clkout_nets [get_nets -of_objects $mmcm_clkout_pins]
|
||||
set clkbuf_in_pins [get_pins -leaf -of_objects $mmcm_clkout_nets -filter {DIRECTION == IN}]
|
||||
set clkbuf_cells [get_cells -of_objects $clkbuf_in_pins]
|
||||
set clkbuf_out_pins [get_pins -of_objects $clkbuf_cells -filter {DIRECTION == OUT}]
|
||||
set clkbuf_out_nets [get_nets -of_objects $clkbuf_out_pins]
|
||||
set_property CLOCK_DELAY_GROUP DataClkGroup $clkbuf_out_nets
|
||||
|
||||
|
||||
# We treat rfdc_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/*rEnableRfdc0Bufg1x*/C}] \
|
||||
-to [get_pins -hierarchical -filter {NAME =~ */rfdc/rf_clock_buffers/rf0_clk_1x_buf/*BUFGCE*/CE}]
|
||||
|
||||
set_false_path -from [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*rEnableRfdc0Bufg2x*/C}] \
|
||||
-to [get_pins -hierarchical -filter {NAME =~ */rfdc/rf_clock_buffers/rf0_clk_2x_buf/*BUFGCE*/CE}]
|
||||
|
||||
set_false_path -from [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*rEnableRfdc1Bufg1x*/C}] \
|
||||
-to [get_pins -hierarchical -filter {NAME =~ */rfdc/rf_clock_buffers/rf1_clk_1x_buf/*BUFGCE*/CE}]
|
||||
|
||||
set_false_path -from [get_pins -hierarchical -filter {NAME =~ */rfdc/clock_gates_0/*rEnableRfdc1Bufg2x*/C}] \
|
||||
-to [get_pins -hierarchical -filter {NAME =~ */rfdc/rf_clock_buffers/rf1_clk_2x_buf/*BUFGCE*/CE}]
|
||||
set_false_path -from [get_cells -hierarchical -regexp -filter {NAME =~ .*/rfdc/clock_gates_0/.*rEnableRfdc\dBufg.*_reg}]
|
||||
|
||||
|
||||
###############################################################################
|
||||
@@ -117,8 +110,8 @@ set_input_delay -clock pll_ref_clk -min $sysref_min_input_delay [get_ports {SYSR
|
||||
|
||||
# The output delays are chosen to allow a large time window of valid data for
|
||||
# the MB CPLD logic.
|
||||
set spi_min_out_delay -1.500
|
||||
set spi_max_out_delay 9.500
|
||||
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}]
|
||||
|
||||
@@ -12,26 +12,12 @@
|
||||
#
|
||||
# Note: Vivado will create generated clocks based on the default MMCM settings
|
||||
# configured in the clocking wizard, but we are going to dynamically change
|
||||
# those clocks, and so we need to provide worst-case values in here.
|
||||
# those clocks, and so the MMCM has to be configured for the highest frequency.
|
||||
###############################################################################
|
||||
|
||||
# PLL Reference Clock (PRC) input. This goes from the LMK straight to the MMCM
|
||||
# input, and is used to generate the internal PRC as well as RFDC/data clocks.
|
||||
set pll_ref_clk_in_period 15.625
|
||||
create_clock -name pll_ref_in_clk -period $pll_ref_clk_in_period [get_ports PLL_REFCLK_FPGA_P]
|
||||
|
||||
# Internal PLL Reference Clock (PRC). Used to derive data clocks. Constrain to
|
||||
# the fastest possible clock rate supported in the driver.
|
||||
# Set to maximum frequency of 64 MHz. Actual frequency depends on the LMK
|
||||
# configuration.
|
||||
set pll_ref_clk_period 15.625
|
||||
create_clock -name pll_ref_clk \
|
||||
-period $pll_ref_clk_period \
|
||||
[get_pins x440_ps_rfdc_bd_i/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/mmcme4_adv_inst/CLKOUT0]
|
||||
|
||||
###############################################################################
|
||||
# Generated Clocks
|
||||
###############################################################################
|
||||
|
||||
create_generated_clock -name sync_ref_clk \
|
||||
-source [get_ports BASE_REFCLK_FPGA_P] \
|
||||
-divide_by 2 [get_pins clock_div_5mhz/clk_out_reg/Q]
|
||||
|
||||
create_clock -name pll_ref_clk -period $pll_ref_clk_period [get_ports PLL_REFCLK_FPGA_P]
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#
|
||||
# Copyright 2023 Ettus Research, a National Instruments Brand
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
# Description:
|
||||
# Clock definition constraints for X440 1600 type images
|
||||
#
|
||||
|
||||
# Data clocks: Generated by the MMCM, used for data paths between the RFDC output
|
||||
# and RFNoC. Maximum supported master clock rate is 2.048 Gsps @8SPC => 256 MHz.
|
||||
set rfdc_data_clk_period 3.906
|
||||
|
||||
create_clock -name rfdc_r0_clk -add \
|
||||
-period $rfdc_data_clk_period \
|
||||
[get_pins x440_ps_rfdc_bd_i/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/mmcme4_adv_inst/CLKOUT2]
|
||||
create_clock -name rfdc_r1_clk -add \
|
||||
-period $rfdc_data_clk_period \
|
||||
[get_pins x440_ps_rfdc_bd_i/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/mmcme4_adv_inst/CLKOUT5]
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright 2024 Ettus Research, a National Instruments Brand
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
# Description:
|
||||
# Clock definition constraints for X440 200 MHz BW type images
|
||||
#
|
||||
|
||||
# Data clocks: Generated by the MMCM, used for data paths between the RFDC output and RFNoC.
|
||||
# The RFDC block diagram is set up for the maximum required clock frequencies (rfdc_clk_1x @ 256 MHz),
|
||||
# which are used in the 1600 MHz bitfile.
|
||||
# This is not required for the 200 MHz bitfile, hence we multiply the output clock divider values by 8
|
||||
# to allow Vivado to auto-derive the correct clock periods.
|
||||
|
||||
set data_clock_mmcm [get_cells -hierarchical -filter { PRIMITIVE_TYPE == CLOCK.PLL.MMCME4_ADV && NAME =~ "*data_clock_mmcm*" }]
|
||||
|
||||
set_property -dict [ list \
|
||||
CLKOUT1_DIVIDE {32} \
|
||||
CLKOUT2_DIVIDE {32} \
|
||||
CLKOUT3_DIVIDE {16} \
|
||||
CLKOUT4_DIVIDE {16} \
|
||||
CLKOUT5_DIVIDE {32} \
|
||||
CLKOUT6_DIVIDE {16} \
|
||||
] $data_clock_mmcm
|
||||
@@ -1,21 +1,25 @@
|
||||
#
|
||||
# Copyright 2023 Ettus Research, a National Instruments Brand
|
||||
# Copyright 2024 Ettus Research, a National Instruments Brand
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
# Description:
|
||||
# Clock definition constraints for X440 400 type images
|
||||
# Clock definition constraints for X440 400 MHz BW type images
|
||||
#
|
||||
|
||||
# Data clocks: Generated by the MMCM, used for data paths between the RFDC output
|
||||
# and RFNoC. Maximum supported master clock rate is 500 Msps @8SPC => 62.5 MHz.
|
||||
# Theoretical maximum converter rate is 4.096 GSps, so really, 512 Msps @ 8SPC => 64 MHz.
|
||||
set rfdc_data_clk_period 15.625
|
||||
# Data clocks: Generated by the MMCM, used for data paths between the RFDC output and RFNoC.
|
||||
# The RFDC block diagram is set up for the maximum required clock frequencies (rfdc_clk_1x @ 256 MHz),
|
||||
# which are used in the 1600 MHz bitfile.
|
||||
# This is not required for the 400 MHz bitfile, hence we multiply the output clock divider values by 4
|
||||
# to allow Vivado to auto-derive the correct clock periods.
|
||||
|
||||
create_clock -name rfdc_r0_clk -add \
|
||||
-period $rfdc_data_clk_period \
|
||||
[get_pins x440_ps_rfdc_bd_i/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/mmcme4_adv_inst/CLKOUT2]
|
||||
create_clock -name rfdc_r1_clk -add \
|
||||
-period $rfdc_data_clk_period \
|
||||
[get_pins x440_ps_rfdc_bd_i/rfdc/data_clock_mmcm/inst/CLK_CORE_DRP_I/clk_inst/mmcme4_adv_inst/CLKOUT5]
|
||||
set data_clock_mmcm [get_cells -hierarchical -filter { PRIMITIVE_TYPE == CLOCK.PLL.MMCME4_ADV && NAME =~ "*data_clock_mmcm*" }]
|
||||
|
||||
set_property -dict [ list \
|
||||
CLKOUT1_DIVIDE {16} \
|
||||
CLKOUT2_DIVIDE {16} \
|
||||
CLKOUT3_DIVIDE {8} \
|
||||
CLKOUT4_DIVIDE {8} \
|
||||
CLKOUT5_DIVIDE {16} \
|
||||
CLKOUT6_DIVIDE {8} \
|
||||
] $data_clock_mmcm
|
||||
|
||||
Reference in New Issue
Block a user