/*
 *  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.
 *
 */

#ifndef FSMDATA_H
#define FSMDATA_H

#include "kernel/yosys.h"

YOSYS_NAMESPACE_BEGIN

struct FsmData
{
	int num_inputs, num_outputs, state_bits, reset_state;
	struct transition_t { int state_in, state_out; RTLIL::Const ctrl_in, ctrl_out; };
	std::vector<transition_t> transition_table;
	std::vector<RTLIL::Const> state_table;

	void copy_to_cell(RTLIL::Cell *cell)
	{
		cell->parameters["\\CTRL_IN_WIDTH"] = RTLIL::Const(num_inputs);
		cell->parameters["\\CTRL_OUT_WIDTH"] = RTLIL::Const(num_outputs);

		int state_num_log2 = 0;
		for (int i = state_table.size(); i > 0; i = i >> 1)
			state_num_log2++;
		state_num_log2 = max(state_num_log2, 1);

		cell->parameters["\\STATE_BITS"] = RTLIL::Const(state_bits);
		cell->parameters["\\STATE_NUM"] = RTLIL::Const(state_table.size());
		cell->parameters["\\STATE_NUM_LOG2"] = RTLIL::Const(state_num_log2);
		cell->parameters["\\STATE_RST"] = RTLIL::Const(reset_state);
		cell->parameters["\\STATE_TABLE"] = RTLIL::Const();

		for (int i = 0; i < int(state_table.size()); i++) {
			std::vector<RTLIL::State> &bits_table = cell->parameters["\\STATE_TABLE"].bits;
			std::vector<RTLIL::State> &bits_state = state_table[i].bits;
			bits_table.insert(bits_table.end(), bits_state.begin(), bits_state.end());
		}

		cell->parameters["\\TRANS_NUM"] = RTLIL::Const(transition_table.size());
		cell->parameters["\\TRANS_TABLE"] = RTLIL::Const();
		for (int i = 0; i < int(transition_table.size()); i++)
		{
			std::vector<RTLIL::State> &bits_table = cell->parameters["\\TRANS_TABLE"].bits;
			transition_t &tr = transition_table[i];

			RTLIL::Const const_state_in = RTLIL::Const(tr.state_in, state_num_log2);
			RTLIL::Const const_state_out = RTLIL::Const(tr.state_out, state_num_log2);
			std::vector<RTLIL::State> &bits_state_in = const_state_in.bits;
			std::vector<RTLIL::State> &bits_state_out = const_state_out.bits;

			std::vector<RTLIL::State> &bits_ctrl_in = tr.ctrl_in.bits;
			std::vector<RTLIL::State> &bits_ctrl_out = tr.ctrl_out.bits;

			// append lsb first
			bits_table.insert(bits_table.end(), bits_ctrl_out.begin(), bits_ctrl_out.end());
			bits_table.insert(bits_table.end(), bits_state_out.begin(), bits_state_out.end());
			bits_table.insert(bits_table.end(), bits_ctrl_in.begin(), bits_ctrl_in.end());
			bits_table.insert(bits_table.end(), bits_state_in.begin(), bits_state_in.end());
		}
	}

	void copy_from_cell(RTLIL::Cell *cell)
	{
		num_inputs = cell->parameters["\\CTRL_IN_WIDTH"].as_int();
		num_outputs = cell->parameters["\\CTRL_OUT_WIDTH"].as_int();

		state_bits = cell->parameters["\\STATE_BITS"].as_int();
		reset_state = cell->parameters["\\STATE_RST"].as_int();

		int state_num = cell->parameters["\\STATE_NUM"].as_int();
		int state_num_log2 = cell->parameters["\\STATE_NUM_LOG2"].as_int();
		int trans_num = cell->parameters["\\TRANS_NUM"].as_int();

		if (reset_state < 0 || reset_state >= state_num)
			reset_state = -1;

		RTLIL::Const state_table = cell->parameters["\\STATE_TABLE"];
		RTLIL::Const trans_table = cell->parameters["\\TRANS_TABLE"];

		for (int i = 0; i < state_num; i++) {
			RTLIL::Const state_code;
			int off_begin = i*state_bits, off_end = off_begin + state_bits;
			state_code.bits.insert(state_code.bits.begin(), state_table.bits.begin()+off_begin, state_table.bits.begin()+off_end);
			this->state_table.push_back(state_code);
		}

		for (int i = 0; i < trans_num; i++)
		{
			auto off_ctrl_out = trans_table.bits.begin() + i*(num_inputs+num_outputs+2*state_num_log2);
			auto off_state_out = off_ctrl_out + num_outputs;
			auto off_ctrl_in = off_state_out + state_num_log2;
			auto off_state_in = off_ctrl_in + num_inputs;
			auto off_end = off_state_in + state_num_log2;

			RTLIL::Const state_in, state_out, ctrl_in, ctrl_out;
			ctrl_out.bits.insert(state_in.bits.begin(), off_ctrl_out, off_state_out);
			state_out.bits.insert(state_out.bits.begin(), off_state_out, off_ctrl_in);
			ctrl_in.bits.insert(ctrl_in.bits.begin(), off_ctrl_in, off_state_in);
			state_in.bits.insert(state_in.bits.begin(), off_state_in, off_end);

			transition_t tr;
			tr.state_in = state_in.as_int();
			tr.state_out = state_out.as_int();
			tr.ctrl_in = ctrl_in;
			tr.ctrl_out = ctrl_out;

			if (tr.state_in < 0 || tr.state_in >= state_num)
				tr.state_in = -1;
			if (tr.state_out < 0 || tr.state_out >= state_num)
				tr.state_out = -1;

			transition_table.push_back(tr);
		}
	}

	void log_info(RTLIL::Cell *cell)
	{
		log("-------------------------------------\n");
		log("\n");
		log("  Information on FSM %s (%s):\n", cell->name.c_str(), cell->parameters["\\NAME"].decode_string().c_str());
		log("\n");
		log("  Number of input signals:  %3d\n", num_inputs);
		log("  Number of output signals: %3d\n", num_outputs);
		log("  Number of state bits:     %3d\n", state_bits);

		log("\n");
		log("  Input signals:\n");
		RTLIL::SigSpec sig_in = cell->getPort("\\CTRL_IN");
		for (int i = 0; i < GetSize(sig_in); i++)
			log("  %3d: %s\n", i, log_signal(sig_in[i]));

		log("\n");
		log("  Output signals:\n");
		RTLIL::SigSpec sig_out = cell->getPort("\\CTRL_OUT");
		for (int i = 0; i < GetSize(sig_out); i++)
			log("  %3d: %s\n", i, log_signal(sig_out[i]));

		log("\n");
		log("  State encoding:\n");
		for (int i = 0; i < GetSize(state_table); i++)
			log("  %3d: %10s%s\n", i, log_signal(state_table[i], false),
					int(i) == reset_state ? "  <RESET STATE>" : "");

		log("\n");
		log("  Transition Table (state_in, ctrl_in, state_out, ctrl_out):\n");
		for (int i = 0; i < GetSize(transition_table); i++) {
			transition_t &tr = transition_table[i];
			log("  %5d: %5d %s   -> %5d %s\n", i, tr.state_in, log_signal(tr.ctrl_in), tr.state_out, log_signal(tr.ctrl_out));
		}

		log("\n");
		log("-------------------------------------\n");
	}

	// implemented in fsm_opt.cc
	static void optimize_fsm(RTLIL::Cell *cell, RTLIL::Module *module);
};

YOSYS_NAMESPACE_END

#endif
