#include "kernel/sigtools.h"
#include "kernel/yosys.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

#define MODE_BITS_REGISTER_INPUTS_ID 92
#define MODE_BITS_OUTPUT_SELECT_START_ID 81
#define MODE_BITS_OUTPUT_SELECT_WIDTH 3

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

struct QlDspIORegs : public Pass {

    const std::vector<std::string> ports2del_mult = {"load_acc", "subtract", "acc_fir", "dly_b"};
    const std::vector<std::string> ports2del_mult_acc = {"acc_fir", "dly_b"};
    const std::vector<std::string> ports2del_mult_add = {"dly_b"};
    const std::vector<std::string> ports2del_extension = {"saturate_enable", "shift_right", "round"};

    /// Temporary SigBit to SigBit helper map.
    SigMap m_SigMap;

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

    QlDspIORegs() : Pass("ql_dsp_io_regs", "Changes types of QL_DSP2/QL_DSP3 depending on their configuration.") {}

    void help() override
    {
        log("\n");
        log("    ql_dsp_io_regs [options] [selection]\n");
        log("\n");
        log("Looks for QL_DSP2/QL_DSP3 cells and changes their types depending\n");
        log("on their configuration.\n");
    }

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

        size_t argidx;
        for (argidx = 1; argidx < a_Args.size(); argidx++) {
            break;
        }
        extra_args(a_Args, argidx, a_Design);

        for (auto module : a_Design->selected_modules()) {
            ql_dsp_io_regs_pass(module);
        }
    }

    // Returns a pair of mask and value describing constant bit connections of
    // a SigSpec
    std::pair<uint32_t, uint32_t> get_constant_mask_value(const RTLIL::SigSpec *sigspec)
    {
        uint32_t mask = 0L;
        uint32_t value = 0L;

        auto sigbits = sigspec->bits();
        for (ssize_t i = (sigbits.size() - 1); i >= 0; --i) {
            auto other = m_SigMap(sigbits[i]);

            mask <<= 1;
            value <<= 1;

            // A known constant
            if (!other.is_wire() && other.data != RTLIL::Sx) {
                mask |= 0x1;
                value |= (other.data == RTLIL::S1);
            }
        }

        return std::make_pair(mask, value);
    }

    void ql_dsp_io_regs_pass(RTLIL::Module *module)
    {
        // Setup the SigMap
        m_SigMap.clear();
        m_SigMap.set(module);

        for (auto cell : module->cells_) {
            std::string cell_type = cell.second->type.str();
            if (cell_type == RTLIL::escape_id("QL_DSP2") || cell_type == RTLIL::escape_id("QL_DSP3")) {
                auto dsp = cell.second;

                // If the cell does not have the "is_inferred" attribute set
                // then don't touch it.
                if (!dsp->has_attribute(RTLIL::escape_id("is_inferred")) ||
                     dsp->get_bool_attribute(RTLIL::escape_id("is_inferred")) == false)
                {
                    continue;
                }

                bool del_clk = true;
                bool use_dsp_cfg_params = (cell_type == RTLIL::escape_id("QL_DSP3"));

                int reg_in_i;
                int out_sel_i;

                // Get DSP configuration
                if (use_dsp_cfg_params) {
                    // Read MODE_BITS at correct indexes
                    auto mode_bits = &dsp->getParam(RTLIL::escape_id("MODE_BITS"));
                    RTLIL::Const register_inputs;
                    register_inputs = mode_bits->bits.at(MODE_BITS_REGISTER_INPUTS_ID);
                    reg_in_i = register_inputs.as_int();

                    RTLIL::Const output_select;
                    output_select = mode_bits->extract(MODE_BITS_OUTPUT_SELECT_START_ID, MODE_BITS_OUTPUT_SELECT_WIDTH);
                    out_sel_i = output_select.as_int();
                } else {
                    // Read dedicated configuration ports
                    const RTLIL::SigSpec *register_inputs;
                    register_inputs = &dsp->getPort(RTLIL::escape_id("register_inputs"));
                    if (!register_inputs)
                        log_error("register_inputs port not found!");
                    auto reg_in_c = register_inputs->as_const();
                    reg_in_i = reg_in_c.as_int();

                    const RTLIL::SigSpec *output_select;
                    output_select = &dsp->getPort(RTLIL::escape_id("output_select"));
                    if (!output_select)
                        log_error("output_select port not found!");
                    auto out_sel_c = output_select->as_const();
                    out_sel_i = out_sel_c.as_int();
                }

                // Get the feedback port
                const RTLIL::SigSpec *feedback;
                feedback = &dsp->getPort(RTLIL::escape_id("feedback"));
                if (!feedback)
                    log_error("feedback port not found!");

                // Check if feedback is or can be set to 0 which implies MACC
                auto feedback_con = get_constant_mask_value(feedback);
                bool have_macc = (feedback_con.second == 0x0);
                // log("mask=0x%08X value=0x%08X\n", consts.first, consts.second);
                // log_error("=== END HERE ===\n");

                // Build new type name
                std::string new_type = cell_type;
                new_type += "_MULT";

                if (have_macc) {
                    switch (out_sel_i) {
                    case 1:
                    case 2:
                    case 3:
                    case 5:
                    case 7:
                        del_clk = false;
                        new_type += "ACC";
                        break;
                    default:
                        break;
                    }
                } else {
                    switch (out_sel_i) {
                    case 1:
                    case 2:
                    case 3:
                    case 5:
                    case 7:
                        new_type += "ADD";
                        break;
                    default:
                        break;
                    }
                }

                if (reg_in_i) {
                    del_clk = false;
                    new_type += "_REGIN";
                }

                if (out_sel_i > 3) {
                    del_clk = false;
                    new_type += "_REGOUT";
                }

                // Set new type name
                dsp->type = RTLIL::IdString(new_type);

                std::vector<std::string> ports2del;

                if (del_clk)
                    ports2del.push_back("clk");

                switch (out_sel_i) {
                case 0:
                case 4:
                case 6:
                    ports2del.insert(ports2del.end(), ports2del_mult.begin(), ports2del_mult.end());
                    // Mark for deleton additional configuration ports
                    if (!use_dsp_cfg_params) {
                        ports2del.insert(ports2del.end(), ports2del_extension.begin(), ports2del_extension.end());
                    }
                    break;
                case 1:
                case 2:
                case 3:
                case 5:
                case 7:
                    if (have_macc) {
                        ports2del.insert(ports2del.end(), ports2del_mult_acc.begin(), ports2del_mult_acc.end());
                    } else {
                        ports2del.insert(ports2del.end(), ports2del_mult_add.begin(), ports2del_mult_add.end());
                    }
                    break;
                }

                for (auto portname : ports2del) {
                    const RTLIL::SigSpec *port = &dsp->getPort(RTLIL::escape_id(portname));
                    if (!port)
                        log_error("%s port not found!", portname.c_str());
                    dsp->connections_.erase(RTLIL::escape_id(portname));
                }
            }
        }

        // Clear the sigmap
        m_SigMap.clear();
    }

} QlDspIORegs;

PRIVATE_NAMESPACE_END
