/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  Copyright (C) 2019  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.
 *
 *  ---
 *
 *   XDC commands
 *
 *   This plugin operates on the existing design and modifies its structure
 *   based on the content of the XDC (Xilinx Design Constraints) file.
 *   Since the XDC file consists of Tcl commands it is read using Yosys's
 *   Tcl interpreter and processed by the new XDC commands imported to the
 *   Tcl interpreter.
 */
#include "../common/bank_tiles.h"
#include "../common/utils.h"
#include "kernel/log.h"
#include "kernel/register.h"
#include "kernel/rtlil.h"
#include "libs/json11/json11.hpp"
#include <cassert>

USING_YOSYS_NAMESPACE

PRIVATE_NAMESPACE_BEGIN

static bool isInputPort(RTLIL::Wire *wire) { return wire->port_input; }
static bool isOutputPort(RTLIL::Wire *wire) { return wire->port_output; }

enum class SetPropertyOptions { INTERNAL_VREF, IOSTANDARD, SLEW, DRIVE, IN_TERM, IO_LOC_PAIRS };

const std::unordered_map<std::string, SetPropertyOptions> set_property_options_map = {{"INTERNAL_VREF", SetPropertyOptions::INTERNAL_VREF},
                                                                                      {"IOSTANDARD", SetPropertyOptions::IOSTANDARD},
                                                                                      {"SLEW", SetPropertyOptions::SLEW},
                                                                                      {"DRIVE", SetPropertyOptions::DRIVE},
                                                                                      {"IN_TERM", SetPropertyOptions::IN_TERM},
                                                                                      {"LOC", SetPropertyOptions::IO_LOC_PAIRS},
                                                                                      {"PACKAGE_PIN", SetPropertyOptions::IO_LOC_PAIRS}};

// Apart from the common I/OBUFs there is also the GTPE2_CHANNEL primitive which has a total
// of four IOPADs (2 IPADs and 2 OPADs) which are directly connected to the GTP[RT]X[PN] ports
// of the BEL. The GTPE2_CHANNEL holds all the placement constraints information of the
// corresponding PADs
const std::unordered_map<std::string, std::vector<std::string>> supported_primitive_parameters = {
  {"OBUF", {"IO_LOC_PAIRS", "IOSTANDARD", "DRIVE", "SLEW", "IN_TERM"}},
  {"OBUFDS", {"IO_LOC_PAIRS", "IOSTANDARD", "SLEW", "IN_TERM"}},
  {"OBUFTDS", {"IO_LOC_PAIRS", "IOSTANDARD", "SLEW", "IN_TERM"}},
  {"IBUF", {"IO_LOC_PAIRS", "IOSTANDARD"}},
  {"IOBUF", {"IO_LOC_PAIRS", "IOSTANDARD", "DRIVE", "SLEW", "IN_TERM"}},
  {"IOBUFDS", {"IO_LOC_PAIRS", "IOSTANDARD", "SLEW", "IN_TERM"}},
  {"IBUFDS_GTE2", {"IO_LOC_PAIRS"}},
  {"GTPE2_CHANNEL", {"IO_LOC_PAIRS"}}};

void register_in_tcl_interpreter(const std::string &command)
{
    Tcl_Interp *interp = yosys_get_tcl_interp();
    std::string tcl_script = stringf("proc %s args { return [yosys %s {*}$args] }", command.c_str(), command.c_str());
    Tcl_Eval(interp, tcl_script.c_str());
}

struct GetIOBanks : public Pass {
    GetIOBanks(std::function<const BankTilesMap &()> get_bank_tiles) : Pass("get_iobanks", "Set IO Bank number"), get_bank_tiles(get_bank_tiles)
    {
        register_in_tcl_interpreter(pass_name);
    }

    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("   get_iobanks <bank_number>\n");
        log("\n");
        log("Get IO Bank number\n");
        log("\n");
    }

    void execute(std::vector<std::string> args, RTLIL::Design *) override
    {
        if (args.size() < 2) {
            log_cmd_error("%s: Missing bank number.\n", pass_name.c_str());
        }
        auto bank_tiles = get_bank_tiles();
        if (bank_tiles.count(std::atoi(args[1].c_str())) == 0) {
            log_cmd_error("%s:Bank number %s is not present in the target device.\n", args[1].c_str(), pass_name.c_str());
        }

        Tcl_Interp *interp = yosys_get_tcl_interp();
        Tcl_SetResult(interp, const_cast<char *>(args[1].c_str()), NULL);
        log("%s\n", args[1].c_str());
    }

    std::function<const BankTilesMap &()> get_bank_tiles;
};

