/*
 *  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/log.h"
#include "kernel/register.h"
#include "kernel/sigtools.h"
#include "kernel/consteval.h"
#include "kernel/celltypes.h"
#include "fsmdata.h"
#include <string.h>

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct FsmExpand
{
	RTLIL::Module *module;
	RTLIL::Cell *fsm_cell;
	bool full_mode;

	SigMap assign_map;
	SigSet<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> sig2driver, sig2user;
	CellTypes ct;

	std::set<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> merged_set;
	std::set<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> current_set;
	std::set<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> no_candidate_set;

	bool already_optimized;
	int limit_transitions;

	bool is_cell_merge_candidate(RTLIL::Cell *cell)
	{
		if (full_mode || cell->type == "$_MUX_")
			return true;

		if (cell->type.in("$mux", "$pmux"))
			if (cell->getPort("\\A").size() < 2)
				return true;

		int in_bits = 0;
		RTLIL::SigSpec new_signals;

		if (cell->hasPort("\\A")) {
			in_bits += GetSize(cell->getPort("\\A"));
			new_signals.append(assign_map(cell->getPort("\\A")));
		}

		if (cell->hasPort("\\B")) {
			in_bits += GetSize(cell->getPort("\\B"));
			new_signals.append(assign_map(cell->getPort("\\B")));
		}

		if (cell->hasPort("\\S")) {
			in_bits += GetSize(cell->getPort("\\S"));
			new_signals.append(assign_map(cell->getPort("\\S")));
		}

		if (in_bits > 8)
			return false;

		if (cell->hasPort("\\Y"))
			new_signals.append(assign_map(cell->getPort("\\Y")));

		new_signals.sort_and_unify();
		new_signals.remove_const();

		new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_IN")));
		new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_OUT")));

		if (new_signals.size() > 3)
			return false;

		return true;
	}

	void create_current_set()
	{
		std::vector<RTLIL::Cell*> cell_list;

		for (auto c : sig2driver.find(assign_map(fsm_cell->getPort("\\CTRL_IN"))))
			cell_list.push_back(c);

		for (auto c : sig2user.find(assign_map(fsm_cell->getPort("\\CTRL_OUT"))))
			cell_list.push_back(c);

		current_set.clear();
		for (auto c : cell_list)
		{
			if (merged_set.count(c) > 0 || current_set.count(c) > 0 || no_candidate_set.count(c) > 0)
				continue;
			for (auto &p : c->connections()) {
				if (p.first != "\\A" && p.first != "\\B" && p.first != "\\S" && p.first != "\\Y")
					goto next_cell;
			}
			if (!is_cell_merge_candidate(c)) {
				no_candidate_set.insert(c);
				continue;
			}
			current_set.insert(c);
		next_cell:;
		}
	}

	void optimze_as_needed()
	{
		if (already_optimized)
			return;

		int trans_num = fsm_cell->parameters["\\TRANS_NUM"].as_int();
		if (trans_num > limit_transitions)
		{
			log("  grown transition table to %d entries -> optimize.\n", trans_num);
			FsmData::optimize_fsm(fsm_cell, module);
			already_optimized = true;

			trans_num = fsm_cell->parameters["\\TRANS_NUM"].as_int();
			log("  transition table size after optimizaton: %d\n", trans_num);
			limit_transitions = 16 * trans_num;
		}
	}

	void merge_cell_into_fsm(RTLIL::Cell *cell)
	{
		optimze_as_needed();

		log("  merging %s cell %s.\n", cell->type.c_str(), cell->name.c_str());
		merged_set.insert(cell);
		already_optimized = false;

		RTLIL::SigSpec input_sig, output_sig;

		for (auto &p : cell->connections())
			if (ct.cell_output(cell->type, p.first))
				output_sig.append(assign_map(p.second));
			else
				input_sig.append(assign_map(p.second));
		input_sig.sort_and_unify();
		input_sig.remove_const();

		std::vector<RTLIL::Const> truth_tab;

		for (int i = 0; i < (1 << input_sig.size()); i++) {
			RTLIL::Const in_val(i, input_sig.size());
			RTLIL::SigSpec A, B, S;
			if (cell->hasPort("\\A"))
				A = assign_map(cell->getPort("\\A"));
			if (cell->hasPort("\\B"))
				B = assign_map(cell->getPort("\\B"));
			if (cell->hasPort("\\S"))
				S = assign_map(cell->getPort("\\S"));
			A.replace(input_sig, RTLIL::SigSpec(in_val));
			B.replace(input_sig, RTLIL::SigSpec(in_val));
			S.replace(input_sig, RTLIL::SigSpec(in_val));
			log_assert(A.is_fully_const());
			log_assert(B.is_fully_const());
			log_assert(S.is_fully_const());
			truth_tab.push_back(ct.eval(cell, A.as_const(), B.as_const(), S.as_const()));
		}

		FsmData fsm_data;
		fsm_data.copy_from_cell(fsm_cell);

		fsm_data.num_inputs += input_sig.size();
		RTLIL::SigSpec new_ctrl_in = fsm_cell->getPort("\\CTRL_IN");
		new_ctrl_in.append(input_sig);
		fsm_cell->setPort("\\CTRL_IN", new_ctrl_in);

		fsm_data.num_outputs += output_sig.size();
		RTLIL::SigSpec new_ctrl_out = fsm_cell->getPort("\\CTRL_OUT");
		new_ctrl_out.append(output_sig);
		fsm_cell->setPort("\\CTRL_OUT", new_ctrl_out);

		if (GetSize(input_sig) > 10)
			log_warning("Cell %s.%s (%s) has %d input bits, merging into FSM %s.%s might be problematic.\n",
					log_id(cell->module), log_id(cell), log_id(cell->type),
					GetSize(input_sig), log_id(fsm_cell->module), log_id(fsm_cell));

		if (GetSize(fsm_data.transition_table) > 10000)
			log_warning("Transition table for FSM %s.%s already has %d rows, merging more cells "
					"into this FSM might be problematic.\n", log_id(fsm_cell->module), log_id(fsm_cell),
					GetSize(fsm_data.transition_table));

		std::vector<FsmData::transition_t> new_transition_table;
		for (auto &tr : fsm_data.transition_table) {
			for (int i = 0; i < (1 << input_sig.size()); i++) {
				FsmData::transition_t new_tr = tr;
				RTLIL::Const in_val(i, input_sig.size());
				RTLIL::Const out_val = truth_tab[i];
				RTLIL::SigSpec ctrl_in = new_tr.ctrl_in;
				RTLIL::SigSpec ctrl_out = new_tr.ctrl_out;
				ctrl_in.append(in_val);
				ctrl_out.append(out_val);
				new_tr.ctrl_in = ctrl_in.as_const();
				new_tr.ctrl_out = ctrl_out.as_const();
				new_transition_table.push_back(new_tr);
			}
		}
		fsm_data.transition_table.swap(new_transition_table);
		new_transition_table.clear();

		fsm_data.copy_to_cell(fsm_cell);
	}

	FsmExpand(RTLIL::Cell *cell, RTLIL::Design *design, RTLIL::Module *mod, bool full)
	{
		module = mod;
		fsm_cell = cell;
		full_mode = full;

		assign_map.set(module);
		ct.setup_internals();
		ct.setup_stdcells();

		for (auto &cell_it : module->cells_) {
			RTLIL::Cell *c = cell_it.second;
			if (ct.cell_known(c->type) && design->selected(mod, c))
				for (auto &p : c->connections()) {
					if (ct.cell_output(c->type, p.first))
						sig2driver.insert(assign_map(p.second), c);
					else
						sig2user.insert(assign_map(p.second), c);
				}
		}
	}

	void execute()
	{
		log("\n");
		log("Expanding FSM `%s' from module `%s':\n", fsm_cell->name.c_str(), module->name.c_str());

		already_optimized = false;
		limit_transitions =  16 * fsm_cell->parameters["\\TRANS_NUM"].as_int();

		for (create_current_set(); current_set.size() > 0; create_current_set()) {
			for (auto c : current_set)
				merge_cell_into_fsm(c);
		}

		for (auto c : merged_set)
			module->remove(c);

		if (merged_set.size() > 0 && !already_optimized)
			FsmData::optimize_fsm(fsm_cell, module);

		log("  merged %d cells into FSM.\n", GetSize(merged_set));
	}
};

struct FsmExpandPass : public Pass {
	FsmExpandPass() : Pass("fsm_expand", "expand FSM cells by merging logic into it") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    fsm_expand [-full] [selection]\n");
		log("\n");
		log("The fsm_extract pass is conservative about the cells that belong to a finite\n");
		log("state machine. This pass can be used to merge additional auxiliary gates into\n");
		log("the finite state machine.\n");
		log("\n");
		log("By default, fsm_expand is still a bit conservative regarding merging larger\n");
		log("word-wide cells. Call with -full to consider all cells for merging.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		bool full_mode = false;

		log_header(design, "Executing FSM_EXPAND pass (merging auxiliary logic into FSMs).\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-full") {
				full_mode = true;
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		for (auto &mod_it : design->modules_) {
			if (!design->selected(mod_it.second))
				continue;
			std::vector<RTLIL::Cell*> fsm_cells;
			for (auto &cell_it : mod_it.second->cells_)
				if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
					fsm_cells.push_back(cell_it.second);
			for (auto c : fsm_cells) {
				FsmExpand fsm_expand(c, design, mod_it.second, full_mode);
				fsm_expand.execute();
			}
		}
	}
} FsmExpandPass;

PRIVATE_NAMESPACE_END
