#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> 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();

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

                auto& dspType = dspTypes.back();
                dspType.registers[registerType].push_back(portType);
            }

            // 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>\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("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());
            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];
                if (!sigbit.wire) {
                    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)) {
                    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 found\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 found\n");
                            flopsOk = false;
                            continue;
                        }
                    }
                    others.insert(driver);
                }

                // No others - unconnected
                if (others.empty()) {
                    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("  port connection reaches outside of the module\n");
                        flopsOk = false;
                    }
                    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;
        }

        // Debug log
        for (const auto& port : a_Ports) {
            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) {

            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
