/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  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 "pcf_parser.hh"
#include "pinmap_parser.hh"

#include "kernel/register.h"
#include "kernel/rtlil.h"

#include <regex>
#include <sstream>

#ifndef YS_OVERRIDE
#define YS_OVERRIDE override
#endif

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct QuicklogicIob : public Pass {

    struct IoCellType {
        std::string type;                        // Cell type
        std::string port;                        // Name of the port that goes to a pad
        std::vector<std::string> preferredTypes; // A list of preferred IO cell types

        IoCellType (const std::string& _type, const std::string& _port, const std::vector<std::string> _preferredTypes = std::vector<std::string>()) :
            type(_type),
            port(_port),
            preferredTypes(_preferredTypes)
        {}
    };

    QuicklogicIob () :
        Pass("quicklogic_iob", "Map IO buffers to cells that correspond to their assigned locations") {
        }    

    void help() YS_OVERRIDE {
        log("\n");
        log("    quicklogic_iob <PCF file> <pinmap file> [<io cell specs>]");
        log("\n");
        log("This command assigns certain parameters of the specified IO cell types\n");
        log("basing on the placement constraints and the pin map of the target device\n");
        log("\n");
        log("Each affected IO cell is assigned the followin parameters:\n");
        log(" - IO_PAD  = \"<IO pad name>\"\n");
        log(" - IO_LOC  = \"<IO cell location>\"\n");
        log(" - IO_CELL = \"<IO cell type>\"\n");
        log("\n");
        log("Parameters:\n");
        log("\n");
        log("    - <PCF file>\n");
        log("        Path to a PCF file with IO constraints for the design\n");
        log("\n");
        log("    - <pinmap file>\n");
        log("        Path to a pinmap CSV file with package pin map\n");
        log("\n");
        log("    - <io cell specs> (optional)\n");
        log("        A space-separated list of <io cell type>:<port> or of\n");
        log("        <io cell type>:<port>:<preferred type 1>,<preferred type 2>...\n");
        log("        Each entry defines a type of IO cell to be affected an its port\n");
        log("        name that should connect to the top-level port of the design.\n");
        log("\n");
        log("        The third argument is a comma-separated list of preferred IO cell\n");
        log("        types in order of preference.\n");
        log("\n");
    }
    
    void execute(std::vector<std::string> a_Args, RTLIL::Design* a_Design) YS_OVERRIDE {
        if (a_Args.size() < 3) {
            log_cmd_error("    Usage: quicklogic_iob <PCF file> <pinmap file> [<io cell specs>]");
        }

        // A map of IO cell types and their port names that should go to a pad
        std::unordered_map<std::string, IoCellType> ioCellTypes;


        // Parse io cell specification
        if (a_Args.size() > 3) {

            // FIXME: Are these characters set the only ones that can be in
            // cell / port name ?
            std::regex re1("^([\\w$]+):([\\w$]+)$");
            std::regex re2("^([\\w$]+):([\\w$]+):([\\w,$]+)$");

            for (size_t i=3; i<a_Args.size(); ++i) {
                std::cmatch cm;

                // No preffered IO cell types
                if (std::regex_match(a_Args[i].c_str(), cm, re1)) {
                    ioCellTypes.emplace(cm[1].str(), IoCellType(cm[1], cm[2]));
                }

                // With preferred IO cell types
                else if (std::regex_match(a_Args[i].c_str(), cm, re2)) {
                    std::vector<std::string> preferredTypes;
                    std::stringstream ss(cm[3]);

                    while (ss.good()) {
                        std::string field;
                        std::getline(ss, field, ',');

                        preferredTypes.push_back(field);
                    }
                    
                    ioCellTypes.emplace(cm[1].str(), IoCellType(cm[1], cm[2], preferredTypes));
                }

                // Invalid
                else {
                    log_cmd_error("Invalid IO cell+port spec: '%s'\n", a_Args[i].c_str());
                }
            }
        }

        // Use the default IO cells for QuickLogic FPGAs
        else {
            ioCellTypes.emplace("inpad",  IoCellType("inpad",  "P", {"BIDIR", "SDIOMUX"}));
            ioCellTypes.emplace("outpad", IoCellType("outpad", "P", {"BIDIR", "SDIOMUX"}));
            ioCellTypes.emplace("bipad",  IoCellType("bipad",  "P", {"BIDIR", "SDIOMUX"}));
            ioCellTypes.emplace("ckpad",  IoCellType("ckpad",  "P", {"CLOCK", "BIDIR", "SDIOMUX"}));
        }

        // Get the top module of the design
        RTLIL::Module* topModule = a_Design->top_module();
        if (topModule == nullptr) {
            log_cmd_error("No top module detected!\n");
        }

        // Read and parse the PCF file
        log("Loading PCF from '%s'...\n", a_Args[1].c_str());
        auto pcfParser = PcfParser();
        if (!pcfParser.parse(a_Args[1])) {
            log_cmd_error("Failed to parse the PCF file!\n");
        }

        // Build a map of net names to constraints
        std::unordered_map<std::string, const PcfParser::Constraint> constraintMap;
        for (auto& constraint : pcfParser.getConstraints()) {
            if (constraintMap.count(constraint.netName) != 0) {
                log_cmd_error("The net '%s' is constrained twice!", constraint.netName.c_str());
            }
            constraintMap.emplace(constraint.netName, constraint);
        }

        // Read and parse pinmap CSV file
        log("Loading pinmap CSV from '%s'...\n", a_Args[2].c_str());
        auto pinmapParser = PinmapParser();
        if (!pinmapParser.parse(a_Args[2])) {
            log_cmd_error("Failed to parse the pinmap CSV file!\n");
        }

        // Build a map of pad names to entries
        std::unordered_map<std::string, std::vector<PinmapParser::Entry>> pinmapMap;
        for (auto& entry : pinmapParser.getEntries()) {
            if (entry.count("name") != 0) {
                auto& name = entry.at("name");

                if (pinmapMap.count(name) == 0) {
                    pinmapMap[name] = std::vector<PinmapParser::Entry>();
                }

                pinmapMap[name].push_back(entry);
            }
        }

        // Check all IO cells
        log("Processing cells...");
        log("\n");
        log("  type       | net        | pad        | loc      | type     | instance\n");
        log(" ------------+------------+------------+----------+----------+-----------\n");
        for (auto cell : topModule->cells()) {
            auto ysCellType = RTLIL::unescape_id(cell->type); 

            // Not an IO cell
            if (ioCellTypes.count(ysCellType) == 0) {
                continue;
            }

            log("  %-10s ", ysCellType.c_str());

            std::string netName;
            std::string padName;
            std::string locName;
            std::string cellType;

            // Get connections to the specified port
            const auto& ioCellType = ioCellTypes.at(ysCellType);
            const std::string port = RTLIL::escape_id(ioCellType.port);
            if (cell->connections().count(port)) {

                // Get the sigspec of the connection
                auto sigspec = cell->connections().at(port);

                // Get the connected wire
                for (auto sigbit : sigspec.bits()) {
                    if (sigbit.wire != nullptr) {
                        auto wire = sigbit.wire;

                        // Has to be top level wire
                        if (wire->port_input || wire->port_output) {

                            // Check if the wire is constrained. Get pad name.
                            std::string baseName = RTLIL::unescape_id(wire->name);
                            std::string netNames[] = {
                                baseName,
                                stringf("%s[%d]", baseName.c_str(), sigbit.offset),
                                stringf("%s(%d)", baseName.c_str(), sigbit.offset),
                            };

                            padName = "";
                            netName = "";

                            for (auto& name : netNames) {                       
                                if (constraintMap.count(name)) {
                                    auto constraint = constraintMap.at(name);
                                    padName = constraint.padName;
                                    netName = name;
                                    break;
                                }
                            }

                            // Check if there is an entry in the pinmap for this pad name
                            if (pinmapMap.count(padName)) {

                                // Choose a correct entry for the cell
                                auto entry = choosePinmapEntry(
                                    pinmapMap.at(padName),
                                    ioCellType
                                );

                                // Location string
                                if (entry.count("x") && entry.count("y")) {
                                    locName = stringf("X%sY%s", 
                                        entry.at("x").c_str(),
                                        entry.at("y").c_str()
                                    );
                                }

                                // Cell type
                                if (entry.count("type")) {
                                    cellType = entry.at("type");
                                }
                            }
                        }
                    }
                }
            }

            log("| %-10s | %-10s | %-8s | %-8s | %s\n",
                netName.c_str(),
                padName.c_str(),
                locName.c_str(),
                cellType.c_str(),
                cell->name.c_str()
            );

            // Annotate the cell by setting its parameters
            cell->setParam(RTLIL::escape_id("IO_PAD"),  padName);
            cell->setParam(RTLIL::escape_id("IO_LOC"),  locName);
            cell->setParam(RTLIL::escape_id("IO_TYPE"), cellType);
        }
    }

    PinmapParser::Entry choosePinmapEntry(
        const std::vector<PinmapParser::Entry>& a_Entries,
        const IoCellType& a_IoCellType)
    {
        // No preferred types, pick the first one
        if (a_IoCellType.preferredTypes.empty()) {
            return a_Entries[0];
        }

        // Loop over preferred types
        for (auto& type : a_IoCellType.preferredTypes) {
            
            // Find an entry for that type. If found then return it.
            for (auto& entry : a_Entries) {
                if (type == entry.at("type")) {
                    return entry;
                }
            }
        }

        // No preferred type was found, pick the first one.
        return a_Entries[0];
    }

} QuicklogicIob;

PRIVATE_NAMESPACE_END
