soc/cores/clock: add divclk_divide/vco_margin support on S7/Ultrascale

This commit is contained in:
Florent Kermarrec 2019-04-15 11:36:42 +02:00
parent f986974d60
commit c252972bef

View file

@ -16,7 +16,8 @@ class S7Clocking(Module, AutoCSR):
clkfbout_mult_frange = (2, 64+1)
clkout_divide_range = (1, 128+1)
def __init__(self):
def __init__(self, vco_margin=0):
self.vco_margin = vco_margin
self.reset = Signal()
self.locked = Signal()
self.clkin_freq = None
@ -57,12 +58,14 @@ class S7Clocking(Module, AutoCSR):
def compute_config(self):
config = {}
config["divclk_divide"] = 1
for divclk_divide in range(*self.divclk_divide_range):
config["divclk_divide"] = divclk_divide
for clkfbout_mult in range(*self.clkfbout_mult_frange):
all_valid = True
vco_freq = self.clkin_freq*clkfbout_mult
vco_freq = self.clkin_freq*clkfbout_mult/divclk_divide
(vco_freq_min, vco_freq_max) = self.vco_freq_range
if vco_freq >= vco_freq_min and vco_freq <= vco_freq_max:
if (vco_freq >= vco_freq_min*(1 + self.vco_margin) and
vco_freq <= vco_freq_max*(1 - self.vco_margin)):
for n, (clk, f, p, m) in sorted(self.clkouts.items()):
valid = False
for d in range(*self.clkout_divide_range):
@ -122,6 +125,7 @@ class S7PLL(S7Clocking):
def __init__(self, speedgrade=-1):
S7Clocking.__init__(self)
self.divclk_divide_range = (1, 56+1)
self.vco_freq_range = {
-1: (800e6, 2133e6),
-2: (800e6, 1866e6),
@ -152,6 +156,7 @@ class S7MMCM(S7Clocking):
def __init__(self, speedgrade=-1):
S7Clocking.__init__(self)
self.divclk_divide_range = (1, 106+1)
self.clkin_freq_range = {
-1: (10e6, 800e6),
-2: (10e6, 933e6),
@ -208,7 +213,8 @@ class USClocking(Module, AutoCSR):
clkfbout_mult_frange = (2, 64+1)
clkout_divide_range = (1, 128+1)
def __init__(self):
def __init__(self, vco_margin=0):
self.vco_margin = vco_margin
self.reset = Signal()
self.locked = Signal()
self.clkin_freq = None
@ -249,12 +255,14 @@ class USClocking(Module, AutoCSR):
def compute_config(self):
config = {}
config["divclk_divide"] = 1
for divclk_divide in range(*self.divclk_divide_range):
config["divclk_divide"] = divclk_divide
for clkfbout_mult in range(*self.clkfbout_mult_frange):
all_valid = True
vco_freq = self.clkin_freq*clkfbout_mult
vco_freq = self.clkin_freq*clkfbout_mult/divclk_divide
(vco_freq_min, vco_freq_max) = self.vco_freq_range
if vco_freq >= vco_freq_min and vco_freq <= vco_freq_max:
if (vco_freq >= vco_freq_min*(1 + self.vco_margin) and
vco_freq <= vco_freq_max*(1 - self.vco_margin)):
for n, (clk, f, p, m) in sorted(self.clkouts.items()):
valid = False
for d in range(*self.clkout_divide_range):
@ -313,12 +321,12 @@ class USPLL(USClocking):
def __init__(self, speedgrade=-1):
USClocking.__init__(self)
self.divclk_divide_range = (1, 56+1)
self.clkin_freq_range = {
-1: (70e6, 800e6),
-2: (70e6, 933e6),
-3: (70e6, 1066e6),
}[speedgrade]
self.vco_freq_range = {
-1: (600e6, 1200e6),
-2: (600e6, 1335e6),
@ -349,12 +357,12 @@ class USMMCM(USClocking):
def __init__(self, speedgrade=-1):
USClocking.__init__(self)
self.divclk_divide_range = (1, 106+1)
self.clkin_freq_range = {
-1: (10e6, 800e6),
-2: (10e6, 933e6),
-3: (10e6, 1066e6),
}[speedgrade]
self.vco_freq_range = {
-1: (600e6, 1200e6),
-2: (600e6, 1440e6),