Datasheet

Table Of Contents
13 # Fixed hardware parameters
14 fbdiv_range = range(16, 320 + 1)
15 postdiv_range = range(1, 7 + 1)
16
17 best = (0, 0, 0, 0)
18 best_margin = args.output
19
20 for fbdiv in (fbdiv_range if args.low_vco else reversed(fbdiv_range)):
21 vco = args.input * fbdiv
22 if vco < args.vco_min or vco > args.vco_max:
23 continue
24 # pd1 is inner loop so that we prefer higher ratios of pd1:pd2
25 for pd2 in postdiv_range:
26 for pd1 in postdiv_range:
27 out = vco / pd1 / pd2
28 margin = abs(out - args.output)
29 if margin < best_margin:
30 best = (out, fbdiv, pd1, pd2)
31 best_margin = margin
32
33 print("Requested: {} MHz".format(args.output))
34 print("Achieved: {} MHz".format(best[0]))
35 print("FBDIV: {} (VCO = {} MHz)".format(best[1], args.input * best[1]))
36 print("PD1: {}".format(best[2]))
37 print("PD2: {}".format(best[3]))
Given an input and output frequency, this script will find the best possible set of PLL parameters to get as close as
possible. Where multiple equally good combinations are found, it returns the parameters which yield the highest VCO
frequency, for best output stability. The -l or --low-vco flag will instead prefer lower frequencies, for reduced power
consumption.
Here a 48 MHz output is requested:
$ ./vcocalc.py 48
Requested: 48.0 MHz
Achieved: 48.0 MHz
FBDIV: 120 (VCO = 1440 MHz)
PD1: 6
PD2: 5
Asking for a 48 MHz output with a lower VCO frequency, if possible:
$ ./vcocalc.py -l 48
Requested: 48.0 MHz
Achieved: 48.0 MHz
FBDIV: 36 (VCO = 432 MHz)
PD1: 3
PD2: 3
For a 125 MHz system clock with a 12 MHz input, the minimum VCO frequency is quite high.
$ ./vcocalc.py -l 125
Requested: 125.0 MHz
Achieved: 125.0 MHz
FBDIV: 125 (VCO = 1500 MHz)
PD1: 6
RP2040 Datasheet
2.18. PLL 253