/*
 *  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 "propagation.h"
#include <cassert>

USING_YOSYS_NAMESPACE

std::vector<RTLIL::Wire*> NaturalPropagation::FindAliasWires(
    RTLIL::Wire* wire) {
    RTLIL::Module* top_module = design_->top_module();
    assert(top_module);
    std::vector<RTLIL::Wire*> alias_wires;
    pass_->extra_args(
        std::vector<std::string>{
            top_module->name.str() + "/w:" + wire->name.str(), "%a"},
        0, design_);
    for (auto module : design_->selected_modules()) {
	for (auto wire : module->selected_wires()) {
	    alias_wires.push_back(wire);
	}
    }
    return alias_wires;
}

std::vector<Clock> ClockDividerPropagation::FindSinkClocksForCellType(
    RTLIL::Wire* driver_wire, const std::string& cell_type) {
    std::vector<Clock> clocks;
    if (cell_type == "PLLE2_ADV") {
	RTLIL::Cell* cell = NULL;
	for (auto input : Pll::inputs) {
	    cell = FindSinkCellOnPort(driver_wire, input);
	    if (cell and RTLIL::unescape_id(cell->type) == cell_type) {
		break;
	    }
	}
	if (!cell) {
	    return clocks;
	}
	Pll pll(cell);
	for (auto output : Pll::outputs) {
	    RTLIL::Wire* wire = FindSinkWireOnPort(cell, output);
	    if (wire) {
		float period(pll.CalculatePeriod(output));
		Clock clock(RTLIL::unescape_id(wire->name), wire, period, 0,
		            period / 2);
		clocks.push_back(clock);
		auto further_clocks =
		    FindSinkClocksForCellType(wire, cell_type);
		std::copy(further_clocks.begin(), further_clocks.end(),
		          std::back_inserter(clocks));
	    }
	}
    }
    return clocks;
}

RTLIL::Cell* Propagation::FindSinkCellOfType(RTLIL::Wire* wire,
                                             const std::string& type) {
    RTLIL::Cell* sink_cell = NULL;
    if (!wire) {
	return sink_cell;
    }
    RTLIL::Module* top_module = design_->top_module();
    assert(top_module);
    std::string base_selection =
        top_module->name.str() + "/w:" + wire->name.str();
    pass_->extra_args(std::vector<std::string>{base_selection, "%co:+" + type,
                                               base_selection, "%d"},
                      0, design_);
    auto selected_cells = top_module->selected_cells();
    // FIXME Handle more than one sink
    assert(selected_cells.size() <= 1);
    if (selected_cells.size() > 0) {
	sink_cell = selected_cells.at(0);
#ifdef SDC_DEBUG
	log("Found sink cell: %s\n",
	    RTLIL::unescape_id(sink_cell->name).c_str());
#endif
    }
    return sink_cell;
}

std::vector<RTLIL::Wire*> Propagation::FindSinkWiresForCellType(
    RTLIL::Wire* driver_wire, const std::string& cell_type,
    const std::string& cell_port) {
    std::vector<RTLIL::Wire*> wires;
    if (!driver_wire) {
	return wires;
    }
    auto cell = FindSinkCellOfType(driver_wire, cell_type);
    RTLIL::Wire* wire = FindSinkWireOnPort(cell, cell_port);
    if (wire) {
	wires.push_back(wire);
	auto further_wires =
	    FindSinkWiresForCellType(wire, cell_type, cell_port);
	std::copy(further_wires.begin(), further_wires.end(),
	          std::back_inserter(wires));
    }
    return wires;
}

RTLIL::Cell* Propagation::FindSinkCellOnPort(RTLIL::Wire* wire,
                                             const std::string& port) {
    RTLIL::Cell* sink_cell = NULL;
    if (!wire) {
	return sink_cell;
    }
    RTLIL::Module* top_module = design_->top_module();
    assert(top_module);
    std::string base_selection =
        top_module->name.str() + "/w:" + wire->name.str();
    pass_->extra_args(
        std::vector<std::string>{base_selection, "%co:+[" + port + "]",
                                 base_selection, "%d"},
        0, design_);
    auto selected_cells = top_module->selected_cells();
    // FIXME Handle more than one sink
    assert(selected_cells.size() <= 1);
    if (selected_cells.size() > 0) {
	sink_cell = selected_cells.at(0);
#ifdef SDC_DEBUG
	log("Found sink cell: %s\n",
	    RTLIL::unescape_id(sink_cell->name).c_str());
#endif
    }
    return sink_cell;
}

RTLIL::Wire* Propagation::FindSinkWireOnPort(RTLIL::Cell* cell,
                                             const std::string& port_name) {
    RTLIL::Wire* sink_wire = NULL;
    if (!cell) {
	return sink_wire;
    }
    RTLIL::Module* top_module = design_->top_module();
    assert(top_module);
    std::string base_selection =
        top_module->name.str() + "/c:" + cell->name.str();
    pass_->extra_args(
        std::vector<std::string>{base_selection, "%co:+[" + port_name + "]",
                                 base_selection, "%d"},
        0, design_);
    auto selected_wires = top_module->selected_wires();
    // FIXME Handle more than one sink
    assert(selected_wires.size() <= 1);
    if (selected_wires.size() > 0) {
	sink_wire = selected_wires.at(0);
#ifdef SDC_DEBUG
	log("Found sink wire: %s\n",
	    RTLIL::unescape_id(sink_wire->name).c_str());
#endif
    }
    return sink_wire;
}
