Last active
July 8, 2021 05:15
-
-
Save hansfbaier/505e50eae2c5686a1a1e85e5fd5116e3 to your computer and use it in GitHub Desktop.
Using constraint solver for calculating optimal PLL parameters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# from the python-constraint package | |
import constraint | |
from pprint import pprint | |
# All frequencies in MHz | |
platform = 'xilinx-mmcm' | |
fin = 50 | |
fout = 12.288 | |
error_threshold = 0.001 | |
print(f"platform: {platform} fin: {fin}MHz fout: {fout}MHz, error_threshold: {error_threshold}") | |
if platform == 'altera': | |
vco_min = 600 | |
vco_max = 1300 | |
max_mult = 200 | |
max_div = 400 | |
elif platform == 'xilinx': | |
vco_min = 800 | |
vco_max = 1600 | |
max_mult = 64 | |
max_div = 128 | |
elif platform == 'xilinx-mmcm': | |
vco_min = 600 | |
vco_max = 1600 | |
max_mult = 64 | |
max_div = 128 * 128 | |
problem = constraint.Problem() | |
problem.addVariable('mult', range(1, max_mult)) | |
problem.addVariable('div', range(1, max_div)) | |
def vco_range(mult): | |
vco_freq = fin * mult | |
return vco_min <= vco_freq and vco_freq <= vco_max | |
def relative_error(mult, div): | |
return abs((fin * mult / div - fout)) / fout | |
def is_precise(mult, div): | |
return relative_error(mult, div) < error_threshold | |
problem.addConstraint(vco_range, ['mult']) | |
problem.addConstraint(is_precise, ['mult', 'div']) | |
solutions = problem.getSolutions() | |
errors = [relative_error(s['mult'], s['div']) for s in solutions] | |
solutions_by_error = list(zip(errors, solutions)) | |
def sort_by_error(tuple): | |
return tuple[0] | |
solutions_by_error.sort(key=sort_by_error) | |
pprint(solutions_by_error) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment