


/* I was unable to find good information on how the PLL dividers work
in the ECP5 PLL Design and Usage Guide, so I ran several frequencies
through Lattice's clarity designer, and was surprised with what I
found:
| Input | Output | refclk | feedback | output | fvco |
|    12 |     48 |      1 |        4 |     12 |  576 |
|    12 |     60 |      1 |        5 |     10 |  600 |
|    20 |     30 |      2 |        3 |     20 |  600 |
|    45 |     30 |      3 |        2 |     20 |  600 |
|   100 |    400 |      1 |        4 |      1 |  400 |
|   200 |    400 |      1 |        2 |      2 |  800 |
|    50 |    400 |      1 |        8 |      2 |  800 |
|    70 |     40 |      7 |        4 |     15 |  600 |
|    12 |     36 |      1 |        3 |     18 |  648 |
|    12 |     96 |      1 |        8 |      6 |  576 |
|    90 |     40 |      9 |        4 |     15 |  600 |
|    90 |     50 |      9 |        5 |     13 |  650 |
|    43 |     86 |      1 |        2 |      7 |  602 |

it appears that
f_pfd = f_in/refclk
f_vco = f_pfd * feedback * output
f_out = f_vco / output
 */

#define INPUT_MIN 8.0f
#define INPUT_MAX 400.0f
#define OUTPUT_MIN 10.0f
#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
#include <iostream>
#include <limits>
#include <boost/program_options.hpp>
using namespace std;


struct pll_params{
  int refclk_div;
  int feedback_div;
  int output_div;

  float fout;
  float fvco;
};

pll_params calc_pll_params(float input, float output);

int main(int argc, char** argv){
  namespace po = boost::program_options;
  po::options_description options("Allowed options");

  options.add_options()("help,h", "show help");
  options.add_options()("input,i", po::value<float>()->required(), "Input frequency in MHz");
  options.add_options()("output,o", po::value<float>()->required(), "Output frequency in MHz");

  po::variables_map vm;
  po::parsed_options parsed = po::command_line_parser(argc, argv).options(options).run();
  po::store(parsed, vm);
  po::notify(vm);

  if(vm.count("help")){
    cerr << "Project Trellis - Open Source Tools for ECP5 FPGAs" << endl;
    cerr << "ecpunpack: ECP5 bitstream to text config converter" << endl;
    cerr << endl;
    cerr << "Copyright (C) 2018 David Shah <david@symbioticeda.com>" << endl;
    cerr << endl;
    cerr << options << endl;
  }
  float inputf = vm["input"].as<float>();
  float outputf = vm["output"].as<float>();
  if(inputf < INPUT_MIN || inputf > INPUT_MAX){
    fprintf(stderr, "Input frequency %.3fMHz not in range (%.3fMHz, %.3fMHz)\n",
	    inputf, INPUT_MIN, INPUT_MAX);
    return 1;
  }
  if(outputf < OUTPUT_MIN || outputf > OUTPUT_MAX){
    fprintf(stderr, "Output frequency %.3fMHz not in range (%.3fMHz, %.3fMHz)\n",
	    outputf, OUTPUT_MIN, OUTPUT_MAX);
    return 1;
  }
  pll_params params = calc_pll_params(inputf, outputf);

  fprintf(stdout, "Pll parameters:\n");
  fprintf(stdout, "Refclk divisor: %d\n", params.refclk_div);
  fprintf(stdout, "Feedback divisor: %d\n", params.feedback_div);
  fprintf(stdout, "Output divisor: %d\n", params.output_div);
  fprintf(stdout, "VCO frequency: %f\n", params.fvco);
  fprintf(stdout, "Output frequency: %f\n", params.fout);

}

pll_params calc_pll_params(float input, float output){
  float error = std::numeric_limits<float>::max();
  pll_params params = {0};
  for(int input_div=1;input_div <= 128; input_div++){

    float fpfd = input / (float)input_div;
    if(fpfd < PFD_MIN || fpfd > PFD_MAX)
      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;
	
	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))){
	  error = fabsf(fout-output);
	  params.refclk_div = input_div;
	  params.feedback_div = feedback_div;
	  params.output_div = output_div;
	  params.fout = fout;
	  params.fvco = fvco;

	}

      }
    }
  }
  return params;
  
}
