From 6bb89af74a68b63e71556c65102d6b583181490d Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 7 May 2020 11:39:34 +0200 Subject: [PATCH] phy/s7pciehy: disable constraints generated from the .xci and use our owns. Vivado generates default constraints that are not working with all configurations and that we then have difficulties to reset... So let's disable all constraints generated from the .xci and just use our owns (subset of the generated ones). --- examples/kc705.py | 1 + litepcie/phy/s7pciephy.py | 48 +++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/examples/kc705.py b/examples/kc705.py index f4f57c7..9295e09 100755 --- a/examples/kc705.py +++ b/examples/kc705.py @@ -66,6 +66,7 @@ def __init__(self, platform, nlanes=1): # PCIe PHY --------------------------------------------------------------------------------- self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x" + str(nlanes))) + self.pcie_phy.add_timing_constraints(platform) self.add_csr("pcie_phy") # PCIe Endpoint ---------------------------------------------------------------------------- diff --git a/litepcie/phy/s7pciephy.py b/litepcie/phy/s7pciephy.py index 383003a..58c19cb 100644 --- a/litepcie/phy/s7pciephy.py +++ b/litepcie/phy/s7pciephy.py @@ -194,6 +194,7 @@ def convert_size(command, size, max_size): class Open(Signal): pass m_axis_rx_tlast = Signal() m_axis_rx_tuser = Signal(32) + self.pcie_gt_device = {"xc7a": "GTP", "xc7k": "GTX", "xc7v": "GTX"}[platform.device[:4]] self.pcie_phy_params = dict( # Parameters --------------------------------------------------------------------------- p_LINK_CAP_MAX_LINK_WIDTH = nlanes, @@ -202,9 +203,7 @@ class Open(Signal): pass p_PCIE_REFCLK_FREQ = 0, # 100MHz refclk p_PCIE_USERCLK1_FREQ = 3 if nlanes <= 2 else 4, p_PCIE_USERCLK2_FREQ = 3 if (pcie_clk_freq == 125e6) else 4, - p_PCIE_GT_DEVICE = {"xc7a": "GTP", - "xc7k": "GTX", - "xc7v": "GTX"}[platform.device[:4]], + p_PCIE_GT_DEVICE = self.pcie_gt_device, p_PCIE_USE_MODE = "1.0", # PCI Express Interface ---------------------------------------------------------------- @@ -431,15 +430,56 @@ class Open(Signal): pass # Hard IP sources ------------------------------------------------------------------------------ def add_sources(self, platform, phy_path, phy_filename): - platform.add_ip(os.path.join(phy_path, phy_filename)) platform.add_source(os.path.join(phy_path, "pcie_pipe_clock.v")) platform.add_source(os.path.join(phy_path, "pcie_s7_x{}_support.v".format(self.nlanes))) + platform.add_ip(os.path.join(phy_path, phy_filename), disable_constraints=True) # External Hard IP ----------------------------------------------------------------------------- def use_external_hard_ip(self, hard_ip_path, hard_ip_filename): self.external_hard_ip = True self.add_sources(self.platform, hard_ip_path, hard_ip_filename) + # Timing constraints --------------------------------------------------------------------------- + def add_timing_constraints(self, platform): + platform.add_platform_command(""" +# PCIe 100MHz input clock. +create_clock -name pcie_phy_clk -period 10 [get_pins -hierarchical \ + -filter {{NAME=~*pcie_support/pcie_i/inst/inst/gt_top_i/pipe_wrapper_i/pipe_lane[0].gt_wrapper_i/gtX_channel.gtXe2_channel_i/TXOUTCLK}}] + +# False paths (through). +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/PLPHYLNKUPN}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/PLRECEIVEDHOTRST}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/RXELECIDLE}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/TXPHINITDONE}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/TXPHALIGNDONE}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/TXDLYSRESETDONE}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/RXDLYSRESETDONE}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/RXPHALIGNDONE}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/RXCDRLOCK}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/CFGMSGRECEIVEDPMETO}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/PLL0LOCK}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/RXPMARESETDONE}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/RXSYNCDONE}}] +set_false_path -through [get_pins -hierarchical -filter {{NAME=~*/TXSYNCDONE}}] + +# False path (to). +set_false_path -to [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/S0}}] +set_false_path -to [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/S1}}] + +# Generated clocks. +create_generated_clock -name clk_125mhz_phy [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/mmcm_i/CLKOUT0}}] +create_generated_clock -name clk_250mhz_phy [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/mmcm_i/CLKOUT1}}] +create_generated_clock -name clk_125mhz_mux_phy \ + -source [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/I0}}] \ + -divide_by 1 \ + [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/O}}] +create_generated_clock -name clk_250mhz_mux_phy \ + -source [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/I1}}] \ + -divide_by 1 -add -master_clock [get_clocks -of [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/I1}}]] \ + [get_pins -hierarchical -filter {{NAME=~*pcie_support/pipe_clock_i/pclk_i1_bufgctrl.pclk_i1/O}}] +set_clock_groups -name pcieclkmux -physically_exclusive -group clk_125mhz_mux_phy -group clk_250mhz_mux_phy + """.replace("gtX", self.pcie_gt_device.lower())) + # Finalize ------------------------------------------------------------------------------------- def do_finalize(self): if not self.external_hard_ip: