/*
 *  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/log.h"
#include "kernel/sigtools.h"
#include <stdlib.h>
#include <stdio.h>
#include <set>

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct SubmodWorker
{
	CellTypes ct;
	RTLIL::Design *design;
	RTLIL::Module *module;
	SigMap sigmap;
	std::map<RTLIL::SigBit, RTLIL::SigBit> replace_const;

	bool copy_mode;
	bool hidden_mode;
	std::string opt_name;

	struct SubModule
	{
		std::string name, full_name;
		std::set<RTLIL::Cell*> cells;
	};

	std::map<std::string, SubModule> submodules;

	struct wire_flags_t {
		RTLIL::Wire *new_wire;
		RTLIL::Const is_int_driven;
		bool is_int_used, is_ext_driven, is_ext_used;
		wire_flags_t(RTLIL::Wire* wire) : new_wire(NULL), is_int_driven(State::S0, GetSize(wire)), is_int_used(false), is_ext_driven(false), is_ext_used(false) { }
	};
	std::map<RTLIL::Wire*, wire_flags_t> wire_flags;
	bool flag_found_something;

	void flag_wire(RTLIL::Wire *wire, bool create, bool /*set_int_driven*/, bool set_int_used, bool set_ext_driven, bool set_ext_used)
	{
		if (wire_flags.count(wire) == 0) {
			if (!create)
				return;
			wire_flags.emplace(wire, wire_flags_t(wire));
		}
		//if (set_int_driven)
		//	wire_flags[wire].is_int_driven = true;
		if (set_int_used)
			wire_flags.at(wire).is_int_used = true;
		if (set_ext_driven)
			wire_flags.at(wire).is_ext_driven = true;
		if (set_ext_used)
			wire_flags.at(wire).is_ext_used = true;
		flag_found_something = true;
	}

	void flag_signal(const RTLIL::SigSpec &sig, bool create, bool set_int_driven, bool set_int_used, bool set_ext_driven, bool set_ext_used)
	{
		for (auto &c : sig.chunks())
			if (c.wire != NULL) {
				flag_wire(c.wire, create, set_int_driven, set_int_used, set_ext_driven, set_ext_used);
				if (set_int_driven)
					for (int i = c.offset; i < c.offset+c.width; i++) {
						wire_flags.at(c.wire).is_int_driven[i] = State::S1;
						flag_found_something = true;
					}
			}
	}

	void handle_submodule(SubModule &submod)
	{
		log("Creating submodule %s (%s) of module %s.\n", submod.name.c_str(), submod.full_name.c_str(), module->name.c_str());

		wire_flags.clear();
		for (RTLIL::Cell *cell : submod.cells) {
			if (ct.cell_known(cell->type)) {
				for (auto &conn : cell->connections())
					flag_signal(conn.second, true, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first), false, false);
			} else {
				log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str());
				for (auto &conn : cell->connections())
					flag_signal(conn.second, true, true, true, false, false);
			}
		}
		for (auto &it : module->cells_) {
			RTLIL::Cell *cell = it.second;
			if (submod.cells.count(cell) > 0)
				continue;
			if (ct.cell_known(cell->type)) {
				for (auto &conn : cell->connections())
					flag_signal(conn.second, false, false, false, ct.cell_output(cell->type, conn.first), ct.cell_input(cell->type, conn.first));
			} else {
				flag_found_something = false;
				for (auto &conn : cell->connections())
					flag_signal(conn.second, false, false, false, true, true);
				if (flag_found_something)
					log_warning("Port directions for cell %s (%s) are unknown. Assuming inout for all ports.\n", cell->name.c_str(), cell->type.c_str());
			}
		}

		RTLIL::Module *new_mod = new RTLIL::Module;
		new_mod->name = submod.full_name;
		design->add(new_mod);
		int auto_name_counter = 1;

		std::set<RTLIL::IdString> all_wire_names;
		for (auto &it : wire_flags) {
			all_wire_names.insert(it.first->name);
		}

		for (auto &it : wire_flags)
		{
			RTLIL::Wire *wire = it.first;
			wire_flags_t &flags = it.second;

			if (wire->port_input)
				flags.is_ext_driven = true;
			if (wire->port_output)
				flags.is_ext_used = true;
			else {
				auto sig = sigmap(wire);
				for (auto c : sig.chunks())
					if (c.wire->port_output) {
						flags.is_ext_used = true;
						break;
					}
			}

			bool new_wire_port_input = false;
			bool new_wire_port_output = false;

			if (!flags.is_int_driven.is_fully_zero() && flags.is_ext_used)
				new_wire_port_output = true;
			if (flags.is_ext_driven && flags.is_int_used)
				new_wire_port_input = true;

			if (!flags.is_int_driven.is_fully_zero() && flags.is_ext_driven)
				new_wire_port_input = true, new_wire_port_output = true;

			std::string new_wire_name = wire->name.str();
			if (new_wire_port_input || new_wire_port_output) {
				if (new_wire_name[0] == '$')
					while (1) {
						std::string next_wire_name = stringf("%s\\n%d", hidden_mode ? "$submod" : "", auto_name_counter++);
						if (all_wire_names.count(next_wire_name) == 0) {
							all_wire_names.insert(next_wire_name);
							new_wire_name = next_wire_name;
							break;
						}
					}
				else if (hidden_mode)
					new_wire_name = stringf("$submod%s", new_wire_name.c_str());
			}

			RTLIL::Wire *new_wire = new_mod->addWire(new_wire_name, wire->width);
			new_wire->port_input = new_wire_port_input;
			new_wire->port_output = new_wire_port_output;
			new_wire->start_offset = wire->start_offset;
			new_wire->attributes = wire->attributes;
			if (new_wire->port_output) {
				new_wire->attributes.erase(ID(init));
				auto sig = sigmap(wire);
				for (int i = 0; i < GetSize(sig); i++) {
					if (flags.is_int_driven[i] == State::S0)
						continue;
					if (!sig[i].wire)
						continue;
					auto it = sig[i].wire->attributes.find(ID(init));
					if (it != sig[i].wire->attributes.end()) {
						auto jt = new_wire->attributes.insert(std::make_pair(ID(init), Const(State::Sx, GetSize(sig)))).first;
						jt->second[i] = it->second[sig[i].offset];
						it->second[sig[i].offset] = State::Sx;
					}
				}
			}

			if (new_wire->port_input && new_wire->port_output)
				log("  signal %s: inout %s\n", wire->name.c_str(), new_wire->name.c_str());
			else if (new_wire->port_input)
				log("  signal %s: input %s\n", wire->name.c_str(), new_wire->name.c_str());
			else if (new_wire->port_output)
				log("  signal %s: output %s\n", wire->name.c_str(), new_wire->name.c_str());
			else
				log("  signal %s: internal\n", wire->name.c_str());

			flags.new_wire = new_wire;
		}

		new_mod->fixup_ports();
		ct.setup_module(new_mod);

		for (RTLIL::Cell *cell : submod.cells) {
			RTLIL::Cell *new_cell = new_mod->addCell(cell->name, cell);
			for (auto &conn : new_cell->connections_)
				for (auto &bit : conn.second)
					if (bit.wire != NULL) {
						log_assert(wire_flags.count(bit.wire) > 0);
						bit.wire = wire_flags.at(bit.wire).new_wire;
					}
			log("  cell %s (%s)\n", new_cell->name.c_str(), new_cell->type.c_str());
			if (!copy_mode)
				module->remove(cell);
		}
		submod.cells.clear();

		if (!copy_mode) {
			RTLIL::Cell *new_cell = module->addCell(submod.full_name, submod.full_name);
			for (auto &it : wire_flags)
			{
				RTLIL::SigSpec old_sig = sigmap(it.first);
				RTLIL::Wire *new_wire = it.second.new_wire;
				if (new_wire->port_id > 0) {
					// Prevents "ERROR: Mismatch in directionality ..." when flattening
					if (new_wire->port_output)
						old_sig.replace(replace_const);
					new_cell->setPort(new_wire->name, old_sig);
				}
			}
		}
	}

	SubmodWorker(RTLIL::Design *design, RTLIL::Module *module, bool copy_mode = false, bool hidden_mode = false, std::string opt_name = std::string()) :
			design(design), module(module), sigmap(module), copy_mode(copy_mode), hidden_mode(hidden_mode), opt_name(opt_name)
	{
		if (!design->selected_whole_module(module->name) && opt_name.empty())
			return;

		if (module->processes.size() > 0) {
			log("Skipping module %s as it contains processes (run 'proc' pass first).\n", module->name.c_str());
			return;
		}

		if (module->memories.size() > 0) {
			log("Skipping module %s as it contains memories (run 'memory' pass first).\n", module->name.c_str());
			return;
		}

		ct.setup_internals();
		ct.setup_internals_mem();
		ct.setup_stdcells();
		ct.setup_stdcells_mem();
		ct.setup_design(design);

		for (auto port : module->ports) {
			auto wire = module->wire(port);
			if (wire->port_output)
				sigmap.add(wire);
		}
		auto wire = module->addWire(NEW_ID);
		replace_const.emplace(State::S0, wire);
		replace_const.emplace(State::S1, wire);
		replace_const.emplace(State::Sx, wire);
		replace_const.emplace(State::Sz, wire);

		if (opt_name.empty())
		{
			for (auto &it : module->wires_)
				it.second->attributes.erase("\\submod");

			for (auto &it : module->cells_)
			{
				RTLIL::Cell *cell = it.second;
				if (cell->attributes.count("\\submod") == 0 || cell->attributes["\\submod"].bits.size() == 0) {
					cell->attributes.erase("\\submod");
					continue;
				}

				std::string submod_str = cell->attributes["\\submod"].decode_string();
				cell->attributes.erase("\\submod");

				if (submodules.count(submod_str) == 0) {
					submodules[submod_str].name = submod_str;
					submodules[submod_str].full_name = module->name.str() + "_" + submod_str;
					while (design->modules_.count(submodules[submod_str].full_name) != 0 ||
							module->count_id(submodules[submod_str].full_name) != 0)
						submodules[submod_str].full_name += "_";
				}

				submodules[submod_str].cells.insert(cell);
			}
		}
		else
		{
			for (auto &it : module->cells_)
			{
				RTLIL::Cell *cell = it.second;
				if (!design->selected(module, cell))
					continue;
				submodules[opt_name].name = opt_name;
				submodules[opt_name].full_name = RTLIL::escape_id(opt_name);
				submodules[opt_name].cells.insert(cell);
			}

			if (submodules.size() == 0)
				log("Nothing selected -> do nothing.\n");
		}

		for (auto &it : submodules)
			handle_submodule(it.second);
	}
};

