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

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

// ============================================================================

struct DspFF : public Pass {

    /// A structure identifying specific pin in a cell instance
    struct CellPin {
        RTLIL::Cell *cell;    /// Cell pointer (nullptr for top-level ports)
        RTLIL::IdString port; /// Port name
        int bit;              /// Bit index

        CellPin(RTLIL::Cell *_cell, const RTLIL::IdString &_port, int _bit = 0) : cell(_cell), port(_port), bit(_bit) {}

        CellPin(const CellPin &ref) = default;
        CellPin(CellPin &&ref) = default;

        unsigned int hash() const
        {
            unsigned int h = 0;
            if (cell != nullptr) {
                h = mkhash_add(h, cell->hash());
            }
            h = mkhash_add(h, port.hash());
            h = mkhash_add(h, bit);
            return h;
        }

        bool operator==(const CellPin &ref) const { return (cell == ref.cell) && (port == ref.port) && (bit == ref.bit); }

        std::string as_string() const
        {
            if (cell != nullptr) {
                return stringf("%s.%s[%d]", RTLIL::unescape_id(cell->name).c_str(), RTLIL::unescape_id(port).c_str(), bit);
            } else {
                return stringf("%s[%d]", RTLIL::unescape_id(port).c_str(), bit);
            }
        }
    };

    // ..........................................

    /// Describes a flip-flop type that can be integrated with a DSP cell
    struct FlopType {
        RTLIL::IdString name;

        /// A dict of port names indexed by their functions (like "clk", "rst")
        dict<RTLIL::IdString, RTLIL::IdString> ports;

        struct {
            /// A list of parameters that must match for all flip-flops
            std::vector<RTLIL::IdString> matching;
            /// A dict of parameter values that must match for a flip-flop
            dict<RTLIL::IdString, RTLIL::Const> required;
            /// A dict of parameters to be set in the DSP cell after integration
            dict<RTLIL::IdString, RTLIL::Const> set;
            /// A dict of parameters to be mapped to the DSP cell after integration
            dict<RTLIL::IdString, RTLIL::IdString> map;
        } params;
    };

    /// Describes a DSP cell port that has built-in register (flip-flops)
    struct PortType {
        RTLIL::IdString name;

        /// Range of port pins that have FFs (low to high, inclusive)
        std::pair<int, int> bits;
        /// A dict of associated cell ports indexed by their function (like "clk, "rst")
        /// along with the default value to connect when unused.
        dict<RTLIL::IdString, std::pair<RTLIL::IdString, RTLIL::Const>> assoc;
    };

    /// Describes a DSP register
    struct RegisterType {

        /// Control parameters
        struct {
            /// A dict of parameters to be set in the cell after integration
            dict<RTLIL::IdString, RTLIL::Const> set;
            /// A dict of parameters to be mapped to the cell after integration
            dict<RTLIL::IdString, RTLIL::IdString> map;
        } params;

        /// A list of ports to be connected to specific constants after flip-flop
        /// integration.
        dict<RTLIL::IdString, RTLIL::Const> connect;

        unsigned int hash() const
        {
            unsigned int h = 0;
            h = mkhash_add(h, params.set.hash());
            h = mkhash_add(h, params.map.hash());
            h = mkhash_add(h, connect.hash());
            return h;
        }

        bool operator==(const RegisterType &ref) const
        {
            return (params.set == ref.params.set) && (params.map == ref.params.map) && (connect == ref.connect);
        }
    };

    /// Describes a DSP cell type
    struct DspType {
        RTLIL::IdString name;
        dict<RegisterType, std::vector<PortType>> registers;
    };

    /// Describes a changes made to a DSP cell
    struct DspChanges {
        pool<RTLIL::IdString> params; // Modified params
        pool<RTLIL::IdString> conns;  // Altered connections (ports)
    };

    // ..........................................

    /// Describes unique flip-flop configuration that is exclusive.
    struct FlopData {
        RTLIL::IdString type;
        dict<RTLIL::IdString, RTLIL::SigBit> conns;
        struct {
            dict<RTLIL::IdString, RTLIL::Const> flop;
            dict<RTLIL::IdString, RTLIL::Const> dsp;
        } params;

        FlopData(const RTLIL::IdString &_type) : type(_type){};

        FlopData(const FlopData &ref) = default;
        FlopData(FlopData &&ref) = default;

        unsigned int hash() const
        {
            unsigned int h = 0;
            h = mkhash_add(h, type.hash());
            h = mkhash_add(h, conns.hash());
            h = mkhash_add(h, params.flop.hash());
            h = mkhash_add(h, params.dsp.hash());
            return h;
        }

        bool operator==(const FlopData &ref) const
        {
            return (type == ref.type) && (conns == ref.conns) && (params.flop == ref.params.flop) && (params.dsp == ref.params.dsp);
        }
    };

    // ..........................................

