/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2021 QuickLogic Corp.
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

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

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

#include "pmgen/ql-dsp-pm.h"

void create_ql_dsp(ql_dsp_pm &pm)
{
    auto &st = pm.st_ql_dsp;

    log("Checking %s.%s for QL DSP inference.\n", log_id(pm.module), log_id(st.mul));

    log_debug("ffA:    %s\n", log_id(st.ffA, "--"));
    log_debug("ffB:    %s\n", log_id(st.ffB, "--"));
    log_debug("ffCD:   %s\n", log_id(st.ffCD, "--"));
    log_debug("mul:    %s\n", log_id(st.mul, "--"));
    log_debug("ffFJKG: %s\n", log_id(st.ffFJKG, "--"));
    log_debug("ffH:    %s\n", log_id(st.ffH, "--"));
    log_debug("add:    %s\n", log_id(st.add, "--"));
    log_debug("mux:    %s\n", log_id(st.mux, "--"));
    log_debug("ffO:    %s\n", log_id(st.ffO, "--"));
    log_debug("\n");

    if (GetSize(st.sigA) > 16) {
        log("  input A (%s) is too large (%d > 16).\n", log_signal(st.sigA), GetSize(st.sigA));
        return;
    }

    if (GetSize(st.sigB) > 16) {
        log("  input B (%s) is too large (%d > 16).\n", log_signal(st.sigB), GetSize(st.sigB));
        return;
    }

    if (GetSize(st.sigO) > 33) {
        log("  adder/accumulator (%s) is too large (%d > 33).\n", log_signal(st.sigO), GetSize(st.sigO));
        return;
    }

    if (GetSize(st.sigH) > 32) {
        log("  output (%s) is too large (%d > 32).\n", log_signal(st.sigH), GetSize(st.sigH));
        return;
    }

    Cell *cell = st.mul;
    if (cell->type == ID($mul)) {
        log("  replacing %s with QL_DSP cell.\n", log_id(st.mul->type));

        cell = pm.module->addCell(NEW_ID, ID(QL_DSP));
        pm.module->swap_names(cell, st.mul);
    } else
        log_assert(cell->type == ID(QL_DSP));

    // QL_DSP Input Interface
    SigSpec A = st.sigA;
    A.extend_u0(16, st.mul->getParam(ID::A_SIGNED).as_bool());
    log_assert(GetSize(A) == 16);

    SigSpec B = st.sigB;
    B.extend_u0(16, st.mul->getParam(ID::B_SIGNED).as_bool());
    log_assert(GetSize(B) == 16);

    SigSpec CD = st.sigCD;
    if (CD.empty())
        CD = RTLIL::Const(0, 32);
    else
        log_assert(GetSize(CD) == 32);

    cell->setPort(ID::A, A);
    cell->setPort(ID::B, B);
    cell->setPort(ID::C, CD.extract(16, 16));
    cell->setPort(ID::D, CD.extract(0, 16));

    cell->setParam(ID(A_REG), st.ffA ? State::S1 : State::S0);
    cell->setParam(ID(B_REG), st.ffB ? State::S1 : State::S0);
    cell->setParam(ID(C_REG), st.ffCD ? State::S1 : State::S0);
    cell->setParam(ID(D_REG), st.ffCD ? State::S1 : State::S0);

    // QL_DSP Output Interface

    SigSpec O = st.sigO;
    int O_width = GetSize(O);
    if (O_width == 33) {
        log_assert(st.add);
        // If we have a signed multiply-add, then perform sign extension
        if (st.add->getParam(ID::A_SIGNED).as_bool() && st.add->getParam(ID::B_SIGNED).as_bool())
            pm.module->connect(O[32], O[31]);
        else
            cell->setPort(ID::CO, O[32]);
        O.remove(O_width - 1);
    } else
        cell->setPort(ID::CO, pm.module->addWire(NEW_ID));
    log_assert(GetSize(O) <= 32);
    if (GetSize(O) < 32)
        O.append(pm.module->addWire(NEW_ID, 32 - GetSize(O)));

    cell->setPort(ID::O, O);

    cell->setParam(ID::A_SIGNED, st.mul->getParam(ID::A_SIGNED).as_bool());
    cell->setParam(ID::B_SIGNED, st.mul->getParam(ID::B_SIGNED).as_bool());

    if (cell != st.mul)
        pm.autoremove(st.mul);
    else
        pm.blacklist(st.mul);
    pm.autoremove(st.ffFJKG);
    pm.autoremove(st.add);
}

struct QlDspPass : public Pass {
    QlDspPass() : Pass("ql_dsp", "ql: map multipliers") {}
    void help() override
    {
        //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
        log("\n");
        log("    ql_dsp [options] [selection]\n");
        log("\n");
        log("Map multipliers ($mul/QL_DSP) and multiply-accumulate ($mul/QL_DSP + $add)\n");
        log("cells into ql DSP resources.\n");
        log("Pack input registers (A, B, {C,D}), pipeline registers\n");
        log("({F,J,K,G}, H), output registers (O -- full 32-bits or lower 16-bits only); \n");
        log("and post-adder into into the QL_DSP resource.\n");
        log("\n");
        log("Multiply-accumulate operations using the post-adder with feedback on the {C,D}\n");
        log("input will be folded into the DSP. In this scenario only, resetting the\n");
        log("the accumulator to an arbitrary value can be inferred to use the {C,D} input.\n");
        log("\n");
    }
    void execute(std::vector<std::string> args, RTLIL::Design *design) override
    {
        log_header(design, "Executing ql_DSP pass (map multipliers).\n");

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

        for (auto module : design->selected_modules())
            ql_dsp_pm(module, module->selected_cells()).run_ql_dsp(create_ql_dsp);
    }
} QlDspPass;

PRIVATE_NAMESPACE_END
