/*
 *  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 "../bank_tiles.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}};

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"}}};

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("\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");
        }

        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