    /// Loads FF and DSP integration rules from a file
    void load_rules(const std::string &a_FileName)
    {

        // Parses a string and returns a vector of fields delimited by the
        // given character.
        auto getFields = [](const std::string &a_String, const char a_Delim = ' ', bool a_KeepEmpty = false) {
            std::vector<std::string> fields;
            std::stringstream ss(a_String);

            while (ss.good()) {
                std::string field;
                std::getline(ss, field, a_Delim);
                if (!field.empty() || a_KeepEmpty) {
                    fields.push_back(field);
                }
            }

            return fields;
        };

        // Parses a vector of strings like "<name>=<value>" starting from the
        // second one on the list
        auto parseNameValue = [&](const std::vector<std::string> &strs) {
            const std::regex expr("(\\S+)=(\\S+)");
            std::smatch match;

            std::vector<std::pair<std::string, std::string>> vec;

            for (size_t i = 1; i < strs.size(); ++i) {
                if (std::regex_match(strs[i], match, expr)) {
                    vec.push_back(std::make_pair(match[1], match[2]));
                } else {
                    log_error(" syntax error: '%s'\n", strs[i].c_str());
                }
            }

            return vec;
        };

        // Parses port name as "<name>[<hi>:<lo>]" or just "<name>"
        auto parsePortName = [&](const std::string &str) {
            const std::regex expr("^(.*)\\[([0-9]+):([0-9]+)\\]");
            std::smatch match;

            std::tuple<std::string, int, int> data;
            auto res = std::regex_match(str, match, expr);
            if (res) {
                data = std::make_tuple(std::string(match[1]), std::stoi(match[2]), std::stoi(match[3]));

                if ((std::get<2>(data) > std::get<1>(data)) || std::get<2>(data) < 0 || std::get<1>(data) < 0) {
                    log_error(" invalid port spec: '%s'\n", str.c_str());
                }
            } else {
                data = std::make_tuple(str, -1, -1);
            }

            return data;
        };

        std::ifstream file(a_FileName);
        std::string line;

        log("Loading rules from '%s'...\n", a_FileName.c_str());
        if (!file) {
            log_error(" Error opening file!\n");
        }

        // Parse each port as if it was associated with its own DSP register.
        // Group them each time a port definition is complete.
        PortType portType;
        RegisterType registerType;

        std::vector<DspType> dspTypes;
        std::vector<FlopType> flopTypes;

        std::vector<RTLIL::IdString> dspAliases;
        std::vector<std::string> portNames;

        std::vector<std::string> tok;

        // Parse the file
        while (1) {

            // Get line
            std::getline(file, line);
            if (!file) {
                break;
            }

            // Strip comment if any, skip empty lines
            size_t pos = line.find("#");
            if (pos != std::string::npos) {
                line = line.substr(0, pos);
            }
            if (line.find_first_not_of(" \r\n\t") == std::string::npos) {
                continue;
            }

            // Split the line
            const auto fields = getFields(line);
            log_assert(fields.size() >= 1);

            // DSP section
            if (fields[0] == "dsp") {
                if (fields.size() < 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (!tok.empty()) {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }
                tok.push_back(fields[0]);

                dspTypes.resize(dspTypes.size() + 1);
                dspTypes.back().name = RTLIL::escape_id(fields[1]);

                dspAliases.clear();
                for (size_t i = 2; i < fields.size(); ++i) {
                    dspAliases.push_back(RTLIL::escape_id(fields[i]));
                }
            } else if (fields[0] == "enddsp") {
                if (fields.size() != 1) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() != 1 || tok.back() != "dsp") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }
                tok.pop_back();

                const auto dspType = dspTypes.back();

                for (const auto &alias : dspAliases) {
                    dspTypes.push_back(dspType);
                    dspTypes.back().name = alias;
                }
            }

            // DSP port section
            else if (fields[0] == "port") {
                if (fields.size() < 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() != 1 || tok.back() != "dsp") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }
                tok.push_back(fields[0]);

                auto spec = parsePortName(fields[1]);

                portType = PortType();
                portType.name = RTLIL::escape_id(std::get<0>(spec));
                portType.bits = std::make_pair(std::get<2>(spec), std::get<1>(spec));
                portType.assoc.insert(std::make_pair(RTLIL::escape_id("clk"), std::make_pair(RTLIL::IdString(), RTLIL::Sx)));
                portType.assoc.insert(std::make_pair(RTLIL::escape_id("rst"), std::make_pair(RTLIL::IdString(), RTLIL::Sx)));
                portType.assoc.insert(std::make_pair(RTLIL::escape_id("ena"), std::make_pair(RTLIL::IdString(), RTLIL::Sx)));

                registerType = RegisterType();

                portNames.clear();
                for (size_t i = 2; i < fields.size(); ++i) {
                    portNames.push_back(fields[i]);
                }

            } else if (fields[0] == "endport") {
                if (fields.size() != 1) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() != 2 || tok.back() != "port") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }
                tok.pop_back();

                // Store the DSP port
                auto &dspType = dspTypes.back();
                dspType.registers[registerType].push_back(portType);

                // Store any extra DSP ports belonging to the same register
                for (const auto &name : portNames) {
                    auto spec = parsePortName(name);

                    PortType portTypeCopy = portType;
                    portTypeCopy.name = RTLIL::escape_id(std::get<0>(spec));
                    portTypeCopy.bits = std::make_pair(std::get<2>(spec), std::get<1>(spec));

                    dspType.registers[registerType].push_back(portTypeCopy);
                }
            }

            // Flip-flop type section
            else if (fields[0] == "ff") {
                if (fields.size() != 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (!tok.empty()) {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }
                tok.push_back(fields[0]);

                flopTypes.resize(flopTypes.size() + 1);
                flopTypes.back().name = RTLIL::escape_id(fields[1]);
                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("clk"), RTLIL::IdString()));
                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("rst"), RTLIL::IdString()));
                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("ena"), RTLIL::IdString()));
                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("d"), RTLIL::IdString()));
                flopTypes.back().ports.insert(std::make_pair(RTLIL::escape_id("q"), RTLIL::IdString()));
            } else if (fields[0] == "endff") {
                if (fields.size() != 1) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() != 1 || tok.back() != "ff") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }
                tok.pop_back();
            }

            // Signals
            else if (fields[0] == "clk") {
                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                // Associated clock
                if (tok.back() == "port") {
                    if (fields.size() != 3) {
                        log_error(" syntax error: '%s'\n", line.c_str());
                    }
                    portType.assoc[RTLIL::escape_id("clk")] = std::make_pair(RTLIL::escape_id(fields[1]), RTLIL::Const::from_string(fields[2]));
                } else if (tok.back() == "ff") {
                    if (fields.size() != 2) {
                        log_error(" syntax error: '%s'\n", line.c_str());
                    }
                    flopTypes.back().ports[RTLIL::escape_id("clk")] = RTLIL::escape_id(fields[1]);
                }
            } else if (fields[0] == "rst") {
                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                // Associated reset
                if (tok.back() == "port") {
                    if (fields.size() != 3) {
                        log_error(" syntax error: '%s'\n", line.c_str());
                    }
                    portType.assoc[RTLIL::escape_id("rst")] = std::make_pair(RTLIL::escape_id(fields[1]), RTLIL::Const::from_string(fields[2]));
                } else if (tok.back() == "ff") {
                    if (fields.size() != 2) {
                        log_error(" syntax error: '%s'\n", line.c_str());
                    }
                    flopTypes.back().ports[RTLIL::escape_id("rst")] = RTLIL::escape_id(fields[1]);
                }
            } else if (fields[0] == "ena") {
                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                // Associated enable
                if (tok.back() == "port") {
                    if (fields.size() != 3) {
                        log_error(" syntax error: '%s'\n", line.c_str());
                    }
                    portType.assoc[RTLIL::escape_id("ena")] = std::make_pair(RTLIL::escape_id(fields[1]), RTLIL::Const::from_string(fields[2]));
                } else if (tok.back() == "ff") {
                    if (fields.size() != 2) {
                        log_error(" syntax error: '%s'\n", line.c_str());
                    }
                    flopTypes.back().ports[RTLIL::escape_id("ena")] = RTLIL::escape_id(fields[1]);
                }
            }

            else if (fields[0] == "d") {
                if (fields.size() != 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() == 0 || tok.back() != "ff") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                flopTypes.back().ports[RTLIL::escape_id("d")] = RTLIL::escape_id(fields[1]);
            } else if (fields[0] == "q") {
                if (fields.size() != 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() == 0 || tok.back() != "ff") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                flopTypes.back().ports[RTLIL::escape_id("q")] = RTLIL::escape_id(fields[1]);
            }

            // Parameters that must be set to certain values
            else if (fields[0] == "require") {
                if (fields.size() < 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() == 0 || tok.back() != "ff") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                const auto vec = parseNameValue(fields);
                for (const auto &it : vec) {
                    flopTypes.back().params.required.insert(std::make_pair(RTLIL::escape_id(it.first), RTLIL::Const(it.second)));
                }
            }
            // Parameters that has to match for a flip-flop
            else if (fields[0] == "match") {
                if (fields.size() < 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() == 0 || tok.back() != "ff") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                for (size_t i = 1; i < fields.size(); ++i) {
                    flopTypes.back().params.matching.push_back(RTLIL::escape_id(fields[i]));
                }
            }
            // Parameters to set
            else if (fields[0] == "set") {
                if (fields.size() < 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                const auto vec = parseNameValue(fields);
                dict<RTLIL::IdString, RTLIL::Const> set;
                for (const auto &it : vec) {
                    set.insert(std::make_pair(RTLIL::escape_id(it.first), RTLIL::Const(it.second)));
                }

                if (tok.back() == "port") {
                    registerType.params.set.swap(set);
                } else if (tok.back() == "ff") {
                    flopTypes.back().params.set.swap(set);
                }
            }
            // Parameters to copy / map
            else if (fields[0] == "map") {
                if (fields.size() < 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() == 0 || (tok.back() != "port" && tok.back() != "ff")) {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                const auto vec = parseNameValue(fields);
                dict<RTLIL::IdString, RTLIL::IdString> map;
                for (const auto &it : vec) {
                    map.insert(std::make_pair(RTLIL::escape_id(it.first), RTLIL::escape_id(it.second)));
                }

                if (tok.back() == "port") {
                    registerType.params.map.swap(map);
                } else if (tok.back() == "ff") {
                    flopTypes.back().params.map.swap(map);
                }
            }
            // Connections to make
            else if (fields[0] == "con") {
                if (fields.size() < 2) {
                    log_error(" syntax error: '%s'\n", line.c_str());
                }
                if (tok.size() == 0 || tok.back() != "port") {
                    log_error(" unexpected keyword '%s'\n", fields[0].c_str());
                }

                const auto vec = parseNameValue(fields);
                for (const auto &it : vec) {
                    registerType.connect.insert(std::make_pair(RTLIL::escape_id(it.first), RTLIL::Const(it.second)));
                }
            }

            else {
                log_error(" unexpected keyword '%s'\n", fields[0].c_str());
            }
        }

        // Convert lists to maps
        for (const auto &it : dspTypes) {
            if (m_DspTypes.count(it.name)) {
                log_error(" duplicated rule for DSP '%s'\n", it.name.c_str());
            }
            m_DspTypes.insert(std::make_pair(it.name, it));
        }
        for (const auto &it : flopTypes) {
            if (m_FlopTypes.count(it.name)) {
                log_error(" duplicated rule for flip-flop '%s'\n", it.name.c_str());
            }
            m_FlopTypes.insert(std::make_pair(it.name, it));
        }
    }

    void dump_rules()
    {

        // Dump DSP types
        log("DSP types:\n");
        for (const auto &it1 : m_DspTypes) {
            const auto &dsp = it1.second;
            log(" %s\n", dsp.name.c_str());

            for (const auto &it2 : dsp.registers) {
                const auto &reg = it2.first;
                const auto &ports = it2.second;
                log(" ports:\n");
                for (const auto &port : ports) {

                    std::string range;
                    if (port.bits.first != -1 && port.bits.second != -1) {
                        range = stringf("[%d:%d]", port.bits.second, port.bits.first);
                    }

                    log("  %s.%s%s\n", dsp.name.c_str(), port.name.c_str(), range.c_str());

                    for (const auto &it : port.assoc) {
                        log("   %.3s: %s\n", it.first.c_str(), !it.second.first.empty() ? it.second.first.c_str() : "<none>");
                    }

                    if (!reg.params.set.empty()) {
                        log("   set params:\n");
                        for (const auto &it : reg.params.set) {
                            log("    %s=%s\n", it.first.c_str(), it.second.decode_string().c_str());
                        }
                    }
                    if (!reg.params.map.empty()) {
                        log("   map params:\n");
                        for (const auto &it : reg.params.map) {
                            log("    %s=%s\n", it.first.c_str(), it.second.c_str());
                        }
                    }
                    if (!reg.connect.empty()) {
                        log("   connect ports:\n");
                        for (const auto &it : reg.connect) {
                            log("    %s.%s=%s\n", dsp.name.c_str(), it.first.c_str(), it.second.as_string().c_str());
                        }
                    }
                }
            }
        }

        // Dump flop types
        log("Flip-flop types:\n");
        for (const auto &it : m_FlopTypes) {
            const auto &ff = it.second;
            log(" %s\n", ff.name.c_str());

            for (const auto &it : ff.ports) {
                log("  %.3s: %s\n", it.first.c_str(), !it.second.empty() ? it.second.c_str() : "<none>");
            }

            if (!ff.params.required.empty()) {
                log("  required params:\n");
                for (const auto &it : ff.params.required) {
                    log("   %s=%s\n", it.first.c_str(), it.second.decode_string().c_str());
                }
            }
            if (!ff.params.matching.empty()) {
                log("  params that must match:\n");
                for (const auto &it : ff.params.matching) {
                    log("   %s\n", it.c_str());
                }
            }
            if (!ff.params.set.empty()) {
                log("  set params:\n");
                for (const auto &it : ff.params.set) {
                    log("   %s=%s\n", it.first.c_str(), it.second.decode_string().c_str());
                }
            }
            if (!ff.params.map.empty()) {
                log("  map params:\n");
                for (const auto &it : ff.params.map) {
                    log("   %s=%s\n", it.first.c_str(), it.second.c_str());
                }
            }
        }
    }

    // ..........................................

    /// Temporary SigBit to SigBit helper map.
    SigMap m_SigMap;
    //    /// Net map
    //    dict<RTLIL::SigBit, RTLIL::SigBit> m_NetMap;
    /// Cells to be removed (per module!)
    pool<RTLIL::Cell *> m_CellsToRemove;
    /// DSP cells that got changed
    dict<RTLIL::Cell *, DspChanges> m_DspChanges;

    /// DSP types
    dict<RTLIL::IdString, DspType> m_DspTypes;
    /// Flip-flop types
    dict<RTLIL::IdString, FlopType> m_FlopTypes;

    // ..........................................

    DspFF() : Pass("dsp_ff", "Integrates flip-flop into DSP blocks") {}

    void help() override
    {
        log("\n");
        log("    dsp_ff -rules <rules.txt> [selection]\n");
        log("\n");
        log("Integrates flip-flops with DSP blocks and enables their internal registers.\n");
        log("\n");
        log("The pass loads a set of rules from the file given with the '-rules' parameter.\n");
        log("The rules define what ports of a DSP module have internal registers and what\n");
        log("has to be done to enable them. They also define compatible flip-flop cell\n");
        log("types.\n");
        log("\n");
        log("The format of the rules file is the following:\n");
        log("\n");
        log("  # This is a comment\n");
        log("\n");
        log("  dsp <dsp_type> [<dsp_type> ...]\n");
        log("    port <dsp_port> [<dsp_port> ...]\n");
        log("      clk <associated clk> <default>\n");
        log("     [rst <associated reset>] <default>\n");
        log("     [ena <associated enable>] <default>\n");
        log("\n");
        log("     [set <param>=<value> [<param>=<value> ...]]\n");
        log("     [map <dsp_param>=<ff_param> [<dsp_param>=<ff_param> ...]]\n");
        log("     [con <port>=<const> [<port>=<const> ...]]\n");
        log("    endport\n");
        log("  enddsp\n");
        log("\n");
        log("  ff <ff_type>\n");
        log("    clk <clock input>\n");
        log("   [rst <reset input>]\n");
        log("   [ena <enable input>]\n");
        log("    d   <data input>\n");
        log("    q   <data output>\n");
        log("\n");
        log("    require <param>=<value> [<param>=<value> ...]\n");
        log("    match   <param> [<param> ...]\n");
        log("\n");
        log("    set <param>=<value> [<param>=<value> ...]\n");
        log("    map <dsp_param>=<ff_param> [<dsp_param>=<ff_param> ...]\n");
        log("  endff\n");
        log("\n");
        log("Each 'dsp' section defines a DSP cell type (can apply to multiple types).\n");
        log("Within it each 'port' section defining a data port with internal register.\n");
        log("There can be multiple port names given if they belong to the same control register.\n");
        log("The port can be specified as a whole (eg. 'DATA') or as a subset of the whole\n");
        log("(eg. 'DATA[7:0]').\n");
        log("\n");
        log("Statemenst 'clk', 'rst' and 'ena' define names of clock, reset and enable\n");
        log("ports associated with the data port along with default constant values to\n");
        log("connect them to when a given port has no counterpart in the flip-flop bein\n");
        log("integrated.\n");
        log("\n");
        log("The 'set' statement tells how to set control parameter(s) of the DSP that\n");
        log("enable the input register on the port. The 'map' statement defines how to\n");
        log("map parameter(s) of the flip-flip being integrated to the DSP. Finally the\n");
        log("'con' statement informs how to connected control port(s) of the DSP to enable\n");
        log("the register.\n");
        log("\n");
        log("Each 'ff' section defines a flip-flop type that can be integrated into a DSP\n");
        log("cell. Inside this section 'clk', 'rst', 'ena', 'd' and 'q' define names of\n");
        log("clock, reset, enable, data in and data out ports of the flip-flop respectively.\n");
        log("\n");
        log("The 'require' statement defines parameter(s) that must have specific value\n");
        log("for a flip-flop to be considered for integration. The 'match' statement\n");
        log("lists names of flip-flop parameters that must match on all flip-flops connected\n");
        log("to a single DSP data port.\n");
        log("\n");
        log("The 'set' and 'map' statements serve the same function as in the DSP port\n");
        log("section but here they may differ depending on the flip-flop type being\n");
        log("integrated.\n");
    }

    void execute(std::vector<std::string> a_Args, RTLIL::Design *a_Design) override
    {
        log_header(a_Design, "Executing DSP_FF pass.\n");

        std::string rulesFile;

        // Parse args
        size_t argidx;
        for (argidx = 1; argidx < a_Args.size(); argidx++) {
            if (a_Args[argidx] == "-rules" && (argidx + 1) < a_Args.size()) {
                rulesFile = a_Args[++argidx];
                continue;
            }

            break;
        }
        extra_args(a_Args, argidx, a_Design);

        // Check args
        if (rulesFile.empty()) {
            log_cmd_error("No rules file specified!");
        }

        // Reset state
        m_CellsToRemove.clear();
        m_DspChanges.clear();
        m_DspTypes.clear();
        m_FlopTypes.clear();

        // Load rules
        rewrite_filename(rulesFile);
        load_rules(rulesFile);
        if (log_force_debug) {
            dump_rules();
        }

        // Process modules
        for (auto module : a_Design->selected_modules()) {

            // Setup the SigMap
            m_SigMap.clear();
            m_SigMap.set(module);

            //            // Build the net map
            //            buildNetMap(module);

            // Look for DSP cells
            for (auto cell : module->cells()) {

                // Not a DSP
                if (!m_DspTypes.count(cell->type)) {
                    continue;
                }

                // Process all registers
                auto &dspType = m_DspTypes.at(cell->type);
                for (auto &rule : dspType.registers) {
                    processRegister(cell, rule.first, rule.second);
                }
            }

            // Remove cells
            for (const auto &cell : m_CellsToRemove) {
                module->remove(cell);
            }
            m_CellsToRemove.clear();
        }

        // Clear maps
        m_SigMap.clear();
    }

    // ..........................................

    //    void buildNetMap (RTLIL::Module* a_Module) {
    //        // TODO:
    //    }

    bool checkFlop(RTLIL::Cell *a_Cell)
    {
        const auto &flopType = m_FlopTypes.at(a_Cell->type);
        bool isOk = true;

        log_debug("checking connected flip-flop '%s' of type '%s'... ", a_Cell->name.c_str(), a_Cell->type.c_str());

        // Must not have the "keep" attribute
        if (a_Cell->has_keep_attr()) {
            log_debug("\n   the 'keep' attribute is set");
            isOk = false;
        }

        // Check if required parameters are set as they should be
        for (const auto &it : flopType.params.required) {
            const auto curr = a_Cell->getParam(it.first);
            if (curr != it.second) {
                log_debug("\n   param '%s' mismatch ('%s' instead of '%s')", it.first.c_str(), curr.decode_string().c_str(),
                          it.second.decode_string().c_str());
                isOk = false;
            }
        }

        if (isOk) {
            log_debug("Ok\n");
        } else {
            log_debug("\n");
        }
        return isOk;
    }

    bool checkFlopDataAgainstDspRegister(const FlopData &a_FlopData, RTLIL::Cell *a_Cell, const RegisterType &a_Register,
                                         const std::vector<PortType> &a_Ports)
    {
        const auto &flopType = m_FlopTypes.at(a_FlopData.type);
        const auto &changes = m_DspChanges[a_Cell];
        bool isOk = true;

        log_debug("  checking connected flip-flop settings against the DSP register... ");

        // Check control signal connections
        for (const auto &port : a_Ports) {
            for (const auto &it : port.assoc) {
                const auto &key = it.first;
                const auto &port = it.second.first;

                SigBit conn(RTLIL::Sx);
                if (!port.empty() && a_Cell->hasPort(port)) {
                    auto sigspec = a_Cell->getPort(port);
                    auto sigbits = sigspec.bits();
                    log_assert(sigbits.size() <= 1);
                    if (!sigbits.empty()) {
                        conn = m_SigMap(sigbits[0]);
                    }
                }

                if (conn.is_wire() || (!conn.is_wire() && conn.data != RTLIL::Sx)) {
                    if (conn != a_FlopData.conns.at(key)) {
                        log_debug("\n   connection to port '%s' mismatch", port.c_str());
                        isOk = false;
                    }
                }
            }
        }

        auto checkParam = [&](const RTLIL::IdString &name, const RTLIL::Const &curr, const RTLIL::Const &next) {
            if (curr != next && changes.params.count(name)) {
                log_debug("\n   the param '%s' mismatch ('%s' instead of '%s')", name.c_str(), curr.decode_string().c_str(),
                          next.decode_string().c_str());
                isOk = false;
                return false;
            }
            return true;
        };

        // Check parameters to be mapped (by the port rule)
        for (const auto &it : a_Register.params.map) {
            if (a_Cell->hasParam(it.first) && a_FlopData.params.dsp.count(it.second)) {
                const auto curr = a_Cell->getParam(it.first);
                const auto flop = a_FlopData.params.dsp.at(it.second);
                checkParam(it.first, curr, flop);
            }
        }

        // Check parameters to be set (by the port rule)
        for (const auto &it : a_Register.params.set) {
            if (a_Cell->hasParam(it.first)) {
                const auto curr = a_Cell->getParam(it.first);
                checkParam(it.first, curr, it.second);
            }
        }

        // Check parameters to be mapped (by the flip-flop rule)
        for (const auto &it : flopType.params.map) {
            if (a_Cell->hasParam(it.first) && a_FlopData.params.dsp.count(it.second)) {
                const auto curr = a_Cell->getParam(it.first);
                const auto flop = a_FlopData.params.dsp.at(it.second);
                checkParam(it.first, curr, flop);
            }
        }

        // Check parameters to be set (by the flip-flop rule)
        for (const auto &it : flopType.params.set) {
            if (a_Cell->hasParam(it.first)) {
                const auto curr = a_Cell->getParam(it.first);
                checkParam(it.first, curr, it.second);
            }
        }

        if (isOk) {
            log_debug("Ok\n");
        } else {
            log_debug("\n");
        }
        return isOk;
    }

    /// Returns a string with either wire name or constant value for a SigBit
    static std::string sigBitName(const RTLIL::SigBit &a_SigBit)
    {
        if (a_SigBit.is_wire()) {
            RTLIL::Wire *w = a_SigBit.wire;
            return RTLIL::unescape_id(w->name);
        } else {
            switch (a_SigBit.data) {
            case RTLIL::State::S0:
                return "1'b0";
            case RTLIL::State::S1:
                return "1'b1";
            case RTLIL::State::Sx:
                return "1'bx";
            case RTLIL::State::Sz:
                return "1'bz";
            case RTLIL::State::Sa:
                return "-";
            case RTLIL::State::Sm:
                return "m";
            }
            return "?";
        }
    }

    // ..........................................

    void processRegister(RTLIL::Cell *a_Cell, const RegisterType &a_Register, const std::vector<PortType> &a_Ports)
    {

        // The cell register control parameter(s) must not be set
        for (const auto &it : a_Register.params.set) {
            const auto curr = a_Cell->getParam(it.first);
            if (curr == it.second) {
                log_debug(" the param '%s' is already set to '%s'\n", it.first.c_str(), it.second.decode_string().c_str());
                return;
            }
        }

        pool<FlopData> groups;
        dict<RTLIL::IdString, std::vector<RTLIL::Cell *>> flops;

        // Process ports
        bool flopsOk = true;
        for (const auto &port : a_Ports) {
            log_debug(" attempting flip-flop integration for %s.%s of %s\n", a_Cell->type.c_str(), port.name.c_str(), a_Cell->name.c_str());

            if (!a_Cell->hasPort(port.name)) {
                log_debug("  port unconnected.\n");
                continue;
            }
            log_assert(a_Cell->output(port.name) || a_Cell->input(port.name));

            // Get port connections
            auto sigspec = a_Cell->getPort(port.name);
            auto sigbits = sigspec.bits();

            flops[port.name] = std::vector<RTLIL::Cell *>(sigbits.size(), nullptr);
            for (size_t i = 0; i < sigbits.size(); ++i) {
                auto sigbit = sigbits[i];

                log_debug("  %2zu. ", i);

                // Port connected to a const.
                if (!sigbit.wire) {
                    log_debug("constant\n");
                    continue;
                }

                // Skip bits out of the specified range
                if ((port.bits.first >= 0 && (int)i < port.bits.first) || (port.bits.second >= 0 && (int)i > port.bits.second)) {
                    log_debug("(excluded)\n");
                    continue;
                }

                pool<CellPin> others;

                // Get sinks(s), discard the port completely if more than one sink
                // is found.
                if (a_Cell->output(port.name)) {
                    others = getSinks(CellPin(a_Cell, port.name, i));
                    if (others.size() > 1) {
                        log_debug("multiple sinks\n");
                        flopsOk = false;
                        continue;
                    }
                }
                // Get driver. Discard if the driver drives something else too
                // TODO: This is slow - we are first looking for a driver and then
                // for all its sinks.
                else if (a_Cell->input(port.name)) {
                    auto driver = getDriver(CellPin(a_Cell, port.name, i));
                    if (driver.cell != nullptr) {
                        auto sinks = getSinks(driver);
                        if (sinks.size() > 1) {
                            log_debug("multiple sinks\n");
                            flopsOk = false;
                            continue;
                        }
                    }
                    others.insert(driver);
                }

                // No others - unconnected
                if (others.empty()) {
                    log_debug("unconnected\n");
                    continue;
                }

                // Get the sink, check if this is a flip-flop
                auto &other = *others.begin();
                auto *flop = other.cell;

                if (flop == nullptr) {
                    if (!other.port.empty()) {
                        log_debug("connection reaches module edge\n");
                        flopsOk = false;
                    }
                    log_debug("unconnected\n");
                    continue;
                }

                if (!m_FlopTypes.count(flop->type)) {
                    log_debug("non-flip-flop connected\n");
                    flopsOk = false;
                    continue;
                }

                // Check if the connection goes to the data input/output port
                const auto &flopType = m_FlopTypes.at(flop->type);
                RTLIL::IdString flopPort;
                if (a_Cell->output(port.name)) {
                    flopPort = flopType.ports.at(RTLIL::escape_id("d"));
                } else if (a_Cell->input(port.name)) {
                    flopPort = flopType.ports.at(RTLIL::escape_id("q"));
                }

                if (flopPort != other.port) {
                    log_debug("connection to non-data port of a flip-flip");
                    flopsOk = false;
                    continue;
                }

                // Check the flip-flop configuration
                if (!checkFlop(flop)) {
                    flopsOk = false;
                    continue;
                }

                // Get parameters to be mapped to the DSP according to the port
                // rule.
                dict<RTLIL::IdString, RTLIL::Const> mappedParams;
                for (const auto &it : a_Register.params.map) {
                    if (flop->hasParam(it.second)) {
                        const auto &value = flop->getParam(it.second);
                        mappedParams.insert(std::make_pair(it.first, value));
                    }
                }

                // Store the flop and its data
                groups.insert(getFlopData(flop, mappedParams));
                flops[port.name][i] = flop;
            }
        }

        // Cannot integrate for various reasons
        if (!flopsOk) {
            log_debug(" cannot use the DSP register\n");
            return;
        }

        // No matching flip-flop groups
        if (groups.empty()) {
            log_debug(" no matching flip-flops found\n");
            return;
        }

        // Do not allow more than a single group
        if (groups.size() != 1) {
            log_debug(" %zu flip-flop groups, only a single one allowed\n", groups.size());
            return;
        }

        // Validate the flip flop data agains the DSP cell
        const auto &flopData = *groups.begin();
        if (!checkFlopDataAgainstDspRegister(flopData, a_Cell, a_Register, a_Ports)) {
            log_debug(" flip-flops vs. DSP check failed\n");
            return;
        }

        // Log connections
        for (const auto &port : a_Ports) {

            if (!flops.count(port.name)) {
                continue;
            }

            log(" %s %s.%s\n", a_Cell->type.c_str(), a_Cell->name.c_str(), port.name.c_str());

            const auto &conns = flops.at(port.name);
            for (size_t i = 0; i < conns.size(); ++i) {
                if (conns[i] != nullptr) {
                    log_debug("  %2zu. %s %s\n", i, conns[i]->type.c_str(), conns[i]->name.c_str());
                } else if ((port.bits.first >= 0 && (int)i < port.bits.first) || (port.bits.second >= 0 && (int)i > port.bits.second)) {
                    log_debug("  %2zu. (excluded)\n", i);
                } else {
                    log_debug("  %2zu. None\n", i);
                }
            }
        }

        // Reconnect data signals, mark the flip-flop for removal
        const auto &flopType = m_FlopTypes.at(flopData.type);
        for (const auto &port : a_Ports) {

            if (!flops.count(port.name)) {
                continue;
            }

            const auto &conns = flops.at(port.name);
            auto sigspec = a_Cell->getPort(port.name);
            auto sigbits = sigspec.bits();

            for (size_t i = 0; i < conns.size(); ++i) {

                auto *flop = conns[i];
                if (flop == nullptr) {
                    continue;
                }

                RTLIL::IdString flopPort;
                if (a_Cell->output(port.name)) {
                    flopPort = flopType.ports.at(RTLIL::escape_id("q"));
                } else if (a_Cell->input(port.name)) {
                    flopPort = flopType.ports.at(RTLIL::escape_id("d"));
                }

                if (!flop->hasPort(flopPort)) {
                    log_error("cell '%s' does not have port '%s'!\n", flop->type.c_str(), flopPort.c_str());
                }

                sigbits[i] = SigBit(RTLIL::Sx);
                auto sigspec = flop->getPort(flopPort);
                log_assert(sigspec.bits().size() <= 1);
                if (sigspec.bits().size() == 1) {
                    sigbits[i] = sigspec.bits()[0];
                }

                m_CellsToRemove.insert(flop);
            }

            a_Cell->setPort(port.name, RTLIL::SigSpec(sigbits));
        }

        // Reconnect (map) control signals. Connect the default value if
        // a particular signal is not present in the flip-flop.
        for (const auto &port : a_Ports) {
            for (const auto &it : port.assoc) {
                const auto &key = it.first;
                const auto &port = it.second.first;

                auto conn = RTLIL::SigBit(RTLIL::SigChunk(it.second.second));
                if (flopData.conns.count(key)) {
                    conn = flopData.conns.at(key);
                }

                log_debug(" connecting %s.%s to %s\n", a_Cell->type.c_str(), port.c_str(), sigBitName(conn).c_str());
                a_Cell->setPort(port, conn);
                m_DspChanges[a_Cell].conns.insert(port);
            }
        }

        // Connect control signals according to the register rule
        for (const auto &it : a_Register.connect) {
            log_debug(" connecting %s.%s to %s\n", a_Cell->type.c_str(), it.first.c_str(), it.second.as_string().c_str());
            a_Cell->setPort(it.first, it.second);
            m_DspChanges[a_Cell].conns.insert(it.first);
        }

        // Map parameters (register rule)
        for (const auto &it : a_Register.params.map) {
            if (flopData.params.dsp.count(it.second)) {
                const auto &param = flopData.params.dsp.at(it.second);
                log_debug(" setting param '%s' to '%s'\n", it.first.c_str(), param.decode_string().c_str());
                a_Cell->setParam(it.first, param);
                m_DspChanges[a_Cell].params.insert(it.first);
            }
        }

        // Map parameters (flip-flop rule)
        for (const auto &it : flopType.params.map) {
            if (flopData.params.dsp.count(it.second)) {
                const auto &param = flopData.params.dsp.at(it.second);
                log_debug(" setting param '%s' to '%s'\n", it.first.c_str(), param.decode_string().c_str());
                a_Cell->setParam(it.first, param);
                m_DspChanges[a_Cell].params.insert(it.first);
            }
        }

        // Set parameters (port rule)
        for (const auto &it : a_Register.params.set) {
            log_debug(" setting param '%s' to '%s'\n", it.first.c_str(), it.second.decode_string().c_str());
            a_Cell->setParam(it.first, it.second);
            m_DspChanges[a_Cell].params.insert(it.first);
        }

        // Set parameters (flip-flop rule)
        for (const auto &it : flopType.params.set) {
            log_debug(" setting param '%s' to '%s'\n", it.first.c_str(), it.second.decode_string().c_str());
            a_Cell->setParam(it.first, it.second);
            m_DspChanges[a_Cell].params.insert(it.first);
        }
    }

    // ..........................................

    /// Collects flip-flop connectivity data and parameters which defines the
    /// group it belongs to.
    FlopData getFlopData(RTLIL::Cell *a_Cell, const dict<RTLIL::IdString, RTLIL::Const> &a_ExtraParams)
    {
        FlopData data(a_Cell->type);

        log_assert(m_FlopTypes.count(a_Cell->type) != 0);
        const auto &flopType = m_FlopTypes.at(a_Cell->type);

        // Gather connections to control ports
        for (const auto &it : flopType.ports) {

            // Skip "D" and "Q" as they connection will always differ.
            if (it.first == RTLIL::escape_id("d") || it.first == RTLIL::escape_id("q")) {
                continue;
            }

            if (!it.second.empty() && a_Cell->hasPort(it.second)) {
                auto sigspec = a_Cell->getPort(it.second);
                auto sigbits = sigspec.bits();
                log_assert(sigbits.size() <= 1);
                if (!sigbits.empty()) {
                    data.conns[it.first] = m_SigMap(sigbits[0]);
                }
            }
        }

        // Gather flip-flop parameters that need to match
        for (const auto &it : flopType.params.matching) {
            log_assert(a_Cell->hasParam(it));
            data.params.flop.insert(std::make_pair(it, a_Cell->getParam(it)));
        }

        // Gather flip-flop parameters to be mapped to the DSP as well
        for (const auto &it : flopType.params.map) {
            log_assert(a_Cell->hasParam(it.second));
            data.params.flop.insert(std::make_pair(it.second, a_Cell->getParam(it.second)));
        }

        // Gather DSP parameters and their values to be set to too
        for (const auto &it : flopType.params.set) {
            data.params.dsp.insert(it);
        }

        // Append extra DSP parameters
        for (const auto &it : a_ExtraParams) {
            data.params.dsp.insert(it);
        }

        return data;
    }

    /// Retrieves a list of sinks driven by the given cell pin.
    /// TODO: This is slow, need to make a lookup for that.
    pool<CellPin> getSinks(const CellPin &a_Driver)
    {

        auto module = a_Driver.cell->module;
        pool<CellPin> sinks;

        // The driver has to be an output pin
        log_assert(a_Driver.cell->output(a_Driver.port));

        // Get the driver sigbit
        auto driverSigspec = a_Driver.cell->getPort(a_Driver.port);
        auto driverSigbit = m_SigMap(driverSigspec.bits().at(a_Driver.bit));

        // Look for connected sinks
        for (auto cell : module->cells()) {

            if (m_CellsToRemove.count(cell)) {
                continue;
            }

            for (auto conn : cell->connections()) {
                auto port = conn.first;
                auto sigspec = conn.second;

                // Consider only sinks (inputs)
                if (!cell->input(port)) {
                    continue;
                }

                // Check all sigbits
                auto sigbits = sigspec.bits();
                for (size_t bit = 0; bit < sigbits.size(); ++bit) {

                    auto sigbit = sigbits[bit];
                    if (!sigbit.wire) {
                        continue;
                    }

                    // Got a sink pin of another cell
                    sigbit = m_SigMap(sigbit);
                    if (sigbit == driverSigbit) {
                        sinks.insert(CellPin(cell, port, bit));
                    }
                }
            }
        }

        // Look for connected top-level output ports
        for (auto conn : module->connections()) {
            auto dst = conn.first;
            auto src = conn.second;

            auto sigbits = dst.bits();
            for (size_t bit = 0; bit < sigbits.size(); ++bit) {

                auto sigbit = sigbits[bit];
                if (!sigbit.wire) {
                    continue;
                }

                if (!sigbit.wire->port_output) {
                    continue;
                }

                sigbit = m_SigMap(sigbit);
                if (sigbit == driverSigbit) {
                    sinks.insert(CellPin(nullptr, sigbit.wire->name, bit));
                }
            }
        }

        return sinks;
    }

    /// Finds a driver for the given cell pin
    /// TODO: This is slow, need to make a lookup for that.
    CellPin getDriver(const CellPin &a_Sink)
    {
        auto module = a_Sink.cell->module;

        // The sink has to be an input pin
        log_assert(a_Sink.cell->input(a_Sink.port));

        // Get the sink sigbit
        auto sinkSigspec = a_Sink.cell->getPort(a_Sink.port);
        auto sinkSigbit = m_SigMap(sinkSigspec.bits().at(a_Sink.bit));

        // Look for connected top-level input ports
        for (auto conn : module->connections()) {
            auto dst = conn.first;
            auto src = conn.second;

            auto sigbits = dst.bits();
            for (size_t bit = 0; bit < sigbits.size(); ++bit) {

                auto sigbit = sigbits[bit];
                if (!sigbit.wire) {
                    continue;
                }

                if (!sigbit.wire->port_input) {
                    continue;
                }

                sigbit = m_SigMap(sigbit);
                if (sigbit == sinkSigbit) {
                    CellPin(nullptr, sigbit.wire->name, bit);
                }
            }
        }

        // Look for the driver among cells
        for (auto cell : module->cells()) {

            if (m_CellsToRemove.count(cell)) {
                continue;
            }

            for (auto conn : cell->connections()) {
                auto port = conn.first;
                auto sigspec = conn.second;

                // Consider only outputs
                if (!cell->output(port)) {
                    continue;
                }

                // Check all sigbits
                auto sigbits = sigspec.bits();
                for (size_t bit = 0; bit < sigbits.size(); ++bit) {

                    auto sigbit = sigbits[bit];
                    if (!sigbit.wire) {
                        continue;
                    }

                    // Got a driver pin of another cell
                    sigbit = m_SigMap(sigbit);
                    if (sigbit == sinkSigbit) {
                        return CellPin(cell, port, bit);
                    }
                }
            }
        }

        // No driver found. FIXME: Implement a cleaner way of indicating that
        return CellPin(nullptr, RTLIL::IdString(), -1);
    }

} DspFF;

PRIVATE_NAMESPACE_END
