/*
 *  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/yosys.h"
#include "kernel/sigtools.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
{
	if (cell->type == "$dffsr")
	{
		int width = cell->getParam("\\WIDTH").as_int();
		bool setpol = cell->getParam("\\SET_POLARITY").as_bool();
		bool clrpol = cell->getParam("\\CLR_POLARITY").as_bool();

		SigBit setunused = setpol ? State::S0 : State::S1;
		SigBit clrunused = clrpol ? State::S0 : State::S1;

		SigSpec setsig = sigmap(cell->getPort("\\SET"));
		SigSpec clrsig = sigmap(cell->getPort("\\CLR"));

		Const reset_val;
		SigSpec setctrl, clrctrl;

		for (int i = 0; i < width; i++)
		{
			SigBit setbit = setsig[i], clrbit = clrsig[i];

			if (setbit == setunused) {
				clrctrl.append(clrbit);
				reset_val.bits.push_back(State::S0);
				continue;
			}

			if (clrbit == clrunused) {
				setctrl.append(setbit);
				reset_val.bits.push_back(State::S1);
				continue;
			}

			return;
		}

		setctrl.sort_and_unify();
		clrctrl.sort_and_unify();

		if (GetSize(setctrl) > 1 || GetSize(clrctrl) > 1)
			return;

		if (GetSize(setctrl) == 0 && GetSize(clrctrl) == 0)
			return;

		if (GetSize(setctrl) == 1 && GetSize(clrctrl) == 1) {
			if (setpol != clrpol)
				return;
			if (setctrl != clrctrl)
				return;
		}

		log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell));

		if (GetSize(setctrl) == 1) {
			cell->setPort("\\ARST", setctrl);
			cell->setParam("\\ARST_POLARITY", setpol);
		} else {
			cell->setPort("\\ARST", clrctrl);
			cell->setParam("\\ARST_POLARITY", clrpol);
		}

		cell->type = "$adff";
		cell->unsetPort("\\SET");
		cell->unsetPort("\\CLR");
		cell->setParam("\\ARST_VALUE", reset_val);
		cell->unsetParam("\\SET_POLARITY");
		cell->unsetParam("\\CLR_POLARITY");

		return;
	}

	if (cell->type.in("$_DFFSR_NNN_", "$_DFFSR_NNP_", "$_DFFSR_NPN_", "$_DFFSR_NPP_",
			"$_DFFSR_PNN_", "$_DFFSR_PNP_", "$_DFFSR_PPN_", "$_DFFSR_PPP_"))
	{
		char clkpol = cell->type.c_str()[8];
		char setpol = cell->type.c_str()[9];
		char clrpol = cell->type.c_str()[10];

		SigBit setbit = sigmap(cell->getPort("\\S"));
		SigBit clrbit = sigmap(cell->getPort("\\R"));

		SigBit setunused = setpol == 'P' ? State::S0 : State::S1;
		SigBit clrunused = clrpol == 'P' ? State::S0 : State::S1;

		IdString oldtype = cell->type;

		if (setbit == setunused) {
			cell->type = stringf("$_DFF_%c%c0_", clkpol, clrpol);
			cell->unsetPort("\\S");
			goto converted_gate;
		}

		if (clrbit == clrunused) {
			cell->type = stringf("$_DFF_%c%c1_", clkpol, setpol);
			cell->setPort("\\R", cell->getPort("\\S"));
			cell->unsetPort("\\S");
			goto converted_gate;
		}

		return;

	converted_gate:
		log("Converting %s cell %s.%s to %s.\n", log_id(oldtype), log_id(module), log_id(cell), log_id(cell->type));
		return;
	}
}

void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
{
	if (cell->type == "$adff")
	{
		bool rstpol = cell->getParam("\\ARST_POLARITY").as_bool();
		SigBit rstunused = rstpol ? State::S0 : State::S1;
		SigSpec rstsig = sigmap(cell->getPort("\\ARST"));

		if (rstsig != rstunused)
			return;

		log("Converting %s cell %s.%s to $dff.\n", log_id(cell->type), log_id(module), log_id(cell));

		cell->type = "$dff";
		cell->unsetPort("\\ARST");
		cell->unsetParam("\\ARST_VALUE");
		cell->unsetParam("\\ARST_POLARITY");

		return;
	}

	if (cell->type.in("$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_",
			"$_DFF_PN0_", "$_DFF_PN1_", "$_DFF_PP0_", "$_DFF_PP1_"))
	{
		char clkpol = cell->type.c_str()[6];
		char rstpol = cell->type.c_str()[7];

		SigBit rstbit = sigmap(cell->getPort("\\R"));
		SigBit rstunused = rstpol == 'P' ? State::S0 : State::S1;

		if (rstbit != rstunused)
			return;

		IdString newtype = stringf("$_DFF_%c_", clkpol);
		log("Converting %s cell %s.%s to %s.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(newtype));

		cell->type = newtype;
		cell->unsetPort("\\R");

		return;
	}
}

struct Dffsr2dffPass : public Pass {
	Dffsr2dffPass() : Pass("dffsr2dff", "convert DFFSR cells to simpler FF cell types") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    dffsr2dff [options] [selection]\n");
		log("\n");
		log("This pass converts DFFSR cells ($dffsr, $_DFFSR_???_) and ADFF cells ($adff,\n");
		log("$_DFF_???_) to simpler FF cell types when any of the set/reset inputs is unused.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		log_header(design, "Executing DFFSR2DFF pass (mapping DFFSR cells to simpler FFs).\n");

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

		for (auto module : design->selected_modules()) {
			SigMap sigmap(module);
			for (auto cell : module->selected_cells()) {
				dffsr_worker(sigmap, module, cell);
				adff_worker(sigmap, module, cell);
			}
		}
	}
} Dffsr2dffPass;

PRIVATE_NAMESPACE_END
