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

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

#include "pmgen/ql-bram-asymmetric-wider-read.h"
#include "pmgen/ql-bram-asymmetric-wider-write.h"

void test_ql_bram_asymmetric_wider_read(ql_bram_asymmetric_wider_read_pm &pm)
{
    auto mem = pm.st_ql_bram_asymmetric_wider_read.mem;
    auto mem_wr_addr = pm.st_ql_bram_asymmetric_wider_read.mem_wr_addr;
    auto mem_rd_data = pm.st_ql_bram_asymmetric_wider_read.mem_rd_data;
    auto mem_rd_addr = pm.st_ql_bram_asymmetric_wider_read.mem_rd_addr;
    auto mux = pm.st_ql_bram_asymmetric_wider_read.mux;
    auto mux_s = pm.st_ql_bram_asymmetric_wider_read.mux_s;
    auto wr_en_shift = pm.st_ql_bram_asymmetric_wider_read.wr_en_shift;
    auto wr_en_shift_b = pm.st_ql_bram_asymmetric_wider_read.wr_en_shift_b;
    auto wr_data_shift = pm.st_ql_bram_asymmetric_wider_read.wr_data_shift;
    auto wr_data_shift_a = pm.st_ql_bram_asymmetric_wider_read.wr_data_shift_a;
    auto wr_data_shift_b = pm.st_ql_bram_asymmetric_wider_read.wr_data_shift_b;
    auto wr_en_and = pm.st_ql_bram_asymmetric_wider_read.wr_en_and;
    auto wr_en_and_a = pm.st_ql_bram_asymmetric_wider_read.wr_en_and_a;
    auto wr_en_and_b = pm.st_ql_bram_asymmetric_wider_read.wr_en_and_b;
    auto wr_en_and_y = pm.st_ql_bram_asymmetric_wider_read.wr_en_and_y;

    // Add the BRAM cell
    std::string name = mem->name.str() + "$asymmetric";
    RTLIL::Cell *cell = pm.module->addCell(RTLIL::escape_id(name), mem);

    // Set new type for cell so that it won't be processed by memory_bram pass
    cell->type = IdString(RTLIL::escape_id("_$_mem_v2_asymmetric"));

    // Prepare wires from memory cell side to compare against module wires
    if (!mux_s.is_wire())
        log_error("WR_EN input wire not found\n");
    RTLIL::Wire *wr_en_cw = mux_s.as_wire();

    // The WR address wire can be narrower
    RTLIL::Wire *wr_addr_cw = nullptr;
    if (mem_wr_addr.is_wire())
        wr_addr_cw = mem_wr_addr.as_wire();
    else if (!mem_wr_addr.chunks().empty()) {
        auto chunk = mem_wr_addr.chunks()[0];
        if (chunk.is_wire())
            wr_addr_cw = chunk.wire;
    }
    if (!wr_addr_cw)
        log_error("WR_ADDR input wire not found\n");

    if (!wr_data_shift_a.is_wire())
        log_error("WR_DATA input wire not found\n");
    RTLIL::Wire *wr_data_cw = wr_data_shift_a.as_wire();
    if (!mem_rd_addr.is_wire())
        log_error("RD_ADDR input wire not found\n");
    RTLIL::Wire *rd_addr_cw = mem_rd_addr.as_wire();
    if (!mem_rd_data.is_wire())
        log_error("RD_DATA input wire not found\n");
    RTLIL::Wire *rd_data_cw = mem_rd_data.as_wire();

    // Check if wr_en_and cell has one of its inputs connected to write address
    RTLIL::Wire *wr_en_and_a_w = nullptr;
    RTLIL::Wire *wr_en_and_b_w = nullptr;
    bool has_wire = false;
    if (wr_en_and_a.is_wire()) {
        has_wire = true;
        wr_en_and_a_w = wr_en_and_a.as_wire();
    }
    if (wr_en_and_b.is_wire()) {
        has_wire = true;
        wr_en_and_b_w = wr_en_and_b.as_wire();
    }
    if (!has_wire)
        log_error("RD_ADDR $and cell input wire not found\n");
    if ((wr_en_and_a_w != wr_addr_cw) & (wr_en_and_b_w != wr_addr_cw))
        log_error("This is not the $and cell we are looking for\n");

    // Compare and assign wires
    RTLIL::Wire *wr_en_w = nullptr;
    RTLIL::Wire *wr_addr_w = nullptr;
    RTLIL::Wire *wr_data_w = nullptr;
    RTLIL::Wire *rd_addr_w = nullptr;
    RTLIL::Wire *rd_data_w = nullptr;

    for (auto wire : pm.module->wires_) {
        if (wire.second == wr_en_cw)
            wr_en_w = wire.second;
        if (wire.second == wr_addr_cw)
            wr_addr_w = wire.second;
        if (wire.second == wr_data_cw)
            wr_data_w = wire.second;
        if (wire.second == rd_data_cw)
            rd_data_w = wire.second;
        if (wire.second == rd_addr_cw)
            rd_addr_w = wire.second;
    }

    if (!wr_en_w | !wr_addr_w | !wr_data_w | !rd_data_w | !rd_addr_w)
        log_error("Match between RAM input wires and memory cell ports not found\n");

    // Get address and data lines widths
    int rd_addr_width = rd_addr_w->width;
    int wr_addr_width = wr_addr_w->width;
    int wr_data_width = wr_data_w->width;
    int rd_data_width = rd_data_w->width;

    log_debug("Set RD_ADDR_WIDTH = %d, ", rd_addr_width);
    log_debug("WR_ADDR_WIDTH = %d, ", wr_addr_width);
    log_debug("RD_DATA_WIDTH = %d, ", rd_data_width);
    log_debug("WR_DATA_WIDTH = %d\n", wr_data_width);

    // Set address and data lines width parameters used later in techmap
    cell->setParam(RTLIL::escape_id("RD_ADDR_WIDTH"), RTLIL::Const(rd_addr_width));
    cell->setParam(RTLIL::escape_id("RD_DATA_WIDTH"), RTLIL::Const(rd_data_width));
    cell->setParam(RTLIL::escape_id("WR_ADDR_WIDTH"), RTLIL::Const(wr_addr_width));
    cell->setParam(RTLIL::escape_id("WR_DATA_WIDTH"), RTLIL::Const(wr_data_width));

    int offset;

    switch (wr_data_width) {
    case 1:
        offset = 0;
        break;
    case 2:
        offset = 1;
        break;
    case 4:
        offset = 2;
        break;
    case 8:
    case 9:
        offset = 3;
        break;
    case 16:
    case 18:
        offset = 4;
        break;
    case 32:
    case 36:
        offset = 5;
        break;
    default:
        offset = 0;
        break;
    }

    if (wr_en_and_y != wr_en_shift_b.extract(offset, wr_addr_width))
        log_error("This is not the wr_en $shl cell we are looking for\n");
    if (wr_en_and_y != wr_data_shift_b.extract(offset, wr_addr_width))
        log_error("This is not the wr_data $shl cell we are looking for\n");

    // Bypass shift on write address line
    cell->setPort(RTLIL::escape_id("WR_ADDR"), RTLIL::SigSpec(wr_addr_w));

    // Bypass shift on write address line
    cell->setPort(RTLIL::escape_id("WR_DATA"), RTLIL::SigSpec(wr_data_w));

    // Bypass shift on write address line
    cell->setPort(RTLIL::escape_id("WR_EN"), RTLIL::SigSpec(wr_en_w));

    // Cleanup the module from unused cells
    pm.module->remove(mem);
    pm.module->remove(mux);
    pm.module->remove(wr_en_shift);
    pm.module->remove(wr_en_and);
    pm.module->remove(wr_data_shift);
}

