import operator # first set the desired frequency and constraints input_f_xtal = 20_000_000 # 20 MHz crystal on the inputs input_f_cpu = 333_333_333 # 297 MHz should go to the CPU #input_f_error = 250_000 # allow 100 KHz error input_f_error = input_f_cpu*1e-6*100 # allow 100 ppm tollerance def main(): # determin if the crystal frequency is in bound. values from cgracey assembler file if input_f_xtal < 250_000: print ("Sorry, {:,} Hz is to low for the crystal frequency".format(input_f_xtal)) return if input_f_xtal > 500_000_000: print ("Sorry, {:,} Hz is to high for the crystal frequency".format(input_f_xtal)) return # determin if we are in reachable bounds for f_cpu. values from cgracey assembler file if input_f_cpu < 3_333_333: print ("Sorry, can not reach {:,} Hz on f_cpu. It is too low".format(input_f_cpu)) return if input_f_cpu > 500_000_000: print ("Sorry, can not reach {:,} Hz on f_cpu. It is too high".format(input_f_cpu)) return # now iterate calculate and record results CalculatedValues=list() # iterate postDivider for phelp in range (0,16): # 0..15 #calc the real postDivider if phelp==15: pre=1 else: pre=(phelp+1)*2 # iterate PLL mulitiplier for mul in range (1,1025): # 1..1024 # iterate preDivider for post in range (1,65): # 1..64 f_afterpre = input_f_xtal / pre if f_afterpre<250_000: # do not predivide below 250 KHz. value from forum continue f_vco = f_afterpre * mul if f_vco<100_000_000 or f_vco >500_000_000: #make sure the VCO runs between 100 and 500 MHz continue f_cpu = round(f_vco/post) #round for a whole numer if f_cpu<3_333_333 or f_cpu >500_000_000: #make sure the cpu runs between 3.333 and 500 MHz continue error = abs(f_cpu - input_f_cpu) if error>input_f_error: continue CalculatedValues.append(RegisterValues(pre,mul,post,error)) ##end for post ##end for mul ##end for pre # now sort the list by error,pre then post CalculatedValues.sort(key=operator.attrgetter("error","pre","post")) # now print the things we have found index=0 while index<3 and index