Created
February 3, 2021 16:26
-
-
Save newhouseb/9b563d8e95d14cb7fde9ed591bdb1fde to your computer and use it in GitHub Desktop.
ECP5 PLL w/ nmigen
This file contains hidden or 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
from nmigen import * | |
from pprint import pprint | |
PFD_MIN = 3.125 | |
PFD_MAX = 400 | |
VCO_MIN = 400 | |
VCO_MAX = 800 | |
def find_pll_params(input, output): | |
freqs = [] | |
for input_div in range(1,129): | |
fpfd = input / float(input_div) | |
if fpfd < PFD_MIN: | |
continue | |
if fpfd > PFD_MAX: | |
continue | |
for feedback_div in range(1, 81): | |
for output_div in range(1,129): | |
fvco = fpfd * float(feedback_div) * float(output_div) | |
if fvco < VCO_MIN or fvco > VCO_MAX: | |
continue | |
fout = fvco / float(output_div) | |
if fout == output: | |
return (input_div, feedback_div, output_div) | |
freqs.append(fout) | |
return sorted(list(set(freqs))) | |
class PLL(Elaboratable): | |
def __init__(self, output=None, clock_freq=48, desired_freq=96): | |
self.clock_freq = clock_freq | |
self.desired_freq = desired_freq | |
self.output = output | |
def elaborate(self, platform): | |
m = Module() | |
#print("Possible Frequencies") | |
#pprint(find_pll_params(self.clock_freq, None)) | |
input_div, feedback_div, output_div = find_pll_params(self.clock_freq, self.desired_freq) | |
m.submodules.multiplier = Instance( | |
"EHXPLLL", | |
a_FREQUENCY_PIN_CLKI=str(self.clock_freq), | |
a_FREQUENCY_PIN_CLKOP=str(self.desired_freq), | |
a_ICP_CURRENT="12", | |
a_LPF_RESISTOR="8", | |
a_MFG_ENABLE_FILTEROPAMP="1", | |
a_MFG_GMCREF_SEL="2", | |
p_PLLRST_ENA="DISABLED", | |
p_INTFB_WAKE="DISABLED", | |
p_STDBY_ENABLE="DISABLED", | |
p_OUTDIVIDER_MUXA="DIVA", | |
p_OUTDIVIDER_MUXB="DIVB", | |
p_OUTDIVIDER_MUXC="DIVC", | |
p_OUTDIVIDER_MUXD="DIVD", | |
p_CLKI_DIV=input_div, | |
p_CLKOP_ENABLE="ENABLED", | |
p_CLKOP_DIV=output_div, | |
p_CLKOP_CPHASE=0, | |
p_CLKOP_FPHASE=0, | |
p_FEEDBK_PATH="CLKOP", | |
p_CLKFB_DIV=feedback_div, | |
i_RST=0, | |
i_STDBY=0, | |
i_CLKI=ClockSignal(), | |
o_CLKOP=self.output, | |
i_CLKFB=self.output, | |
# i_CLKINTFB | |
i_PHASESEL0=0, | |
i_PHASESEL1=0, | |
i_PHASEDIR=1, | |
i_PHASESTEP=1, | |
i_PHASELOADREG=1, | |
i_PLLWAKESYNC=0, | |
i_ENCLKOP=1 | |
# o_LOCK | |
) | |
return m |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment