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

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

void proc_init(RTLIL::Module *mod, SigMap &sigmap, RTLIL::Process *proc)
{
	bool found_init = false;

	for (auto &sync : proc->syncs)
		if (sync->type == RTLIL::SyncType::STi)
		{
			found_init = true;
			log("Found init rule in `%s.%s'.\n", mod->name.c_str(), proc->name.c_str());

			for (auto &action : sync->actions)
			{
				RTLIL::SigSpec lhs = action.first;
				RTLIL::SigSpec rhs = sigmap(action.second);

				if (!rhs.is_fully_const())
					log_cmd_error("Failed to get a constant init value for %s: %s\n", log_signal(lhs), log_signal(rhs));

				int offset = 0;
				for (auto &lhs_c : lhs.chunks())
				{
					if (lhs_c.wire != nullptr)
					{
						SigSpec valuesig = rhs.extract(offset, lhs_c.width);
						if (!valuesig.is_fully_const())
							log_cmd_error("Non-const initialization value: %s = %s\n", log_signal(lhs_c), log_signal(valuesig));

						Const value = valuesig.as_const();
						Const &wireinit = lhs_c.wire->attributes["\\init"];

						while (GetSize(wireinit.bits) < lhs_c.wire->width)
							wireinit.bits.push_back(State::Sx);

						for (int i = 0; i < lhs_c.width; i++) {
							auto &initbit = wireinit.bits[i + lhs_c.offset];
							if (initbit != State::Sx && initbit != value[i])
								log_cmd_error("Conflicting initialization values for %s.\n", log_signal(lhs_c));
							initbit = value[i];
						}

						log("  Set init value: %s = %s\n", log_signal(lhs_c.wire), log_signal(wireinit));
					}
					offset += lhs_c.width;
				}
			}
		}

	if (found_init) {
		std::vector<RTLIL::SyncRule*> new_syncs;
		for (auto &sync : proc->syncs)
			if (sync->type == RTLIL::SyncType::STi)
				delete sync;
			else
				new_syncs.push_back(sync);
		proc->syncs.swap(new_syncs);
	}
}

struct ProcInitPass : public Pass {
	ProcInitPass() : Pass("proc_init", "convert initial block to init attributes") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    proc_init [selection]\n");
		log("\n");
		log("This pass extracts the 'init' actions from processes (generated from Verilog\n");
		log("'initial' blocks) and sets the initial value to the 'init' attribute on the\n");
		log("respective wire.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		log_header(design, "Executing PROC_INIT pass (extract init attributes).\n");

		extra_args(args, 1, design);

		for (auto mod : design->modules())
			if (design->selected(mod)) {
				SigMap sigmap(mod);
				for (auto &proc_it : mod->processes)
					if (design->selected(mod, proc_it.second))
						proc_init(mod, sigmap, proc_it.second);
			}
	}
} ProcInitPass;

PRIVATE_NAMESPACE_END
