1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from itertools import product

pll_inputs = [2_000_000, 4_000_000, 8_000_000, 16_000_000, 20_000_000, 25_000_000]
pllp_opts = [2, 4, 6, 8]
plln_opts = list(range(50, 432 + 1))
pllm_opts = list(range(2, 63 + 1))
pllq_opts = list(range(2, 15 + 1))
pllr_opts = list(range(2, 7 + 1))

def clocks_float(pll_input, pllp, plln, pllm, pllq, pllr):
    vco_input = pll_input / pllm
    vco_output = vco_input * plln
    main_clock = vco_output / pllp
    usb_clock = vco_output / pllq
    i2s_clock = vco_output / pllr
    return main_clock, usb_clock, i2s_clock

def clocks_new(pll_input, pllp, plln, pllm, pllq, pllr):
    main_clock = pll_input * plln // (pllm * pllp)
    usb_clock = pll_input * plln // (pllm * pllq)
    i2s_clock = pll_input * plln // (pllm * pllr)
    return main_clock, usb_clock, i2s_clock

for pll_input, pllp, plln, pllm, pllq, pllr in product(pll_inputs, pllp_opts, plln_opts, pllm_opts, pllq_opts, pllr_opts):
    cfloat = clocks_float(pll_input, pllp, plln, pllm, pllq, pllr)
    cnew = clocks_new(pll_input, pllp, plln, pllm, pllq, pllr)
    for correct, new in zip(cfloat, cnew):
        # Without (correct - new) < 0.1 we get stiffed by floats like 1.9999999
        # where the new calculation outputs 2 but int(correct) outputs 1
        if not ((correct - new) < 0.1 or int(correct) == new):
            print(f"deviation: {correct=} {new=}")