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

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct SpliceWorker
{
	RTLIL::Design *design;
	RTLIL::Module *module;

	bool sel_by_cell;
	bool sel_by_wire;
	bool sel_any_bit;
	bool no_outputs;
	bool do_wires;

	std::set<RTLIL::IdString> ports;
	std::set<RTLIL::IdString> no_ports;

	CellTypes ct;
	SigMap sigmap;

	std::vector<RTLIL::SigBit> driven_bits;
	std::map<RTLIL::SigBit, int> driven_bits_map;

	std::set<RTLIL::SigSpec> driven_chunks;
	std::map<RTLIL::SigSpec, RTLIL::SigSpec> spliced_signals_cache;
	std::map<RTLIL::SigSpec, RTLIL::SigSpec> sliced_signals_cache;

	SpliceWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module), ct(design), sigmap(module)
	{
	}

	RTLIL::SigSpec get_sliced_signal(RTLIL::SigSpec sig)
	{
		if (sig.size() == 0 || sig.is_fully_const())
			return sig;

		if (sliced_signals_cache.count(sig))
			return sliced_signals_cache.at(sig);

		int offset = 0;
		int p = driven_bits_map.at(sig.extract(0, 1).as_bit()) - 1;
		while (driven_bits.at(p) != RTLIL::State::Sm)
			p--, offset++;

		RTLIL::SigSpec sig_a;
		for (p++; driven_bits.at(p) != RTLIL::State::Sm; p++)
			sig_a.append(driven_bits.at(p));

		RTLIL::SigSpec new_sig = sig;

		if (sig_a.size() != sig.size()) {
			RTLIL::Cell *cell = module->addCell(NEW_ID, "$slice");
			cell->parameters["\\OFFSET"] = offset;
			cell->parameters["\\A_WIDTH"] = sig_a.size();
			cell->parameters["\\Y_WIDTH"] = sig.size();
			cell->setPort("\\A", sig_a);
			cell->setPort("\\Y", module->addWire(NEW_ID, sig.size()));
			new_sig = cell->getPort("\\Y");
		}

		sliced_signals_cache[sig] = new_sig;

		return new_sig;
	}

	RTLIL::SigSpec get_spliced_signal(RTLIL::SigSpec sig)
	{
		if (sig.size() == 0 || sig.is_fully_const())
			return sig;

		if (spliced_signals_cache.count(sig))
			return spliced_signals_cache.at(sig);

		int last_bit = -1;
		std::vector<RTLIL::SigSpec> chunks;

		for (auto &bit : sig.to_sigbit_vector())
		{
			if (bit.wire == NULL)
			{
				if (last_bit == 0)
					chunks.back().append(bit);
				else
					chunks.push_back(bit);
				last_bit = 0;
				continue;
			}

			if (driven_bits_map.count(bit))
			{
				int this_bit = driven_bits_map.at(bit);
				if (last_bit+1 == this_bit)
					chunks.back().append(bit);
				else
					chunks.push_back(bit);
				last_bit = this_bit;
				continue;
			}

			log("  Failed to generate spliced signal %s.\n", log_signal(sig));
			spliced_signals_cache[sig] = sig;
			return sig;
		}


		RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front());
		for (size_t i = 1; i < chunks.size(); i++) {
			RTLIL::SigSpec sig2 = get_sliced_signal(chunks[i]);
			RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat");
			cell->parameters["\\A_WIDTH"] = new_sig.size();
			cell->parameters["\\B_WIDTH"] = sig2.size();
			cell->setPort("\\A", new_sig);
			cell->setPort("\\B", sig2);
			cell->setPort("\\Y", module->addWire(NEW_ID, new_sig.size() + sig2.size()));
			new_sig = cell->getPort("\\Y");
		}

		spliced_signals_cache[sig] = new_sig;

		log("  Created spliced signal: %s -> %s\n", log_signal(sig), log_signal(new_sig));
		return new_sig;
	}

	void run()
	{
		log("Splicing signals in module %s:\n", RTLIL::id2cstr(module->name));

		driven_bits.push_back(RTLIL::State::Sm);
		driven_bits.push_back(RTLIL::State::Sm);

		for (auto &it : module->wires_)
			if (it.second->port_input) {
				RTLIL::SigSpec sig = sigmap(it.second);
				driven_chunks.insert(sig);
				for (auto &bit : sig.to_sigbit_vector())
					driven_bits.push_back(bit);
				driven_bits.push_back(RTLIL::State::Sm);
			}

		for (auto &it : module->cells_)
		for (auto &conn : it.second->connections())
			if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first)) {
				RTLIL::SigSpec sig = sigmap(conn.second);
				driven_chunks.insert(sig);
				for (auto &bit : sig.to_sigbit_vector())
					driven_bits.push_back(bit);
				driven_bits.push_back(RTLIL::State::Sm);
			}

		driven_bits.push_back(RTLIL::State::Sm);

		for (size_t i = 0; i < driven_bits.size(); i++)
			driven_bits_map[driven_bits[i]] = i;

		SigPool selected_bits;
		if (!sel_by_cell)
			for (auto &it : module->wires_)
				if (design->selected(module, it.second))
					selected_bits.add(sigmap(it.second));

		std::vector<Cell*> mod_cells = module->cells();

		for (auto cell : mod_cells) {
			if (!sel_by_wire && !design->selected(module, cell))
				continue;
			for (auto &conn : cell->connections_)
				if (ct.cell_input(cell->type, conn.first)) {
					if (ports.size() > 0 && !ports.count(conn.first))
						continue;
					if (no_ports.size() > 0 && no_ports.count(conn.first))
						continue;
					RTLIL::SigSpec sig = sigmap(conn.second);
					if (!sel_by_cell) {
						if (!sel_any_bit && !selected_bits.check_all(sig))
							continue;
						if (sel_any_bit && !selected_bits.check_any(sig))
							continue;
					}
					if (driven_chunks.count(sig) > 0)
						continue;
					conn.second = get_spliced_signal(sig);
				}
		}

		std::vector<std::pair<RTLIL::Wire*, RTLIL::SigSpec>> rework_wires;
		std::vector<Wire*> mod_wires = module->wires();

		for (auto wire : mod_wires)
			if ((!no_outputs && wire->port_output) || (do_wires && wire->name[0] == '\\')) {
				if (!design->selected(module, wire))
					continue;
				RTLIL::SigSpec sig = sigmap(wire);
				if (driven_chunks.count(sig) > 0)
					continue;
				RTLIL::SigSpec new_sig = get_spliced_signal(sig);
				if (new_sig != sig)
					rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(wire, new_sig));
			} else
			if (!wire->port_input) {
				RTLIL::SigSpec sig = sigmap(wire);
				if (spliced_signals_cache.count(sig) && spliced_signals_cache.at(sig) != sig)
					rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(wire, spliced_signals_cache.at(sig)));
				else if (sliced_signals_cache.count(sig) && sliced_signals_cache.at(sig) != sig)
					rework_wires.push_back(std::pair<RTLIL::Wire*, RTLIL::SigSpec>(wire, sliced_signals_cache.at(sig)));
			}

		for (auto &it : rework_wires)
		{
			RTLIL::IdString orig_name = it.first->name;
			module->rename(it.first, NEW_ID);

			RTLIL::Wire *new_port = module->addWire(orig_name, it.first);
			it.first->port_id = 0;
			it.first->port_input = false;
			it.first->port_output = false;

			module->connect(RTLIL::SigSig(new_port, it.second));
		}
	}
};