struct SubmodPass : public Pass {
	SubmodPass() : Pass("submod", "moving part of a module to a new submodule") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    submod [options] [selection]\n");
		log("\n");
		log("This pass identifies all cells with the 'submod' attribute and moves them to\n");
		log("a newly created module. The value of the attribute is used as name for the\n");
		log("cell that replaces the group of cells with the same attribute value.\n");
		log("\n");
		log("This pass can be used to create a design hierarchy in flat design. This can\n");
		log("be useful for analyzing or reverse-engineering a design.\n");
		log("\n");
		log("This pass only operates on completely selected modules with no processes\n");
		log("or memories.\n");
		log("\n");
		log("    -copy\n");
		log("        by default the cells are 'moved' from the source module and the source\n");
		log("        module will use an instance of the new module after this command is\n");
		log("        finished. call with -copy to not modify the source module.\n");
		log("\n");
		log("    -name <name>\n");
		log("        don't use the 'submod' attribute but instead use the selection. only\n");
		log("        objects from one module might be selected. the value of the -name option\n");
		log("        is used as the value of the 'submod' attribute instead.\n");
		log("\n");
		log("    -hidden\n");
		log("        instead of creating submodule ports with public names, create ports with\n");
		log("        private names so that a subsequent 'flatten; clean' call will restore the\n");
		log("        original module with original public names.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		log_header(design, "Executing SUBMOD pass (moving cells to submodules as requested).\n");
		log_push();

		std::string opt_name;
		bool copy_mode = false;
		bool hidden_mode = false;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-name" && argidx+1 < args.size()) {
				opt_name = args[++argidx];
				continue;
			}
			if (args[argidx] == "-copy") {
				copy_mode = true;
				continue;
			}
			if (args[argidx] == "-hidden") {
				hidden_mode = true;
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (opt_name.empty())
		{
			Pass::call(design, "opt_clean");
			log_header(design, "Continuing SUBMOD pass.\n");

			std::set<RTLIL::IdString> handled_modules;

			bool did_something = true;
			while (did_something) {
				did_something = false;
				std::vector<RTLIL::IdString> queued_modules;
				for (auto &mod_it : design->modules_)
					if (handled_modules.count(mod_it.first) == 0 && design->selected_whole_module(mod_it.first))
						queued_modules.push_back(mod_it.first);
				for (auto &modname : queued_modules)
					if (design->modules_.count(modname) != 0) {
						SubmodWorker worker(design, design->modules_[modname], copy_mode, hidden_mode);
						handled_modules.insert(modname);
						did_something = true;
					}
			}

			Pass::call(design, "opt_clean");
		}
		else
		{
			RTLIL::Module *module = NULL;
			for (auto &mod_it : design->modules_) {
				if (!design->selected_module(mod_it.first))
					continue;
				if (module != NULL)
					log_cmd_error("More than one module selected: %s %s\n", module->name.c_str(), mod_it.first.c_str());
				module = mod_it.second;
			}
			if (module == NULL)
				log("Nothing selected -> do nothing.\n");
			else {
				Pass::call_on_module(design, module, "opt_clean");
				log_header(design, "Continuing SUBMOD pass.\n");
				SubmodWorker worker(design, module, copy_mode, hidden_mode, opt_name);
			}
		}

		log_pop();
	}
} SubmodPass;

PRIVATE_NAMESPACE_END
