Skip to content

Instantly share code, notes, and snippets.

@agrif
Created May 12, 2025 01:43
Show Gist options
  • Save agrif/a74dcc5a75e160837fa5bbc2ccfe94c8 to your computer and use it in GitHub Desktop.
Save agrif/a74dcc5a75e160837fa5bbc2ccfe94c8 to your computer and use it in GitHub Desktop.
def _calculate_params(self, platform):
key = (platform.family, platform.speed)
try:
info = self.PLL_INFO[key]
except KeyError:
raise NotImplementedError('PLL not implemented for {!r}'.format(key))
fclkin = self.in_period.megahertz
params = None
diff = None
names = ['IDIV_SEL', 'pfd', 'FBDIV_SEL', 'clkout', 'ODIV_SEL', 'vco', 'DYN_SDIV_SEL', 'clkoutd']
valids = (
{n: locals()[n] for n in names}
for IDIV_SEL in range(64)
if info['pfd'][0] <= (pfd := fclkin / (IDIV_SEL + 1)) <= info['pfd'][1]
for FBDIV_SEL in range(64)
if info['clkout'][0] < (clkout := pfd * (FBDIV_SEL + 1)) < info['clkout'][1]
for ODIV_SEL in range(2, 130, 2)
if info['vco'][0] < (vco := clkout * ODIV_SEL) < info['vco'][1]
# 0 stands in for "use clkout not clkoutd"
for DYN_SDIV_SEL in range(0, 130, 2)
if (clkoutd := clkout / max(DYN_SDIV_SEL, 1)) or True
)
for v in valids:
new_params = info.copy()
new_params.update(v)
new_params.update({
'output': v['clkoutd'],
'output_signal': 'CLKOUTD',
'fclkin': fclkin,
'FCLKIN': '{:.6f}'.format(fclkin),
})
if v['DYN_SDIV_SEL'] == 0:
new_params.update({
'output': v['clkout'],
'output_signal': 'CLKOUT',
})
del new_params['DYN_SDIV_SEL']
del new_params['clkoutd']
new_diff = abs((new_params['output'] / self.out_period.megahertz) - 1)
if params is None or diff > new_diff:
params = new_params
diff = new_diff
ppm = diff * 1e6
if ppm > self.MAX_PPM:
raise RuntimeError('PLL settings not found: wanted {:.6f}, best is {:.6f} ({:.0f} ppm)'.format(self.out_period.megahertz, params['output'], ppm))
self._params = params
self.out_period = am.Period(MHz=params['output'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment