#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 DspPortType {
        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;

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

    /// Describes a DSP cell type
    struct DspType {
        RTLIL::IdString name;

        /// A list of data ports with registers
        std::vector<DspPortType> ports;
    };

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

        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]);

                auto& ports = dspTypes.back().ports;
                ports.resize(ports.size() + 1);
                ports.back().name = RTLIL::escape_id(std::get<0>(spec));
                ports.back().bits = std::make_pair(std::get<2>(spec), std::get<1>(spec));
                ports.back().assoc.insert(std::make_pair(RTLIL::escape_id("clk"),
                    std::make_pair(RTLIL::IdString(), RTLIL::Sx)));
                ports.back().assoc.insert(std::make_pair(RTLIL::escape_id("rst"),
                    std::make_pair(RTLIL::IdString(), RTLIL::Sx)));
                ports.back().assoc.insert(std::make_pair(RTLIL::escape_id("ena"),
                    std::make_pair(RTLIL::IdString(), RTLIL::Sx)));
            }
            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(); 
            }

            // 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());
                    }
                    auto& ports = dspTypes.back().ports;
                    ports.back().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());
                    }
                    auto& ports = dspTypes.back().ports;
                    ports.back().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());
                    }
                    auto& ports = dspTypes.back().ports;
                    ports.back().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 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") {
                    auto& ports = dspTypes.back().ports;
                    ports.back().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") {
                    auto& ports = dspTypes.back().ports;
                    ports.back().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);
                auto& ports = dspTypes.back().ports;
                for (const auto& it : vec) {
                    ports.back().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& it : m_DspTypes) {
            const auto& dsp = it.second;
            log(" %s\n", dsp.name.c_str());

            log(" ports:\n");
            for (const auto& port : dsp.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 (!port.params.set.empty()) {
                    log("   set params:\n");
                    for (const auto& it : port.params.set) {
                        log("    %s=%s\n", it.first.c_str(), it.second.decode_string().c_str());
                    }
                }
                if (!port.params.map.empty()) {
                    log("   map params:\n");
                    for (const auto& it : port.params.map) {
                        log("    %s=%s\n", it.first.c_str(), it.second.c_str());
                    }
                }
                if (!port.connect.empty()) {
                    log("   connect ports:\n");
                    for (const auto& it : port.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.set.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");
    }

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

                // Check ports
                auto& rule = m_DspTypes.at(cell->type);
                for (auto& portRule : rule.ports) {

                    // Sanity check
                    if (!cell->hasPort(portRule.name)) {
                        log(" The DSP cell '%s' does not have a port named '%s'!\n",
                            cell->type.c_str(), portRule.name.c_str());
                        continue;
                    }

                    processPort(cell, portRule);
                }
            }

            // 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 checkDspPort (RTLIL::Cell* a_Cell, const DspPortType& a_PortRule) {
        bool isOk = true;

        // The cell register control parameters must not be set
        for (const auto& it : a_PortRule.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());
                isOk = false;
            }
        }

        return isOk;
    }

    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 checkFlopDataAgainstDspPort (const FlopData& a_FlopData,
                                      RTLIL::Cell* a_Cell,
                                      const DspPortType& a_PortRule)
    {
        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 port... ");

        // Check control signal connections
        for (const auto& it : a_PortRule.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_PortRule.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_PortRule.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 processPort (RTLIL::Cell* a_Cell, const DspPortType& a_PortRule) {

        log_debug(" Attempting flip-flop integration for %s.%s of %s\n",
            a_Cell->type.c_str(), a_PortRule.name.c_str(), a_Cell->name.c_str());

        // Check if the port can be used for FF integration
        log_assert(a_Cell->output(a_PortRule.name) || a_Cell->input(a_PortRule.name));
        if (!checkDspPort(a_Cell, a_PortRule)) {
            log_debug("  port check failed\n");
            return;
        }

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

        // Collect flip-flops, identify their group count
        dict<FlopData, int> groups;

        std::vector<std::pair<RTLIL::Cell*, int>> flops
            (sigbits.size(), std::make_pair(nullptr, -1));

        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 ((a_PortRule.bits.first  >= 0 && (int)i < a_PortRule.bits.first) ||
                (a_PortRule.bits.second >= 0 && (int)i > a_PortRule.bits.second))
            {
                continue;
            }

            pool<CellPin> others;

            // Get sinks(s), discard the port completely if more than one sink
            // is found.
            if (a_Cell->output(a_PortRule.name)) {
                others = getSinks(CellPin(a_Cell, a_PortRule.name, i));
                if (others.size() > 1) {
                    log_debug("  multiple sinks found, cannot integrate.\n");
                    return;
                }
            }
            // 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(a_PortRule.name)) {
                auto driver = getDriver(CellPin(a_Cell, a_PortRule.name, i));
                if (driver.cell != nullptr) {
                    auto sinks = getSinks(driver);
                    if (sinks.size() > 1) {
                        log_debug("  multiple sinks found, cannot integrate.\n");
                        return;
                    }
                }
                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, cannot integrate\n");
                    return;
                } else {
                    continue;
                }
            }

            if (!m_FlopTypes.count(flop->type)) {
                log_debug("  non-flip-flop connected, cannot integrate\n");
                return;
            }

            // 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(a_PortRule.name)) {
                flopPort = flopType.ports.at(RTLIL::escape_id("d"));
            }
            else if (a_Cell->input(a_PortRule.name)) {
                flopPort = flopType.ports.at(RTLIL::escape_id("q"));
            }

            if (flopPort != other.port) {
                log_debug("  connection to non-data port of a flip-flip, cannot integrate\n");
                return;
            }

            // Check the flip-flop configuration
            if (!checkFlop(flop)) {
                return;
            }

            // Get parameters to be mapped to the DSP according to the port
            // rule.
            dict<RTLIL::IdString, RTLIL::Const> mappedParams;
            for (const auto& it : a_PortRule.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
            auto res = groups.insert(
                std::make_pair(getFlopData(flop, mappedParams),groups.size())
            );
            flops[i] = std::make_pair(flop, res.first->second);
        }

        // 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()->first;
        if (!checkFlopDataAgainstDspPort(flopData, a_Cell, a_PortRule)) {
            log_debug("  flip-flop vs. DSP check failed\n");
            return;
        }

        // Debug log
        log(" %s %s.%s\n", a_Cell->type.c_str(), a_Cell->name.c_str(), a_PortRule.name.c_str());
        for (size_t i=0; i<flops.size(); ++i) {
            if (flops[i].first != nullptr) {
                log_debug("  %2zu. (%d) %s %s\n", i,
                    flops[i].second,
                    flops[i].first->type.c_str(), flops[i].first->name.c_str());
            }
            else if ((a_PortRule.bits.first  >= 0 && (int)i < a_PortRule.bits.first) ||
                     (a_PortRule.bits.second >= 0 && (int)i > a_PortRule.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 (size_t i=0; i<flops.size(); ++i) {

            auto* flop = flops[i].first;
            if (flop == nullptr) {
                continue;
            }

            RTLIL::IdString port;
            if (a_Cell->output(a_PortRule.name)) {
                port = flopType.ports.at(RTLIL::escape_id("q"));
            }
            else if (a_Cell->input(a_PortRule.name)) {
                port = flopType.ports.at(RTLIL::escape_id("d"));
            }
            
            if (!flop->hasPort(port)) {
                log_error("  cell '%s' does not have port '%s'!\n",
                    flop->type.c_str(), port.c_str());
            }

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

            m_CellsToRemove.insert(flop);
        }
        a_Cell->setPort(a_PortRule.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& it : a_PortRule.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 DSP port rule
        for (const auto& it : a_PortRule.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 (port rule)
        for (const auto& it : a_PortRule.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_PortRule.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