struct SplicePass : public Pass {
	SplicePass() : Pass("splice", "create explicit splicing cells") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    splice [options] [selection]\n");
		log("\n");
		log("This command adds $slice and $concat cells to the design to make the splicing\n");
		log("of multi-bit signals explicit. This for example is useful for coarse grain\n");
		log("synthesis, where dedicated hardware is needed to splice signals.\n");
		log("\n");
		log("    -sel_by_cell\n");
		log("        only select the cell ports to rewire by the cell. if the selection\n");
		log("        contains a cell, than all cell inputs are rewired, if necessary.\n");
		log("\n");
		log("    -sel_by_wire\n");
		log("        only select the cell ports to rewire by the wire. if the selection\n");
		log("        contains a wire, than all cell ports driven by this wire are wired,\n");
		log("        if necessary.\n");
		log("\n");
		log("    -sel_any_bit\n");
		log("        it is sufficient if the driver of any bit of a cell port is selected.\n");
		log("        by default all bits must be selected.\n");
		log("\n");
		log("    -wires\n");
		log("        also add $slice and $concat cells to drive otherwise unused wires.\n");
		log("\n");
		log("    -no_outputs\n");
		log("        do not rewire selected module outputs.\n");
		log("\n");
		log("    -port <name>\n");
		log("        only rewire cell ports with the specified name. can be used multiple\n");
		log("        times. implies -no_output.\n");
		log("\n");
		log("    -no_port <name>\n");
		log("        do not rewire cell ports with the specified name. can be used multiple\n");
		log("        times. can not be combined with -port <name>.\n");
		log("\n");
		log("By default selected output wires and all cell ports of selected cells driven\n");
		log("by selected wires are rewired.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		bool sel_by_cell = false;
		bool sel_by_wire = false;
		bool sel_any_bit = false;
		bool no_outputs = false;
		bool do_wires = false;
		std::set<RTLIL::IdString> ports, no_ports;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-sel_by_cell") {
				sel_by_cell = true;
				continue;
			}
			if (args[argidx] == "-sel_by_wire") {
				sel_by_wire = true;
				continue;
			}
			if (args[argidx] == "-sel_any_bit") {
				sel_any_bit = true;
				continue;
			}
			if (args[argidx] == "-wires") {
				do_wires = true;
				continue;
			}
			if (args[argidx] == "-no_outputs") {
				no_outputs = true;
				continue;
			}
			if (args[argidx] == "-port" && argidx+1 < args.size()) {
				ports.insert(RTLIL::escape_id(args[++argidx]));
				no_outputs = true;
				continue;
			}
			if (args[argidx] == "-no_port" && argidx+1 < args.size()) {
				no_ports.insert(RTLIL::escape_id(args[++argidx]));
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (sel_by_cell && sel_by_wire)
			log_cmd_error("The options -sel_by_cell and -sel_by_wire are exclusive!\n");

		if (sel_by_cell && sel_any_bit)
			log_cmd_error("The options -sel_by_cell and -sel_any_bit are exclusive!\n");

		if (!ports.empty() && !no_ports.empty())
			log_cmd_error("The options -port and -no_port are exclusive!\n");

		log_header(design, "Executing SPLICE pass (creating cells for signal splicing).\n");

		for (auto &mod_it : design->modules_)
		{
			if (!design->selected(mod_it.second))
				continue;

			if (mod_it.second->processes.size()) {
				log("Skipping module %s as it contains processes.\n", mod_it.second->name.c_str());
				continue;
			}

			SpliceWorker worker(design, mod_it.second);
			worker.sel_by_cell = sel_by_cell;
			worker.sel_by_wire = sel_by_wire;
			worker.sel_any_bit = sel_any_bit;
			worker.no_outputs = no_outputs;
			worker.do_wires = do_wires;
			worker.ports = ports;
			worker.no_ports = no_ports;
			worker.run();
		}
	}
} SplicePass;

PRIVATE_NAMESPACE_END
