/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  Copyright (C) 2020  The Symbiflow Authors
 *
 *  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/register.h"
#include "kernel/rtlil.h"
#include "kernel/sigtools.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

/// A structure representing a pin
struct Pin {
  RTLIL::Cell *cell;    /// Cell pointer
  RTLIL::IdString port; /// Cell port name
  int bit;              /// Port bit index

  Pin(RTLIL::Cell *_cell, const RTLIL::IdString &_port, int _bit = 0)
      : cell(_cell), port(_port), bit(_bit) {}

  Pin(const Pin &ref) = default;

  unsigned int hash() const {
    if (cell == nullptr) {
      return mkhash_add(port.hash(), bit);
    } else {
      return mkhash_add(mkhash(cell->hash(), port.hash()), bit);
    }
  };
};

bool operator==(const Pin &lhs, const Pin &rhs) {
  return (lhs.cell == rhs.cell) && (lhs.port == rhs.port) &&
         (lhs.bit == rhs.bit);
}

struct IntegrateInv : public Pass {

  /// Temporary SigBit to SigBit helper map.
  SigMap m_SigMap;
  /// Map of SigBit objects to inverter cells.
  dict<RTLIL::SigBit, RTLIL::Cell *> m_InvMap;
  /// Map of inverter cells that can potentially be integrated and invertable
  /// pins that they are connected to
  dict<RTLIL::Cell *, pool<Pin>> m_Inverters;
  /// Map of invertable pins and names of parameters controlling inversions
  dict<Pin, RTLIL::IdString> m_InvParams;

  IntegrateInv()
      : Pass("integrateinv", "Integrates inverters ($_NOT_ cells) into ports "
                             "with 'invertible_pin' attribute set") {}

  void help() override {
    log("\n");
    log("    integrateinv [selection]");
    log("\n");
    log("This pass integrates inverters into cells that have ports with the\n");
    log("'invertible_pin' attribute set. The attribute should contain the name\n");
    log("of a parameter controlling the inversion.\n");
    log("\n");
    log("This pass is essentially the opposite of the 'extractinv' pass.\n");
    log("\n");
  }

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

    extra_args(a_Args, 1, a_Design);

    // Process modules
    for (auto module : a_Design->selected_modules()) {

      // Setup the SigMap
      m_SigMap.clear();
      m_SigMap.set(module);

      m_Inverters.clear();
      m_InvParams.clear();

      // Setup inverter map
      buildInverterMap(module);

      // Identify inverters that can be integrated and assign them with
      // lists of cells and ports to integrate with
      for (auto cell : module->selected_cells()) {
        collectInverters(cell);
      }

      // Integrate inverters
      integrateInverters();
    }

    // Clear maps
    m_SigMap.clear();

