/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2020  The Symbiflow Authors
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include "buffers.h"
#include <cassert>
#include <cmath>

const std::vector<std::string> Pll::inputs = {"CLKIN1", "CLKIN2"};
const std::vector<std::string> Pll::outputs = {"CLKOUT0", "CLKOUT1", "CLKOUT2",
                                               "CLKOUT3", "CLKOUT4", "CLKOUT5"};
const float Pll::delay = 0;
const std::string Pll::name = "PLLE2_ADV";

Pll::Pll(RTLIL::Cell* cell, float input_clock_period,
         float input_clock_rising_edge)
    : ClockDivider({"PLLE2_ADV"}) {
    assert(RTLIL::unescape_id(cell->type) == "PLLE2_ADV");
    FetchParams(cell);
    CheckInputClockPeriod(cell, input_clock_period);
    CalculateOutputClockPeriods();
    CalculateOutputClockWaveforms(input_clock_rising_edge);
}

void Pll::CheckInputClockPeriod(RTLIL::Cell* cell, float input_clock_period) {
    float abs_diff = fabs(ClkinPeriod() - input_clock_period);
    bool approx_equal = abs_diff < std::max(ClkinPeriod(), input_clock_period) *
                                       10 *
                                       std::numeric_limits<float>::epsilon();
    if (!approx_equal) {
	log_cmd_error(
	    "CLKIN[1/2]_PERIOD doesn't match the virtual clock constraint "
	    "propagated to the CLKIN[1/2] input of the clock divider cell: "
	    "%s.\nInput clock period: %f, CLKIN[1/2]_PERIOD: %f\n",
	    RTLIL::id2cstr(cell->name), input_clock_period, ClkinPeriod());
    }
}

void Pll::FetchParams(RTLIL::Cell* cell) {
    clkin1_period = FetchParam(cell, "CLKIN1_PERIOD", 0.0);
    clkin2_period = FetchParam(cell, "CLKIN2_PERIOD", 0.0);
    clk_mult = FetchParam(cell, "CLKFBOUT_MULT", 5.0);
    clk_fbout_phase = FetchParam(cell, "CLKFBOUT_PHASE", 0.0);
    divclk_divisor = FetchParam(cell, "DIVCLK_DIVIDE", 1.0);
    for (auto output : outputs) {
	// CLKOUT[0-5]_DUTY_CYCLE
	clkout_duty_cycle[output] =
	    FetchParam(cell, output + "_DUTY_CYCLE", 0.5);
	// CLKOUT[0-5]_DIVIDE
	clkout_divisor[output] = FetchParam(cell, output + "_DIVIDE", 1.0);
	// CLKOUT[0-5]_PHASE
	clkout_phase[output] = FetchParam(cell, output + "_PHASE", 0.0);
    }
}

void Pll::CalculateOutputClockPeriods() {
    for (auto output : outputs) {
	// CLKOUT[0-5]_PERIOD = CLKIN1_PERIOD * CLKOUT[0-5]_DIVIDE *
	// DIVCLK_DIVIDE / CLKFBOUT_MULT
	clkout_period[output] = ClkinPeriod() * clkout_divisor.at(output) /
	                        clk_mult * divclk_divisor;
    }
}

void Pll::CalculateOutputClockWaveforms(float input_clock_rising_edge) {
    for (auto output : outputs) {
	float output_clock_period = clkout_period.at(output);
	clkout_rising_edge[output] =
	    fmod(input_clock_rising_edge -
	             (clk_fbout_phase / 360.0) * ClkinPeriod() +
	             output_clock_period * (clkout_phase[output] / 360.0),
	         output_clock_period);
	clkout_falling_edge[output] =
	    fmod(clkout_rising_edge[output] +
	             clkout_duty_cycle[output] * output_clock_period,
	         output_clock_period);
    }
}

float Pll::FetchParam(RTLIL::Cell* cell, std::string&& param_name,
                      float default_value) {
    RTLIL::IdString param(RTLIL::escape_id(param_name));
    if (cell->hasParam(param)) {
	auto param_obj = cell->parameters.at(param);
	std::string value;
	if (param_obj.flags & RTLIL::CONST_FLAG_STRING) {
	    value = param_obj.decode_string();
	} else {
	    value = std::to_string(param_obj.as_int());
	}
	return std::stof(value);
    }
    return default_value;
}