struct SetProperty : public Pass {
    SetProperty(std::function<const BankTilesMap &()> get_bank_tiles) : Pass("set_property", "Set a given property"), get_bank_tiles(get_bank_tiles)
    {
        register_in_tcl_interpreter(pass_name);
    }

    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("    set_property PROPERTY VALUE OBJECT\n");
        log("or\n");
        log("    set_property -dict { PROPERTY VALUE PROPERTY2 VALUE2 } OBJECT\n");
        log("\n");
        log("Set the given property to the specified value on an object\n");
        log("\n");
    }

    void execute(std::vector<std::string> args, RTLIL::Design *design) override
    {
        if (design->top_module() == nullptr) {
            log_cmd_error("No top module detected\n");
        }
        if (args.at(1) == "-dict") {
            std::string dict_args = args.at(2);
            trim(dict_args);
            std::stringstream args_stream(dict_args);
            std::vector<std::string> tokens;
            std::string intermediate;
            while (getline(args_stream, intermediate, ' ')) {
                if (intermediate != "\0") {
                    tokens.push_back(intermediate);
                }
            }
            if (tokens.size() % 2 != 0) {
                log_cmd_error("Invalid number of dict parameters: %lu.\n", tokens.size());
            }
            for (long unsigned int i = 0; i < tokens.size(); i += 2) {
                std::vector<std::string> new_args(args);
                new_args.at(1) = tokens[i];
                new_args.at(2) = tokens[i + 1];
                read_property(new_args, design);
            }
        } else {
            read_property(args, design);
        }
    }

    void read_property(std::vector<std::string> args, RTLIL::Design *design)
    {
        std::string option(args[1]);
        if (set_property_options_map.count(option) == 0) {
            log_warning("set_property: %s option is currently not supported\n", option.c_str());
            return;
        }

        switch (set_property_options_map.at(option)) {
        case SetPropertyOptions::INTERNAL_VREF:
            process_vref(std::vector<std::string>(args.begin() + 2, args.end()), design);
            break;
        case SetPropertyOptions::IOSTANDARD:
        case SetPropertyOptions::SLEW:
        case SetPropertyOptions::DRIVE:
        case SetPropertyOptions::IN_TERM:
            process_port_parameter(std::vector<std::string>(args.begin() + 1, args.end()), design);
            break;
        case SetPropertyOptions::IO_LOC_PAIRS: {
            // args "set_property LOC PAD PORT" become "IO_LOC_PAIRS PORT:PAD PORT"
            std::vector<std::string> new_args(args.begin() + 1, args.end());
            new_args.at(0) = "IO_LOC_PAIRS";
            new_args.at(1) = new_args.at(2) + ":" + new_args.at(1);
            process_port_parameter(new_args, design);
            break;
        }
        default:
            assert(false);
        }
    }

    void process_vref(std::vector<std::string> args, RTLIL::Design *design)
    {
        if (args.size() < 2) {
            log_error("set_property INTERNAL_VREF: Incorrect number of arguments.\n");
        }
        int iobank = std::atoi(args[1].c_str());
        auto bank_tiles = get_bank_tiles();
        if (bank_tiles.count(iobank) == 0) {
            log_cmd_error("set_property INTERNAL_VREF: Invalid IO bank.\n");
        }

        int internal_vref = 1000 * std::atof(args[0].c_str());
        if (internal_vref != 600 && internal_vref != 675 && internal_vref != 750 && internal_vref != 900) {
            log("set_property INTERNAL_VREF: Incorrect INTERNAL_VREF value\n");
            return;
        }

        // Create a new BANK module if it hasn't been created so far
        RTLIL::Module *top_module = design->top_module();
        if (!design->has(ID(BANK))) {
            std::string fasm_extra_modules_dir(proc_share_dirname() + "/plugins/fasm_extra_modules");
            Pass::call(design, "read_verilog " + fasm_extra_modules_dir + "/BANK.v");
        }

        // Set parameters on a new bank instance or update an existing one
        char bank_cell_name[16];
        snprintf(bank_cell_name, 16, "\\bank_cell_%d", iobank);
        RTLIL::Cell *bank_cell = top_module->cell(RTLIL::IdString(bank_cell_name));
        if (!bank_cell) {
            bank_cell = top_module->addCell(RTLIL::IdString(bank_cell_name), ID(BANK));
        }
        bank_cell->setParam(ID(FASM_EXTRA), RTLIL::Const("INTERNAL_VREF"));
        bank_cell->setParam(ID(NUMBER), RTLIL::Const(iobank));
        bank_cell->setParam(ID(INTERNAL_VREF), RTLIL::Const(internal_vref));
    }

    void process_port_parameter(std::vector<std::string> args, RTLIL::Design *design)
    {
        if (args.size() < 1) {
            log_error("set_property: Incorrect number of arguments.\n");
        }

        std::string parameter(args.at(0));
        if (args.size() < 3 || args.at(2).size() == 0) {
            log_error("set_property %s: Incorrect number of arguments.\n", parameter.c_str());
        }

        std::string port_name(args.at(2));
        std::string value(args.at(1));

        auto port_signal = extract_signal(port_name);
        std::string port(port_signal.first);
        int port_bit = port_signal.second;

        RTLIL::Wire *wire = design->top_module()->wire(RTLIL::escape_id(port));
        if (wire == nullptr) {
            log_error("Couldn't find port %s\n", port_name.c_str());
        }

        if (!isInputPort(wire) && !isOutputPort(wire)) {
            log_error("Port %s is not a top port\n", port_name.c_str());
        }

        if (port_bit < wire->start_offset || port_bit >= wire->start_offset + wire->width) {
            log_error("Incorrect top port index %d in port %s\n", port_bit, port_name.c_str());
        }

        // Traverse the port wire
        traverse_wire(port_name, design->top_module());

        RTLIL::IdString parameter_id(RTLIL::escape_id(parameter));
        for (auto cell_obj : design->top_module()->cells_) {
            RTLIL::IdString cell_id = cell_obj.first;
            RTLIL::Cell *cell = cell_obj.second;

            // Check if the cell is of the type we are looking for
            auto cell_type_str = RTLIL::unescape_id(cell->type.str());
            auto primitive_parameters_iter = supported_primitive_parameters.find(cell_type_str);
            if (primitive_parameters_iter == supported_primitive_parameters.end()) {
                continue;
            }

            // Set the parameter on the cell connected to the selected port
            for (auto connection : cell->connections_) {
                RTLIL::SigSpec cell_signal = connection.second;
                if (is_signal_port(cell_signal, port_name)) {
                    // Check if the attribute is allowed for this module
                    auto primitive_parameters = primitive_parameters_iter->second;
                    if (std::find(primitive_parameters.begin(), primitive_parameters.end(), parameter) == primitive_parameters.end()) {
                        log_error("Cell %s of type %s doesn't support the %s attribute\n", cell->name.c_str(), cell->type.c_str(),
                                  parameter_id.c_str());
                    }
                    if (parameter_id == ID(IO_LOC_PAIRS) and cell->hasParam(parameter_id)) {
                        std::string cur_value(cell->getParam(parameter_id).decode_string());
                        value = cur_value + "," + value;
                    }
                    cell->setParam(parameter_id, RTLIL::Const(value));
                    log("Setting parameter %s to value %s on cell %s \n", parameter_id.c_str(), value.c_str(), cell_obj.first.c_str());
                }
            }
        }
        log("\n");
    }

    // Search module's connections for the specified destination port
    // and traverse from the specified destination wire to the source wire
    void traverse_wire(std::string &port_name, RTLIL::Module *module)
    {
        auto port_signal = extract_signal(port_name);
        std::string signal_name(port_signal.first);
        auto signal_name_idstr = RTLIL::IdString(RTLIL::escape_id(signal_name));
        int port_bit = port_signal.second;
        for (auto connection : module->connections_) {
            auto dst_sig = connection.first;
            auto src_sig = connection.second;
            if (dst_sig.is_chunk()) {
                auto chunk = dst_sig.as_chunk();
                if (chunk.wire) {
                    if (chunk.wire->name != signal_name_idstr) {
                        continue;
                    }
                    if (port_bit < chunk.offset || port_bit >= (chunk.offset + chunk.width)) {
                        continue;
                    }
                    auto src_wires = src_sig.to_sigbit_vector();
                    auto src_wire_sigbit = src_wires.at(port_bit - chunk.offset);
                    if (src_wire_sigbit.wire) {
                        port_name = src_wires.at(port_bit - chunk.offset).wire->name.str();
                        if (src_wire_sigbit.offset > 0) {
                            port_name += "[" + std::to_string(src_wire_sigbit.offset) + "]";
                        }
                        return;
                    }
                }
            }
        }
    }

    // Extract signal name and port bit information from port name
    std::pair<std::string, int> extract_signal(const std::string &port_name)
    {
        int port_bit(0);
        std::string port_str(port_name.size(), '\0');
        sscanf(port_name.c_str(), "%[^[][%d]", &port_str[0], &port_bit);
        port_str.resize(strlen(port_str.c_str()));
        return std::make_pair(port_str, port_bit);
    }

    // Check if the specified port name is part of the provided connection signal
    bool is_signal_port(RTLIL::SigSpec signal, const std::string &port_name)
    {
        auto port_signal = extract_signal(port_name);
        std::string port(port_signal.first);
        int port_bit = port_signal.second;
        if (signal.is_chunk()) {
            auto chunk = signal.as_chunk();
            if (chunk.wire) {
                return (chunk.wire->name == RTLIL::IdString(RTLIL::escape_id(port))) && (port_bit == chunk.offset);
            }
        }
        return false;
    }

    std::function<const BankTilesMap &()> get_bank_tiles;
};

