/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2019  David Shah <david@symbioticeda.com>
 *
 *  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 "cells.h"
#include "design_utils.h"
#include "log.h"
#include "util.h"

NEXTPNR_NAMESPACE_BEGIN

void add_port(const Context *ctx, CellInfo *cell, std::string name, PortType dir)
{
    IdString id = ctx->id(name);
    NPNR_ASSERT(cell->ports.count(id) == 0);
    cell->ports[id] = PortInfo{id, nullptr, dir};
}

std::unique_ptr<CellInfo> create_generic_cell(Context *ctx, IdString type, std::string name)
{
    static int auto_idx = 0;
    std::unique_ptr<CellInfo> new_cell = std::unique_ptr<CellInfo>(new CellInfo());
    if (name.empty()) {
        new_cell->name = ctx->id("$nextpnr_" + type.str(ctx) + "_" + std::to_string(auto_idx++));
    } else {
        new_cell->name = ctx->id(name);
    }
    new_cell->type = type;
    if (type == ctx->id("GENERIC_SLICE")) {
        new_cell->params[ctx->id("K")] = ctx->args.K;
        new_cell->params[ctx->id("INIT")] = 0;
        new_cell->params[ctx->id("FF_USED")] = 0;

        for (int i = 0; i < ctx->args.K; i++)
            add_port(ctx, new_cell.get(), "I[" + std::to_string(i) + "]", PORT_IN);

        add_port(ctx, new_cell.get(), "CLK", PORT_IN);

        add_port(ctx, new_cell.get(), "F", PORT_OUT);
        add_port(ctx, new_cell.get(), "Q", PORT_OUT);
    } else if (type == ctx->id("GENERIC_IOB")) {
        new_cell->params[ctx->id("INPUT_USED")] = 0;
        new_cell->params[ctx->id("OUTPUT_USED")] = 0;
        new_cell->params[ctx->id("ENABLE_USED")] = 0;

        add_port(ctx, new_cell.get(), "PAD", PORT_INOUT);
        add_port(ctx, new_cell.get(), "I", PORT_IN);
        add_port(ctx, new_cell.get(), "EN", PORT_IN);
        add_port(ctx, new_cell.get(), "O", PORT_OUT);
    } else {
        log_error("unable to create generic cell of type %s", type.c_str(ctx));
    }
    return new_cell;
}

void lut_to_lc(const Context *ctx, CellInfo *lut, CellInfo *lc, bool no_dff)
{
    lc->params[ctx->id("INIT")] = lut->params[ctx->id("INIT")];

    int lut_k = int_or_default(lut->params, ctx->id("K"), 4);
    NPNR_ASSERT(lut_k <= ctx->args.K);

    for (int i = 0; i < lut_k; i++) {
        IdString port = ctx->id("I[" + std::to_string(i) + "]");
        replace_port(lut, port, lc, port);
    }

    if (no_dff) {
        lc->params[ctx->id("FF_USED")] = 0;
        replace_port(lut, ctx->id("Q"), lc, ctx->id("F"));
    }
}

void dff_to_lc(const Context *ctx, CellInfo *dff, CellInfo *lc, bool pass_thru_lut)
{
    lc->params[ctx->id("FF_USED")] = 1;
    replace_port(dff, ctx->id("CLK"), lc, ctx->id("CLK"));

    if (pass_thru_lut) {
        // Fill LUT with alternating 10
        const int init_size = 1 << lc->params[ctx->id("K")].as_int64();
        std::string init;
        init.reserve(init_size);
        for (int i = 0; i < init_size; i += 2)
            init.append("10");
        lc->params[ctx->id("INIT")] = Property::from_string(init);

        replace_port(dff, ctx->id("D"), lc, ctx->id("I[0]"));
    }

    replace_port(dff, ctx->id("Q"), lc, ctx->id("Q"));
}

void nxio_to_iob(Context *ctx, CellInfo *nxio, CellInfo *iob, std::unordered_set<IdString> &todelete_cells)
{
    if (nxio->type == ctx->id("$nextpnr_ibuf")) {
        iob->params[ctx->id("INPUT_USED")] = 1;
        replace_port(nxio, ctx->id("O"), iob, ctx->id("O"));
    } else if (nxio->type == ctx->id("$nextpnr_obuf")) {
        iob->params[ctx->id("OUTPUT_USED")] = 1;
        replace_port(nxio, ctx->id("I"), iob, ctx->id("I"));
    } else if (nxio->type == ctx->id("$nextpnr_iobuf")) {
        // N.B. tristate will be dealt with below
        iob->params[ctx->id("INPUT_USED")] = 1;
        iob->params[ctx->id("OUTPUT_USED")] = 1;
        replace_port(nxio, ctx->id("I"), iob, ctx->id("I"));
        replace_port(nxio, ctx->id("O"), iob, ctx->id("O"));
    } else {
        NPNR_ASSERT(false);
    }
    NetInfo *donet = iob->ports.at(ctx->id("I")).net;
    CellInfo *tbuf = net_driven_by(
            ctx, donet, [](const Context *ctx, const CellInfo *cell) { return cell->type == ctx->id("$_TBUF_"); },
            ctx->id("Y"));
    if (tbuf) {
        iob->params[ctx->id("ENABLE_USED")] = 1;
        replace_port(tbuf, ctx->id("A"), iob, ctx->id("I"));
        replace_port(tbuf, ctx->id("E"), iob, ctx->id("EN"));

        if (donet->users.size() > 1) {
            for (auto user : donet->users)
                log_info("     remaining tristate user: %s.%s\n", user.cell->name.c_str(ctx), user.port.c_str(ctx));
            log_error("unsupported tristate IO pattern for IO buffer '%s', "
                      "instantiate GENERIC_IOB manually to ensure correct behaviour\n",
                      nxio->name.c_str(ctx));
        }
        ctx->nets.erase(donet->name);
        todelete_cells.insert(tbuf->name);
    }
}

NEXTPNR_NAMESPACE_END