    m_InvMap.clear();
    m_Inverters.clear();
    m_InvParams.clear();
  }

  void buildInverterMap(RTLIL::Module *a_Module) {
    m_InvMap.clear();

    for (auto cell : a_Module->cells()) {

      // Skip non-inverters
      if (cell->type != RTLIL::escape_id("$_NOT_")) {
        continue;
      }

      // Get output connection
      auto sigspec = cell->getPort(RTLIL::escape_id("Y"));
      auto sigbit = m_SigMap(sigspec.bits().at(0));

      // Store
      log_assert(m_InvMap.count(sigbit) == 0);
      m_InvMap[sigbit] = cell;
    }
  }

  void collectInverters(RTLIL::Cell *a_Cell) {
    auto module = a_Cell->module;
    auto design = module->design;

    for (auto conn : a_Cell->connections()) {
      auto port = conn.first;
      auto sigspec = conn.second;

      // Consider only inputs.
      if (!a_Cell->input(port)) {
        continue;
      }

      // Get the cell module
      auto cellModule = design->module(a_Cell->type);
      if (!cellModule) {
        continue;
      }

      // Get wire.
      auto wire = cellModule->wire(port);
      if (!wire) {
        continue;
      }

      // Check if the pin has an embedded inverter.
      auto it = wire->attributes.find(ID::invertible_pin);
      if (it == wire->attributes.end()) {
        continue;
      }

      // Decode the parameter name.
      RTLIL::IdString paramName = RTLIL::escape_id(it->second.decode_string());

      // Look for connected inverters
      auto sigbits = sigspec.bits();
      for (size_t bit = 0; bit < sigbits.size(); ++bit) {

        auto sigbit = sigbits[bit];
        if (!sigbit.wire) {
          continue;
        }

        sigbit = m_SigMap(sigbit);

        // Get the inverter if any
        if (!m_InvMap.count(sigbit)) {
          continue;
        }
        auto inv = m_InvMap.at(sigbit);

        // Save the inverter pin and the parameter name
        auto pin = Pin(a_Cell, port, bit);

        auto &list = m_Inverters[inv];
        list.insert(pin);

        log_assert(m_InvParams.count(pin) == 0);
        m_InvParams[pin] = paramName;
      }
    }
  }

  void integrateInverters() {

    for (auto it : m_Inverters) {
      auto inv = it.first;
      auto pins = it.second;

      // List all sinks of the inverter
      auto sinks = getSinksForDriver(Pin(inv, RTLIL::escape_id("Y")));

      // If the inverter drives only invertable pins then integrate it
      if (sinks == pins) {
        log("Integrating inverter %s into:\n", log_id(inv->name));

        // Integrate into each pin
        for (auto pin : pins) {
          log_assert(pin.cell != nullptr);
          log(" %s.%s[%d]\n", log_id(pin.cell->name), log_id(pin.port),
              pin.bit);

          // Change the connection
          auto sigspec = pin.cell->getPort(pin.port);
          auto sigbits = sigspec.bits();

          log_assert((size_t)pin.bit < sigbits.size());
          sigbits[pin.bit] =
              RTLIL::SigBit(inv->getPort(RTLIL::escape_id("A"))[0]);
          pin.cell->setPort(pin.port, RTLIL::SigSpec(sigbits));

          // Get the control parameter
          log_assert(m_InvParams.count(pin) != 0);
          auto paramName = m_InvParams[pin];

          RTLIL::Const invMask;
          auto param = pin.cell->parameters.find(paramName);
          if (param == pin.cell->parameters.end()) {
            invMask = RTLIL::Const(0, sigspec.size());
          } else {
            invMask = RTLIL::Const(param->second);
          }

          // Check width.
          if (invMask.size() != sigspec.size()) {
            log_error("The inversion parameter needs to be the same width as "
                      "the port (%s port %s parameter %s)",
                      log_id(pin.cell->name), log_id(pin.port),
                      log_id(paramName));
          }

          // Toggle bit in the control parameter bitmask
          if (invMask[pin.bit] == RTLIL::State::S0) {
            invMask[pin.bit] = RTLIL::State::S1;
          } else if (invMask[pin.bit] == RTLIL::State::S1) {
            invMask[pin.bit] = RTLIL::State::S0;
          } else {
            log_error("The inversion parameter must contain only 0s and 1s (%s "
                      "parameter %s)\n",
                      log_id(pin.cell->name), log_id(paramName));
          }

          // Set the parameter back
          pin.cell->setParam(paramName, invMask);
        }

        // Remove the inverter
        inv->module->remove(inv);
      }
    }
  }

  pool<Pin> getSinksForDriver(const Pin &a_Driver) {
    auto module = a_Driver.cell->module;
    pool<Pin> sinks;

    // The driver has to be an output pin
    if (!a_Driver.cell->output(a_Driver.port)) {
      return sinks;
    }

    // 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()) {
      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(Pin(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(Pin(nullptr, sigbit.wire->name, bit));
        }
      }
    }

    return sinks;
  }

} IntegrateInv;

PRIVATE_NAMESPACE_END