struct ReadXdc : public Frontend {
    ReadXdc()
        : Frontend("xdc", "Read XDC file"), GetIOBanks(std::bind(&ReadXdc::get_bank_tiles, this)),
          SetProperty(std::bind(&ReadXdc::get_bank_tiles, this))
    {
    }

    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("    read_xdc -part_json <part_json_filename> <filename>\n");
        log("\n");
        log("Read XDC file.\n");
        log("\n");
    }

    void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *) override
    {
        if (args.size() < 2) {
            log_cmd_error("Missing script file.\n");
        }
        size_t argidx = 1;
        bank_tiles.clear();
        if (args[argidx] == "-part_json" && argidx + 1 < args.size()) {
            bank_tiles = ::get_bank_tiles(args[++argidx]);
            argidx++;
        }
        extra_args(f, filename, args, argidx);
        std::string content{std::istreambuf_iterator<char>(*f), std::istreambuf_iterator<char>()};
        log("%s\n", content.c_str());

        // According to page 6 of UG903 XDC is tcl, hence quoting of bracketed numbers,
        // such as bus indexes, is required. For example "signal[5]" would be typically
        // expanded to the concatenation of the string "signal" and result of the function call "5"
        // with no arguments. Therefore in TCL the signal indices have to be wrapped in curly braces
        // e.g "{signal[5]}" in order for the interpreter to not perform any variable substitution
        // or function calls on the wrapped content.
        //
        // Nevertheless, it's quite common for EDA tools to allow for specifying signal indices
        // (e.g. "signal[5]") without using non-expanding quotes.
        // Possible TCL implementations of such a feature include registering a TCL command
        // for each integer which returns itself but surrounded with brackets or using the 'unknown'
        // command which is invoked by the Tcl interpreter whenever a script tries to invoke a command
        // that does not exist. In the XDC plugin the latter approach is used, however it's limited to
        // the 'read_xdc' command, hence the 'unknown' command works solely on the content of the XDC file.
        //
        // In this implementation the signal "signal[5]" is expanded in TCL to the concatenation of a string
        // and function call, however this time the handling of the non-existent command '5' is passed by
        // the interpreter to the 'unknown' command which returns a string that consists of the indice
        // integer surrounded by square brackets, i.e. "[5]", effectively expanding the signal to "signal[5]"
        // string.
        //
        Tcl_Interp *interp = yosys_get_tcl_interp();
        Tcl_Eval(interp, "rename unknown _original_unknown");
        Tcl_Eval(interp, "proc unknown args { return \\[[lindex $args 0]\\] }");
        if (Tcl_EvalFile(interp, args[argidx].c_str()) != TCL_OK) {
            log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp));
        }
        Tcl_Eval(interp, "rename unknown \"\"");
        Tcl_Eval(interp, "rename _original_unknown unknown");
    }
    const BankTilesMap &get_bank_tiles() { return bank_tiles; }

    BankTilesMap bank_tiles;
    struct GetIOBanks GetIOBanks;
    struct SetProperty SetProperty;
} ReadXdc;

struct GetBankTiles : public Pass {
    GetBankTiles() : Pass("get_bank_tiles", "Inspect IO Bank tiles") { register_in_tcl_interpreter(pass_name); }

    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("   get_bank_tiles <part_json_file>\n");
        log("\n");
        log("Inspect IO Bank tiles for the specified part based on the provided JSON file.\n");
        log("\n");
    }

    void execute(std::vector<std::string> args, RTLIL::Design *) override
    {
        if (args.size() < 2) {
            log_cmd_error("Missing JSON file.\n");
        }
        // Check if the part has the specified bank
        auto bank_tiles = get_bank_tiles(args[1]);
        if (bank_tiles.size()) {
            log("Available bank tiles:\n");
            for (auto bank : bank_tiles) {
                log("Bank: %d, Tile: %s\n", bank.first, bank.second.c_str());
            }
            log("\n");
        } else {
            log("No bank tiles available.\n");
        }
    }
} GetBankTiles;

PRIVATE_NAMESPACE_END