void test_ql_bram_asymmetric_wider_write(ql_bram_asymmetric_wider_write_pm &pm)
{
    auto mem = pm.st_ql_bram_asymmetric_wider_write.mem;
    auto mem_wr_addr = pm.st_ql_bram_asymmetric_wider_write.mem_wr_addr;
    auto mem_wr_data = pm.st_ql_bram_asymmetric_wider_write.mem_wr_data;
    auto mem_rd_data = pm.st_ql_bram_asymmetric_wider_write.mem_rd_data;
    auto mem_rd_addr = pm.st_ql_bram_asymmetric_wider_write.mem_rd_addr;
    auto rd_data_shift = pm.st_ql_bram_asymmetric_wider_write.rd_data_shift;
    auto rd_data_shift_y = pm.st_ql_bram_asymmetric_wider_write.rd_data_shift_y;
    auto rd_data_ff = pm.st_ql_bram_asymmetric_wider_write.rd_data_ff;
    auto rd_data_ff_q = pm.st_ql_bram_asymmetric_wider_write.rd_data_ff_q;
    auto rd_data_ff_en = pm.st_ql_bram_asymmetric_wider_write.rd_data_ff_en;
    auto rd_data_ff_clk = pm.st_ql_bram_asymmetric_wider_write.rd_data_ff_clk;
    auto wr_addr_ff = pm.st_ql_bram_asymmetric_wider_write.wr_addr_ff;
    auto wr_addr_ff_d = pm.st_ql_bram_asymmetric_wider_write.wr_addr_ff_d;
    auto wr_en_mux = pm.st_ql_bram_asymmetric_wider_write.wr_en_mux;
    auto wr_en_mux_s = pm.st_ql_bram_asymmetric_wider_write.wr_en_mux_s;
    auto rd_addr_and = pm.st_ql_bram_asymmetric_wider_write.rd_addr_and;
    auto rd_addr_and_a = pm.st_ql_bram_asymmetric_wider_write.rd_addr_and_a;
    auto rd_addr_and_b = pm.st_ql_bram_asymmetric_wider_write.rd_addr_and_b;

    // Add the BRAM cell
    std::string name = mem->name.str() + "$asymmetric";
    RTLIL::Cell *cell = pm.module->addCell(RTLIL::escape_id(name), mem);

    // Set new type for cell so that it won't be processed by memory_bram pass
    cell->type = IdString(RTLIL::escape_id("_$_mem_v2_asymmetric"));

    // Prepare wires from memory cell side to compare against module wires
    RTLIL::Wire *rd_data_wc = nullptr;
    RTLIL::Wire *rd_en_wc = nullptr;
    RTLIL::Wire *clk_wc = nullptr;
    RTLIL::Wire *rd_addr_and_a_wc = nullptr;
    RTLIL::Wire *rd_addr_and_b_wc = nullptr;

    if (rd_data_ff) {
        if (!rd_data_ff_q.is_wire())
            log_error("RD_DATA input wire not found\n");
        rd_data_wc = rd_data_ff_q.as_wire();
        if (!rd_data_ff_en.is_wire())
            log_error("RD_EN input wire not found\n");
        rd_en_wc = rd_data_ff_en.as_wire();
        if (!rd_data_ff_clk.is_wire())
            log_error("RD_CLK input wire not found\n");
        clk_wc = rd_data_ff_clk.as_wire();
    } else {
        log_error("output FF not found\n");
    }

    if (rd_addr_and) {
        bool has_wire = false;
        if (rd_addr_and_a.is_wire()) {
            has_wire = true;
            rd_addr_and_a_wc = rd_addr_and_a.as_wire();
        }
        if (rd_addr_and_b.is_wire()) {
            has_wire = true;
            rd_addr_and_b_wc = rd_addr_and_b.as_wire();
        }
        if (!has_wire)
            log_error("RD_ADDR $and cell input wire not found\n");
    } else {
        log_debug("RD_ADDR $and cell not found\n");
    }

    RTLIL::Wire *wr_addr_wc;
    if (wr_addr_ff) {
        if (!wr_addr_ff_d.is_wire())
            log_error("WR_ADDR input wire not found\n");
        wr_addr_wc = wr_addr_ff_d.as_wire();
    } else {
        if (!mem_wr_addr.is_wire())
            log_error("WR_ADDR input wire not found\n");
        wr_addr_wc = mem_wr_addr.as_wire();
    }

    // The RD address wire can be narrower
    RTLIL::Wire *rd_addr_wc = nullptr;
    if (mem_rd_addr.is_wire())
        rd_addr_wc = mem_rd_addr.as_wire();
    else if (!mem_rd_addr.chunks().empty()) {
        auto chunk = mem_rd_addr.chunks()[0];
        if (chunk.is_wire())
            rd_addr_wc = chunk.wire;
    }
    if (!rd_addr_wc)
        log_error("RD_ADDR input wire not found\n");

    if (!mem_wr_data.is_wire())
        log_error("WR_DATA input wire not found\n");
    auto wr_data_wc = mem_wr_data.as_wire();

    // Check if wr_en_and cell has one of its inputs connected to write address

    // Compare and assign wires
    RTLIL::Wire *rd_addr_w = nullptr;
    RTLIL::Wire *rd_data_w = nullptr;
    RTLIL::Wire *rd_en_w = nullptr;
    RTLIL::Wire *rd_clk_w = nullptr;
    RTLIL::Wire *wr_addr_w = nullptr;
    RTLIL::Wire *wr_data_w = nullptr;

    for (auto wire : pm.module->wires_) {
        if (wire.second == rd_addr_wc)
            rd_addr_w = wire.second;
        if (wire.second == rd_data_wc)
            rd_data_w = wire.second;
        if (wire.second == rd_en_wc)
            rd_en_w = wire.second;
        if (wire.second == clk_wc)
            rd_clk_w = wire.second;
        if (wire.second == wr_addr_wc)
            wr_addr_w = wire.second;
        if (wire.second == wr_data_wc)
            wr_data_w = wire.second;
    }

    if (!rd_addr_w | !rd_data_w | !rd_en_w | !rd_clk_w | !wr_addr_w | !wr_data_w)
        log_error("Match between RAM input wires and memory cell ports not found\n");

    // Set shift output SigSpec as RD_DATA
    cell->setPort(RTLIL::escape_id("RD_DATA"), rd_data_shift_y);

    // Get address and data lines widths
    int rd_addr_width = rd_addr_w->width;
    int wr_addr_width = wr_addr_w->width;
    int wr_data_width = wr_data_w->width;
    int rd_data_width = rd_data_w->width;

    log_debug("Set RD_ADDR_WIDTH = %d, ", rd_addr_width);
    log_debug("WR_ADDR_WIDTH = %d, ", wr_addr_width);
    log_debug("RD_DATA_WIDTH = %d, ", rd_data_width);
    log_debug("WR_DATA_WIDTH = %d\n", wr_data_width);

    // Set address and data lines width parameters used later in techmap
    cell->setParam(RTLIL::escape_id("RD_ADDR_WIDTH"), RTLIL::Const(rd_addr_width));
    cell->setParam(RTLIL::escape_id("RD_DATA_WIDTH"), RTLIL::Const(rd_data_width));
    cell->setParam(RTLIL::escape_id("WR_ADDR_WIDTH"), RTLIL::Const(wr_addr_width));
    cell->setParam(RTLIL::escape_id("WR_DATA_WIDTH"), RTLIL::Const(wr_data_width));

    // Bypass read address shift and connect line straight to memory cell
    auto rd_addr_s = RTLIL::SigSpec(rd_addr_w);
    cell->setPort(RTLIL::escape_id("RD_ADDR"), rd_addr_s);

    if (wr_addr_ff) {
        // Bypass FF on write address line if exists
        // wr_addr_ff_d will not be assigned if wr_addr_ff was not detected earlier
        cell->setPort(RTLIL::escape_id("WR_ADDR"), wr_addr_ff_d);
    } else {
        // When there are no regs on address lines, the clock isn't connected to memory
        // Reconnect the clock
        auto rd_clk_s = RTLIL::SigSpec(rd_clk_w);
        cell->setPort(RTLIL::escape_id("RD_CLK"), rd_clk_s);
    }

    // Bypass FF on Data Output and connect the output straight to RD_DATA port
    cell->setPort(RTLIL::escape_id("RD_DATA"), rd_data_ff_q);

    // Bypass MUX on WRITE ENABLE and connect the output straight to WR_EN port
    cell->setPort(RTLIL::escape_id("WR_EN"), wr_en_mux_s);

    // Connect Read Enable signal to memory cell
    if (!rd_en_w)
        log_error("Wire \\rce not found\n");
    auto rd_en_s = RTLIL::SigSpec(rd_en_w);
    cell->setPort(RTLIL::escape_id("RD_EN"), rd_en_s);

    // Cleanup the module from unused cells
    pm.module->remove(mem);
    pm.module->remove(rd_data_shift);
    pm.module->remove(rd_data_ff);
    pm.module->remove(wr_en_mux);
    if (wr_addr_ff)
        pm.module->remove(wr_addr_ff);
    // Check if detected $and is connected to RD_ADDR
    if ((rd_addr_and_a_wc != rd_addr_w) & (rd_addr_and_b_wc != rd_addr_w))
        log_error("This is not the $and cell we are looking for\n");
    else
        pm.module->remove(rd_addr_and);
}

struct QLBramAsymmetric : public Pass {

    QLBramAsymmetric()
        : Pass("ql_bram_asymmetric",
               "Detects memory cells with asymmetric read and write port widths implemented with shifts and infers custom asymmetric memory cell")
    {
    }

    void help() override
    {
        log("\n");
        log("    ql_bram_asymmetric\n");
        log("\n");
        log("		Detects memory cells with asymmetric read and write port widths implemented with shifts and infers custom asymmetric memory "
            "cell");
        log("\n");
    }

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

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

        int found_cells;
        for (auto module : a_Design->selected_modules()) {
            found_cells = ql_bram_asymmetric_wider_write_pm(module, module->selected_cells())
                            .run_ql_bram_asymmetric_wider_write(test_ql_bram_asymmetric_wider_write);
            log_debug("found %d cells matching for wider write port\n", found_cells);
            found_cells = ql_bram_asymmetric_wider_read_pm(module, module->selected_cells())
                            .run_ql_bram_asymmetric_wider_read(test_ql_bram_asymmetric_wider_read);
            log_debug("found %d cells matching for wider read port\n", found_cells);
        }
    }
} QLBramAsymmetric;

PRIVATE_NAMESPACE_END
