From 6733a3e3e692fa1ae79446170619436d05944844 Mon Sep 17 00:00:00 2001 From: George Hilliard Date: Wed, 15 Sep 2021 00:00:24 -0500 Subject: [PATCH 1/2] clock/lattice_ecp5/ECP5PLL: ensure feedback path selected before exiting search --- litex/soc/cores/clock/lattice_ecp5.py | 3 +++ test/test_clock.py | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/litex/soc/cores/clock/lattice_ecp5.py b/litex/soc/cores/clock/lattice_ecp5.py index fd6cdbd4f..44a32ffb1 100644 --- a/litex/soc/cores/clock/lattice_ecp5.py +++ b/litex/soc/cores/clock/lattice_ecp5.py @@ -97,6 +97,9 @@ class ECP5PLL(Module): break if not valid: all_valid = False + if self.nclkouts == self.nclkouts_max and not config["clkfb"]: + # If there is no output suitable for feedback and no spare, not valid + all_valid = False else: all_valid = False if all_valid: diff --git a/test/test_clock.py b/test/test_clock.py index a1795149c..8d5fce8ac 100644 --- a/test/test_clock.py +++ b/test/test_clock.py @@ -121,6 +121,15 @@ class TestClock(unittest.TestCase): pll.expose_dpa() pll.compute_config() + # Test corner cases that have historically had trouble: + pll = ECP5PLL() + pll.register_clkin(Signal(), 100e6) + pll.create_clkout(ClockDomain("clkout1"), 350e6) + pll.create_clkout(ClockDomain("clkout2"), 350e6) + pll.create_clkout(ClockDomain("clkout3"), 175e6) + pll.create_clkout(ClockDomain("clkout4"), 175e6) + pll.compute_config() + # Lattice / NX def test_nxpll(self): pll = NXPLL() From 91ec6e0da8e0f566bce403e6c168f4b7e1f98e06 Mon Sep 17 00:00:00 2001 From: George Hilliard Date: Wed, 15 Sep 2021 00:00:54 -0500 Subject: [PATCH 2/2] clock/lattice_ecp5/ECP5PLL: emit frequency annotations to help Diamond Unlike nextpnr, Diamond appears not to infer the frequency of the outputs. Emit the same attributes that Diamond's PLL tool does. --- litex/soc/cores/clock/lattice_ecp5.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/litex/soc/cores/clock/lattice_ecp5.py b/litex/soc/cores/clock/lattice_ecp5.py index 44a32ffb1..4b0f5c75e 100644 --- a/litex/soc/cores/clock/lattice_ecp5.py +++ b/litex/soc/cores/clock/lattice_ecp5.py @@ -162,4 +162,6 @@ class ECP5PLL(Module): self.params[f"p_CLKO{n_to_l[n]}_FPHASE"] = 0 self.params[f"p_CLKO{n_to_l[n]}_CPHASE"] = cphase self.params[f"o_CLKO{n_to_l[n]}"] = clk + if f > 0: # i.e. not a feedback-only clock + self.params["attr"].append((f"FREQUENCY_PIN_CLKO{n_to_l[n]}", str(f/1e6))) self.specials += Instance("EHXPLLL", **self.params)