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

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

    /// Connection map
    struct ConnMap {

        /// Maps source SigBit to all sinks it drives CellPin.
        dict<RTLIL::SigBit, std::vector<CellPin>> sinks;
        /// Maps source SigBit to its driver CellPin
        dict<RTLIL::SigBit, CellPin> drivers;

        /// Builds the map
        void build(RTLIL::Module *module, const SigMap &sigmap)
        {
            clear();

            // Scan cell ports
            for (auto *cell : module->cells()) {
                for (const auto &it : cell->connections_) {
                    const auto &port = it.first;
                    const auto &sigbits = it.second.bits();
                    for (size_t i = 0; i < sigbits.size(); ++i) {
                        auto sigbit = sigmap(sigbits[i]);

                        // This is an input port (sink))
                        if (cell->input(port)) {
                            auto &vec = sinks[sigbit];
                            vec.push_back(CellPin(cell, port, i));
                        }
                        // This is a source
                        if (cell->output(port)) {
                            drivers.insert(std::make_pair(sigbit, CellPin(cell, port, i)));
                        }
                    }
                }
            }

            // Scan top-level ports
            for (auto &it : module->wires_) {
                auto *wire = it.second;

                if (!wire->port_input && !wire->port_output) {
                    continue;
                }

                RTLIL::SigSpec sigspec(wire, wire->start_offset, wire->width);
                const auto &sigbits = sigspec.bits();
                for (size_t i = 0; i < sigbits.size(); ++i) {
                    auto sigbit = sigbits[i];
                    if (!sigbit.wire) {
                        continue;
                    }

                    // Output port (sink)
                    if (sigbit.wire->port_output) {
                        auto &vec = sinks[sigmap(sigbit)];
                        vec.push_back(CellPin(nullptr, sigbit.wire->name, i));
                    }
                    // Input port (source)
                    if (sigbit.wire->port_input) {
                        drivers.insert(std::make_pair(sigbit, CellPin(nullptr, sigbit.wire->name, i)));
                    }
                }
            }
        }

        /// Clears the map
        void clear()
        {
            sinks.clear();
            drivers.clear();
        };
    };

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

    /// 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;
    /// Module connection map
    ConnMap m_ConnMap;

    /// 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 defines 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 being\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 connection map
            m_ConnMap.clear();
            m_ConnMap.build(module, m_SigMap);

            // 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();
        m_ConnMap.clear();
    }

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

    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 = m_SigMap(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)) {
                    if (m_ConnMap.sinks.count(sigbit)) {
                        for (const auto &sink : m_ConnMap.sinks.at(sigbit)) {
                            if (sink.cell != nullptr && m_CellsToRemove.count(sink.cell)) {
                                continue;
                            }
                            others.insert(sink);
                        }
                    }

                }
                // Get driver. Discard if the driver drives something else too
                else if (a_Cell->input(port.name)) {
                    if (m_ConnMap.drivers.count(sigbit)) {
                        auto driver = m_ConnMap.drivers.at(sigbit);

                        if (m_ConnMap.sinks.count(sigbit)) {
                            auto sinks = m_ConnMap.sinks.at(sigbit);
                            if (sinks.size() > 1) {
                                log_debug("multiple sinks (%zu)\n", others.size());
                                flopsOk = false;
                                continue;
                            }
                        }

                        others.insert(driver);
                    }
                }

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

                if (others.size() > 1) {
                    log_debug("multiple sinks (%zu)\n", others.size());
                    flopsOk = false;
                    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;
    }

} DspFF;

PRIVATE_NAMESPACE_END
