From 5b92bf2d575416739995b9f5905654a72fdcacb3 Mon Sep 17 00:00:00 2001 From: bunnie Date: Tue, 10 Mar 2020 18:48:30 +0800 Subject: [PATCH] add fractional division options to clk0 config on PLL S7 MMCMs allow fractional divider on clock 0. Add a fallback to try fractional values on clock 0 if a solution can't be found. This is necessary for e.g. generating both a 100MHz and 48MHz clock from a 12MHz source with margin=0 --- litex/soc/cores/clock.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/litex/soc/cores/clock.py b/litex/soc/cores/clock.py index 63a9edaa6..d8d9f1f3c 100644 --- a/litex/soc/cores/clock.py +++ b/litex/soc/cores/clock.py @@ -19,6 +19,7 @@ def period_ns(freq): class XilinxClocking(Module, AutoCSR): clkfbout_mult_frange = (2, 64+1) clkout_divide_range = (1, 128+1) + clkout0_divide_range = (2, (128+0.125), 0.125) def __init__(self, vco_margin=0): self.vco_margin = vco_margin @@ -86,6 +87,19 @@ class XilinxClocking(Module, AutoCSR): config["clkout{}_phase".format(n)] = p valid = True break + if not valid and n == 0: + # clkout0 supports fractional division, try the fractional range as a fallback + (start, stop, step) = self.clkout0_divide_range + d = start + while d < stop: + clk_freq = vco_freq / d + if abs(clk_freq - f) <= f * m: + config["clkout{}_freq".format(n)] = clk_freq + config["clkout{}_divide".format(n)] = d + config["clkout{}_phase".format(n)] = p + valid = True + break + d += step if not valid: all_valid = False else: