From adc676d24c41f7ff3d6b509b4fb9f4114d736d31 Mon Sep 17 00:00:00 2001 From: x44203 <60701660+x44203@users.noreply.github.com> Date: Fri, 7 Feb 2020 01:59:18 +0100 Subject: [PATCH] Wider range of PLL usage I experimentally tested the PLL range to be from 30-948 MHz and it doesn't lock when fpfd = 2 MHz and fvco = 600 MHz but it does when fvco = 300 MHz or smaller. For example CLKOP_DIV=1 CLKFB_DIV=25 CLKI_DIV=6 works while CLKOP_DIV=12 CLKFB_DIV=25 CLKI_DIV=6 does not. Signed-off-by: x44203 --- libtrellis/tools/ecppll.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libtrellis/tools/ecppll.cpp b/libtrellis/tools/ecppll.cpp index f7b01d31..16465947 100644 --- a/libtrellis/tools/ecppll.cpp +++ b/libtrellis/tools/ecppll.cpp @@ -29,8 +29,8 @@ f_out = f_vco / output #define OUTPUT_MAX 400.0f #define PFD_MIN 3.125f #define PFD_MAX 400.0f -#define VCO_MIN 400.0f -#define VCO_MAX 800.0f +#define VCO_MIN 60.0f //Experimentally determined 30 MHz, spurious lock at 28 MHz. 60 MHz for safety. Frequency should be kept low to attain lock when using low input frequencies. (VCO = 600 MHz, IN = 12 MHz / 6 = 2 MHz doesn't lock) +#define VCO_MAX 800.0f //Experimentally determined 948 MHz (CLKOP_DIV=79, CLKFB_FIV=25 CLKI_DIV=6) #include #include #include @@ -277,14 +277,16 @@ void calc_pll_params(pll_params ¶ms, float input, float output){ continue; for(int feedback_div=1;feedback_div <= 80; feedback_div++){ for(int output_div=1;output_div <= 128; output_div++){ - float fvco = fpfd * (float)feedback_div * (float) output_div; + float fvco = fpfd * (float)feedback_div * (float)output_div; if(fvco < VCO_MIN || fvco > VCO_MAX) continue; float fout = fvco / (float) output_div; if(fabsf(fout - output) < error || - (fabsf(fout-output) == error && fabsf(fvco - 600) < fabsf(params.fvco - 600))){ + (fabsf(fout - output) == error && + (((fpfd < 4) && fabsf(fvco - 200) < fabsf(params.fvco - 200)) || + ((fpfd >= 4) && fabsf(fvco - 600) < fabsf(params.fvco - 600))))){ error = fabsf(fout-output); params.refclk_div = input_div; params.feedback_div = feedback_div; @@ -319,7 +321,9 @@ void calc_pll_params_highres(pll_params ¶ms, float input, float output){ for(int secondary_div = 1; secondary_div <= 128; secondary_div++){ float fout = fvco / (float) secondary_div; if(fabsf(fout - output) < error || - (fabsf(fout-output) == error && fabsf(fvco - 600) < fabsf(params.fvco - 600))){ + (fabsf(fout-output) == error && + (((fpfd < 4) && fabsf(fvco - 200) < fabsf(params.fvco - 200)) || + ((fpfd >= 4) && fabsf(fvco - 600) < fabsf(params.fvco - 600))))){ error = fabsf(fout-output); params.mode = pll_mode::HIGHRES; params.refclk_div = input_div;