/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  Copyright (C) 2018  Ruben Undheim <ruben.undheim@gmail.com>
 *
 *  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 "frontends/verific/verific.h"
#include <stdlib.h>
#include <stdio.h>
#include <set>

#ifndef _WIN32
#  include <unistd.h>
#endif


USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct generate_port_decl_t {
	bool input, output;
	string portname;
	int index;
};

void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes, const std::vector<generate_port_decl_t> &portdecls)
{
	std::set<RTLIL::IdString> found_celltypes;

	for (auto i1 : design->modules_)
	for (auto i2 : i1.second->cells_)
	{
		RTLIL::Cell *cell = i2.second;
		if (design->has(cell->type))
			continue;
		if (cell->type.begins_with("$__"))
			continue;
		for (auto &pattern : celltypes)
			if (patmatch(pattern.c_str(), RTLIL::unescape_id(cell->type).c_str()))
				found_celltypes.insert(cell->type);
	}

	for (auto &celltype : found_celltypes)
	{
		std::set<RTLIL::IdString> portnames;
		std::set<RTLIL::IdString> parameters;
		std::map<RTLIL::IdString, int> portwidths;
		log("Generate module for cell type %s:\n", celltype.c_str());

		for (auto i1 : design->modules_)
		for (auto i2 : i1.second->cells_)
			if (i2.second->type == celltype) {
				for (auto &conn : i2.second->connections()) {
					if (conn.first[0] != '$')
						portnames.insert(conn.first);
					portwidths[conn.first] = max(portwidths[conn.first], conn.second.size());
				}
				for (auto &para : i2.second->parameters)
					parameters.insert(para.first);
			}

		for (auto &decl : portdecls)
			if (decl.index > 0)
				portnames.insert(decl.portname);

		std::set<int> indices;
		for (int i = 0; i < int(portnames.size()); i++)
			indices.insert(i+1);

		std::vector<generate_port_decl_t> ports(portnames.size());

		for (auto &decl : portdecls)
			if (decl.index > 0) {
				portwidths[decl.portname] = max(portwidths[decl.portname], 1);
				portwidths[decl.portname] = max(portwidths[decl.portname], portwidths[stringf("$%d", decl.index)]);
				log("  port %d: %s [%d:0] %s\n", decl.index, decl.input ? decl.output ? "inout" : "input" : "output", portwidths[decl.portname]-1, RTLIL::id2cstr(decl.portname));
				if (indices.count(decl.index) > ports.size())
					log_error("Port index (%d) exceeds number of found ports (%d).\n", decl.index, int(ports.size()));
				if (indices.count(decl.index) == 0)
					log_error("Conflict on port index %d.\n", decl.index);
				indices.erase(decl.index);
				portnames.erase(decl.portname);
				ports[decl.index-1] = decl;
			}

		while (portnames.size() > 0) {
			RTLIL::IdString portname = *portnames.begin();
			for (auto &decl : portdecls)
				if (decl.index == 0 && patmatch(decl.portname.c_str(), RTLIL::unescape_id(portname).c_str())) {
					generate_port_decl_t d = decl;
					d.portname = portname.str();
					d.index = *indices.begin();
					log_assert(!indices.empty());
					indices.erase(d.index);
					ports[d.index-1] = d;
					portwidths[d.portname] = max(portwidths[d.portname], 1);
					log("  port %d: %s [%d:0] %s\n", d.index, d.input ? d.output ? "inout" : "input" : "output", portwidths[d.portname]-1, RTLIL::id2cstr(d.portname));
					goto found_matching_decl;
				}
			log_error("Can't match port %s.\n", RTLIL::id2cstr(portname));
		found_matching_decl:;
			portnames.erase(portname);
		}

		log_assert(indices.empty());

		RTLIL::Module *mod = new RTLIL::Module;
		mod->name = celltype;
		mod->attributes["\\blackbox"] = RTLIL::Const(1);
		design->add(mod);

		for (auto &decl : ports) {
			RTLIL::Wire *wire = mod->addWire(decl.portname, portwidths.at(decl.portname));
			wire->port_id = decl.index;
			wire->port_input = decl.input;
			wire->port_output = decl.output;
		}

		mod->fixup_ports();

		for (auto &para : parameters)
			log("  ignoring parameter %s.\n", RTLIL::id2cstr(para));

		log("  module %s created.\n", RTLIL::id2cstr(mod->name));
	}
}

// Return the "basic" type for an array item.
std::string basic_cell_type(const std::string celltype, int pos[3] = nullptr) {
	std::string basicType = celltype;
	if (celltype.compare(0, strlen("$array:"), "$array:") == 0) {
		int pos_idx = celltype.find_first_of(':');
		int pos_num = celltype.find_first_of(':', pos_idx + 1);
		int pos_type = celltype.find_first_of(':', pos_num + 1);
		basicType = celltype.substr(pos_type + 1);
		if (pos != nullptr) {
			pos[0] = pos_idx;
			pos[1] = pos_num;
			pos[2] = pos_type;
		}
	}
	return basicType;
}

bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, std::vector<std::string> &libdirs)
{
	bool did_something = false;
	std::map<RTLIL::Cell*, std::pair<int, int>> array_cells;
	std::string filename;

	bool has_interface_ports = false;

	// If any of the ports are actually interface ports, we will always need to
	// reprocess the module:
	if(!module->get_bool_attribute("\\interfaces_replaced_in_module")) {
		for (auto &wire : module->wires_) {
			if ((wire.second->port_input || wire.second->port_output) && wire.second->get_bool_attribute("\\is_interface"))
				has_interface_ports = true;
		}
	}

	// Always keep track of all derived interfaces available in the current module in 'interfaces_in_module':
	dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module;
	for (auto &cell_it : module->cells_)
	{
		RTLIL::Cell *cell = cell_it.second;
		if(cell->get_bool_attribute("\\is_interface")) {
			RTLIL::Module *intf_module = design->modules_[cell->type];
			interfaces_in_module[cell->name] = intf_module;
		}
	}

	for (auto &cell_it : module->cells_)
	{
		RTLIL::Cell *cell = cell_it.second;
		bool has_interfaces_not_found = false;

		std::vector<RTLIL::IdString> connections_to_remove;
		std::vector<RTLIL::IdString> connections_to_add_name;
		std::vector<RTLIL::SigSpec> connections_to_add_signal;

		if (cell->type.begins_with("$array:")) {
			int pos[3];
			basic_cell_type(cell->type.str(), pos);
			int pos_idx = pos[0];
			int pos_num = pos[1];
			int pos_type = pos[2];
			int idx = atoi(cell->type.substr(pos_idx + 1, pos_num).c_str());
			int num = atoi(cell->type.substr(pos_num + 1, pos_type).c_str());
			array_cells[cell] = std::pair<int, int>(idx, num);
			cell->type = cell->type.substr(pos_type + 1);
		}
		dict<RTLIL::IdString, RTLIL::Module*> interfaces_to_add_to_submodule;
		dict<RTLIL::IdString, RTLIL::IdString> modports_used_in_submodule;

		if (design->modules_.count(cell->type) == 0)
		{
			if (design->modules_.count("$abstract" + cell->type.str()))
			{
				cell->type = design->modules_.at("$abstract" + cell->type.str())->derive(design, cell->parameters);
				cell->parameters.clear();
				did_something = true;
				continue;
			}

			if (cell->type[0] == '$')
				continue;

			for (auto &dir : libdirs)
			{
				static const vector<pair<string, string>> extensions_list =
				{
					{".v", "verilog"},
					{".sv", "verilog -sv"},
					{".il", "ilang"}
				};

				for (auto &ext : extensions_list)
				{
					filename = dir + "/" + RTLIL::unescape_id(cell->type) + ext.first;
					if (check_file_exists(filename)) {
						Frontend::frontend_call(design, NULL, filename, ext.second);
						goto loaded_module;
					}
				}
			}

			if ((flag_check || flag_simcheck) && cell->type[0] != '$')
				log_error("Module `%s' referenced in module `%s' in cell `%s' is not part of the design.\n",
						cell->type.c_str(), module->name.c_str(), cell->name.c_str());
			continue;

		loaded_module:
			if (design->modules_.count(cell->type) == 0)
				log_error("File `%s' from libdir does not declare module `%s'.\n", filename.c_str(), cell->type.c_str());
			did_something = true;
		} else {

		RTLIL::Module *mod = design->module(cell->type);

		// Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to
		// some lists, so that the ports for sub-modules can be replaced further down:
		for (auto &conn : cell->connections()) {
			if(mod->wires_.count(conn.first) != 0 && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list
				//const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type");
				//for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module (not crucially important, but good for robustness)
				//}

				// Find if the sub-module has set a modport for the current interface connection:
				const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_modport");
				std::string interface_modport = "";
				for (auto &d : interface_modport_pool) {
					interface_modport = "\\" + d;
				}
				if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { // Check if the connected wire is a potential interface in the parent module
					std::string interface_name_str = conn.second.bits()[0].wire->name.str();
					interface_name_str.replace(0,23,""); // Strip the prefix '$dummywireforinterface' from the dummy wire to get the name
					interface_name_str = "\\" + interface_name_str;
					RTLIL::IdString interface_name = interface_name_str;
					bool not_found_interface = false;
					if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either
						// Check if the interface instance is present in module:
						// Interface instances may either have the plain name or the name appended with '_inst_from_top_dummy'.
						// Check for both of them here
						int nexactmatch = interfaces_in_module.count(interface_name) > 0;
						std::string interface_name_str2 =  interface_name_str + "_inst_from_top_dummy";
						RTLIL::IdString interface_name2 = interface_name_str2;
						int nmatch2 = interfaces_in_module.count(interface_name2) > 0;
						if (nexactmatch > 0 || nmatch2 > 0) {
							if (nexactmatch != 0) // Choose the one with the plain name if it exists
								interface_name2 = interface_name;
							RTLIL::Module *mod_replace_ports = interfaces_in_module.at(interface_name2);
							for (auto &mod_wire : mod_replace_ports->wires_) { // Go over all wires in interface, and add replacements to lists.
								std::string signal_name1 = conn.first.str() + "." + log_id(mod_wire.first);
								std::string signal_name2 = interface_name.str() + "." + log_id(mod_wire.first);
								connections_to_add_name.push_back(RTLIL::IdString(signal_name1));
								if(module->wires_.count(signal_name2) == 0) {
									log_error("Could not find signal '%s' in '%s'\n", signal_name2.c_str(), log_id(module->name));
								}
								else {
									RTLIL::Wire *wire_in_parent = module->wire(signal_name2);
									connections_to_add_signal.push_back(wire_in_parent);
								}
							}
							connections_to_remove.push_back(conn.first);
							interfaces_to_add_to_submodule[conn.first] = interfaces_in_module.at(interface_name2);

							// Add modports to a dict which will be passed to AstModule::derive
							if (interface_modport != "") {
								modports_used_in_submodule[conn.first] = interface_modport;
							}
						}
						else not_found_interface = true;
					}
					else not_found_interface = true;
					// If the interface instance has not already been derived in the module, we cannot complete at this stage. Set "has_interfaces_not_found"
					// which will delay the expansion of this cell:
					if (not_found_interface) {
						// If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error:
						if(!(module->get_bool_attribute("\\cells_not_processed"))) {
							log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module));
						}
						else {
							// Only set has_interfaces_not_found if it would be possible to find them, since otherwiser we will end up in an infinite loop:
							has_interfaces_not_found = true;
						}
					}
				}
			}
		}
		//

		if (flag_check || flag_simcheck)
		{
			for (auto &conn : cell->connections()) {
				if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
					int id = atoi(conn.first.c_str()+1);
					if (id <= 0 || id > GetSize(mod->ports))
						log_error("Module `%s' referenced in module `%s' in cell `%s' has only %d ports, requested port %d.\n",
								log_id(cell->type), log_id(module), log_id(cell), GetSize(mod->ports), id);
				} else if (mod->wire(conn.first) == nullptr || mod->wire(conn.first)->port_id == 0)
					log_error("Module `%s' referenced in module `%s' in cell `%s' does not have a port named '%s'.\n",
							log_id(cell->type), log_id(module), log_id(cell), log_id(conn.first));
			}
			for (auto &param : cell->parameters)
				if (mod->avail_parameters.count(param.first) == 0 && param.first[0] != '$' && strchr(param.first.c_str(), '.') == NULL)
					log_error("Module `%s' referenced in module `%s' in cell `%s' does not have a parameter named '%s'.\n",
							log_id(cell->type), log_id(module), log_id(cell), log_id(param.first));

		}
		}
		RTLIL::Module *mod = design->modules_[cell->type];

		if (design->modules_.at(cell->type)->get_blackbox_attribute()) {
			if (flag_simcheck)
				log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n",
						cell->type.c_str(), module->name.c_str(), cell->name.c_str());
			continue;
		}

		// If interface instances not yet found, skip cell for now, and say we did something, so that we will return back here:
		if(has_interfaces_not_found) {
			did_something = true; // waiting for interfaces to be handled
			continue;
		}

		// Do the actual replacements of the SV interface port connection with the individual signal connections:
		for(unsigned int i=0;i<connections_to_add_name.size();i++) {
			cell->connections_[connections_to_add_name[i]] = connections_to_add_signal[i];
		}
		// Remove the connection for the interface itself:
		for(unsigned int i=0;i<connections_to_remove.size();i++) {
			cell->connections_.erase(connections_to_remove[i]);
		}

		// If there are no overridden parameters AND not interfaces, then we can use the existing module instance as the type
		// for the cell:
		if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute("\\module_not_derived")))) {
			// If the cell being processed is an the interface instance itself, go down to "handle_interface_instance:",
			// so that the signals of the interface are added to the parent module.
			if (mod->get_bool_attribute("\\is_interface")) {
				goto handle_interface_instance;
			}
			continue;
		}

		cell->type = mod->derive(design, cell->parameters, interfaces_to_add_to_submodule, modports_used_in_submodule);
		cell->parameters.clear();
		did_something = true;

		handle_interface_instance:

			// We add all the signals of the interface explicitly to the parent module. This is always needed when we encounter
			// an interface instance:
			if (mod->get_bool_attribute("\\is_interface") && cell->get_bool_attribute("\\module_not_derived")) {
				cell->set_bool_attribute("\\is_interface");
				RTLIL::Module *derived_module = design->modules_[cell->type];
				interfaces_in_module[cell->name] = derived_module;
				did_something = true;
			}
		// We clear 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell)
		cell->attributes.erase("\\module_not_derived");
	}
	// Clear the attribute 'cells_not_processed' such that it can be known that we
	// have been through all cells at least once, and that we can know whether
	// to flag an error because of interface instances not found:
	module->attributes.erase("\\cells_not_processed");


	// If any interface instances or interface ports were found in the module, we need to rederive it completely:
	if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute("\\interfaces_replaced_in_module")) {
		module->reprocess_module(design, interfaces_in_module);
		return did_something;
	}


	for (auto &it : array_cells)
	{
		RTLIL::Cell *cell = it.first;
		int idx = it.second.first, num = it.second.second;

		if (design->modules_.count(cell->type) == 0)
			log_error("Array cell `%s.%s' of unknown type `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));

		RTLIL::Module *mod = design->modules_[cell->type];

		for (auto &conn : cell->connections_) {
			int conn_size = conn.second.size();
			RTLIL::IdString portname = conn.first;
			if (portname.begins_with("$")) {
				int port_id = atoi(portname.substr(1).c_str());
				for (auto &wire_it : mod->wires_)
					if (wire_it.second->port_id == port_id) {
						portname = wire_it.first;
						break;
					}
			}
			if (mod->wires_.count(portname) == 0)
				log_error("Array cell `%s.%s' connects to unknown port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first));
			int port_size = mod->wires_.at(portname)->width;
			if (conn_size == port_size || conn_size == 0)
				continue;
			if (conn_size != port_size*num)
				log_error("Array cell `%s.%s' has invalid port vs. signal size for port `%s'.\n", RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(conn.first));
			conn.second = conn.second.extract(port_size*idx, port_size);
		}
	}

	return did_something;
}

void hierarchy_worker(RTLIL::Design *design, std::set<RTLIL::Module*, IdString::compare_ptr_by_name<Module>> &used, RTLIL::Module *mod, int indent)
{
	if (used.count(mod) > 0)
		return;

	if (indent == 0)
		log("Top module:  %s\n", mod->name.c_str());
	else if (!mod->get_blackbox_attribute())
		log("Used module: %*s%s\n", indent, "", mod->name.c_str());
	used.insert(mod);

	for (auto cell : mod->cells()) {
		std::string celltype = cell->type.str();
		if (celltype.compare(0, strlen("$array:"), "$array:") == 0)
			celltype = basic_cell_type(celltype);
		if (design->module(celltype))
			hierarchy_worker(design, used, design->module(celltype), indent+4);
	}
}

void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib)
{
	std::set<RTLIL::Module*, IdString::compare_ptr_by_name<Module>> used;
	hierarchy_worker(design, used, top, 0);

	std::vector<RTLIL::Module*> del_modules;
	for (auto &it : design->modules_)
		if (used.count(it.second) == 0)
			del_modules.push_back(it.second);
		else {
			// Now all interface ports must have been exploded, and it is hence
			// safe to delete all of the remaining dummy interface ports:
			pool<RTLIL::Wire*> del_wires;
			for(auto &wire : it.second->wires_) {
				if ((wire.second->port_input || wire.second->port_output) && wire.second->get_bool_attribute("\\is_interface")) {
					del_wires.insert(wire.second);
				}
			}
			if (del_wires.size() > 0) {
				it.second->remove(del_wires);
				it.second->fixup_ports();
			}
		}

	int del_counter = 0;
	for (auto mod : del_modules) {
		if (!purge_lib && mod->get_blackbox_attribute())
			continue;
		log("Removing unused module `%s'.\n", mod->name.c_str());
		design->modules_.erase(mod->name);
		del_counter++;
		delete mod;
	}

	log("Removed %d unused modules.\n", del_counter);
}

bool set_keep_assert(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
{
	if (cache.count(mod) == 0)
		for (auto c : mod->cells()) {
			RTLIL::Module *m = mod->design->module(c->type);
			if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in("$assert", "$assume", "$live", "$fair", "$cover"))
				return cache[mod] = true;
		}
	return cache[mod];
}

int find_top_mod_score(Design *design, Module *module, dict<Module*, int> &db)
{
	if (db.count(module) == 0) {
		int score = 0;
		db[module] = 0;
		for (auto cell : module->cells()) {
			std::string celltype = cell->type.str();
			// Is this an array instance
			if (celltype.compare(0, strlen("$array:"), "$array:") == 0)
				celltype = basic_cell_type(celltype);
			// Is this cell a module instance?
			auto instModule = design->module(celltype);
			// If there is no instance for this, issue a warning.
			if (instModule != nullptr) {
				score = max(score, find_top_mod_score(design, instModule, db) + 1);
			}
		}
		db[module] = score;
	}
	return db.at(module);
}

RTLIL::Module *check_if_top_has_changed(Design *design, Module *top_mod)
{
	if(top_mod != NULL && top_mod->get_bool_attribute("\\initial_top"))
		return top_mod;
	else {
		for (auto mod : design->modules()) {
			if (mod->get_bool_attribute("\\top")) {
				return mod;
			}
		}
	}
	return NULL;
}

struct HierarchyPass : public Pass {
	HierarchyPass() : Pass("hierarchy", "check, expand and clean up design hierarchy") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    hierarchy [-check] [-top <module>]\n");
		log("    hierarchy -generate <cell-types> <port-decls>\n");
		log("\n");
		log("In parametric designs, a module might exists in several variations with\n");
		log("different parameter values. This pass looks at all modules in the current\n");
		log("design an re-runs the language frontends for the parametric modules as\n");
		log("needed. It also resolves assignments to wired logic data types (wand/wor),\n");
		log("resolves positional module parameters, unroll array instances, and more.\n");
		log("\n");
		log("    -check\n");
		log("        also check the design hierarchy. this generates an error when\n");
		log("        an unknown module is used as cell type.\n");
		log("\n");
		log("    -simcheck\n");
		log("        like -check, but also throw an error if blackbox modules are\n");
		log("        instantiated, and throw an error if the design has no top module.\n");
		log("\n");
		log("    -purge_lib\n");
		log("        by default the hierarchy command will not remove library (blackbox)\n");
		log("        modules. use this option to also remove unused blackbox modules.\n");
		log("\n");
		log("    -libdir <directory>\n");
		log("        search for files named <module_name>.v in the specified directory\n");
		log("        for unknown modules and automatically run read_verilog for each\n");
		log("        unknown module.\n");
		log("\n");
		log("    -keep_positionals\n");
		log("        per default this pass also converts positional arguments in cells\n");
		log("        to arguments using port names. This option disables this behavior.\n");
		log("\n");
		log("    -keep_portwidths\n");
		log("        per default this pass adjusts the port width on cells that are\n");
		log("        module instances when the width does not match the module port. This\n");
		log("        option disables this behavior.\n");
		log("\n");
		log("    -nodefaults\n");
		log("        do not resolve input port default values\n");
		log("\n");
		log("    -nokeep_asserts\n");
		log("        per default this pass sets the \"keep\" attribute on all modules\n");
		log("        that directly or indirectly contain one or more formal properties.\n");
		log("        This option disables this behavior.\n");
		log("\n");
		log("    -top <module>\n");
		log("        use the specified top module to build the design hierarchy. Modules\n");
		log("        outside this tree (unused modules) are removed.\n");
		log("\n");
		log("        when the -top option is used, the 'top' attribute will be set on the\n");
		log("        specified top module. otherwise a module with the 'top' attribute set\n");
		log("        will implicitly be used as top module, if such a module exists.\n");
		log("\n");
		log("    -auto-top\n");
		log("        automatically determine the top of the design hierarchy and mark it.\n");
		log("\n");
		log("    -chparam name value \n");
		log("       elaborate the top module using this parameter value. Modules on which\n");
		log("       this parameter does not exist may cause a warning message to be output.\n");
		log("       This option can be specified multiple times to override multiple\n");
		log("       parameters. String values must be passed in double quotes (\").\n");
		log("\n");
		log("In -generate mode this pass generates blackbox modules for the given cell\n");
		log("types (wildcards supported). For this the design is searched for cells that\n");
		log("match the given types and then the given port declarations are used to\n");
		log("determine the direction of the ports. The syntax for a port declaration is:\n");
		log("\n");
		log("    {i|o|io}[@<num>]:<portname>\n");
		log("\n");
		log("Input ports are specified with the 'i' prefix, output ports with the 'o'\n");
		log("prefix and inout ports with the 'io' prefix. The optional <num> specifies\n");
		log("the position of the port in the parameter list (needed when instantiated\n");
		log("using positional arguments). When <num> is not specified, the <portname> can\n");
		log("also contain wildcard characters.\n");
		log("\n");
		log("This pass ignores the current selection and always operates on all modules\n");
		log("in the current design.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		log_header(design, "Executing HIERARCHY pass (managing design hierarchy).\n");

		bool flag_check = false;
		bool flag_simcheck = false;
		bool purge_lib = false;
		RTLIL::Module *top_mod = NULL;
		std::string load_top_mod;
		std::vector<std::string> libdirs;

		bool auto_top_mode = false;
		bool generate_mode = false;
		bool keep_positionals = false;
		bool keep_portwidths = false;
		bool nodefaults = false;
		bool nokeep_asserts = false;
		std::vector<std::string> generate_cells;
		std::vector<generate_port_decl_t> generate_ports;
		std::map<std::string, std::string> parameters;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-generate" && !flag_check && !flag_simcheck && !top_mod) {
				generate_mode = true;
				log("Entering generate mode.\n");
				while (++argidx < args.size()) {
					const char *p = args[argidx].c_str();
					generate_port_decl_t decl;
					if (p[0] == 'i' && p[1] == 'o')
						decl.input = true, decl.output = true, p += 2;
					else if (*p == 'i')
						decl.input = true, decl.output = false, p++;
					else if (*p == 'o')
						decl.input = false, decl.output = true, p++;
					else
						goto is_celltype;
					if (*p == '@') {
						char *endptr;
						decl.index = strtol(++p, &endptr, 10);
						if (decl.index < 1)
							goto is_celltype;
						p = endptr;
					} else
						decl.index = 0;
					if (*(p++) != ':')
						goto is_celltype;
					if (*p == 0)
						goto is_celltype;
					decl.portname = p;
					log("Port declaration: %s", decl.input ? decl.output ? "inout" : "input" : "output");
					if (decl.index >= 1)
						log(" [at position %d]", decl.index);
					log(" %s\n", decl.portname.c_str());
					generate_ports.push_back(decl);
					continue;
				is_celltype:
					log("Celltype: %s\n", args[argidx].c_str());
					generate_cells.push_back(RTLIL::unescape_id(args[argidx]));
				}
				continue;
			}
			if (args[argidx] == "-check") {
				flag_check = true;
				continue;
			}
			if (args[argidx] == "-simcheck") {
				flag_simcheck = true;
				continue;
			}
			if (args[argidx] == "-purge_lib") {
				purge_lib = true;
				continue;
			}
			if (args[argidx] == "-keep_positionals") {
				keep_positionals = true;
				continue;
			}
			if (args[argidx] == "-keep_portwidths") {
				keep_portwidths = true;
				continue;
			}
			if (args[argidx] == "-nodefaults") {
				nodefaults = true;
				continue;
			}
			if (args[argidx] == "-nokeep_asserts") {
				nokeep_asserts = true;
				continue;
			}
			if (args[argidx] == "-libdir" && argidx+1 < args.size()) {
				libdirs.push_back(args[++argidx]);
				continue;
			}
			if (args[argidx] == "-top") {
				if (++argidx >= args.size())
					log_cmd_error("Option -top requires an additional argument!\n");
				load_top_mod = args[argidx];
				continue;
			}
			if (args[argidx] == "-auto-top") {
				auto_top_mode = true;
				continue;
			}
			if (args[argidx] == "-chparam"  && argidx+2 < args.size()) {
				const std::string &key = args[++argidx];
				const std::string &value = args[++argidx];
				auto r = parameters.emplace(key, value);
				if (!r.second) {
					log_warning("-chparam %s already specified: overwriting.\n", key.c_str());
					r.first->second = value;
				}
				continue;
			}
			break;
		}
		extra_args(args, argidx, design, false);

		if (!load_top_mod.empty())
		{
			IdString top_name = RTLIL::escape_id(load_top_mod);
			IdString abstract_id = "$abstract" + RTLIL::escape_id(load_top_mod);
			top_mod = design->module(top_name);

			dict<RTLIL::IdString, RTLIL::Const> top_parameters;
			for (auto &para : parameters) {
				SigSpec sig_value;
				if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
					log_cmd_error("Can't decode value '%s'!\n", para.second.c_str());
				top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const();
			}

			if (top_mod == nullptr && design->module(abstract_id))
				top_mod = design->module(design->module(abstract_id)->derive(design, top_parameters));
			else if (top_mod != nullptr && !top_parameters.empty())
				top_mod = design->module(top_mod->derive(design, top_parameters));

			if (top_mod != nullptr && top_mod->name != top_name) {
				Module *m = top_mod->clone();
				m->name = top_name;
				Module *old_mod = design->module(top_name);
				if (old_mod)
					design->remove(old_mod);
				design->add(m);
				top_mod = m;
			}
		}

		if (top_mod == nullptr && !load_top_mod.empty()) {
#ifdef YOSYS_ENABLE_VERIFIC
			if (verific_import_pending) {
				verific_import(design, parameters, load_top_mod);
				top_mod = design->module(RTLIL::escape_id(load_top_mod));
			}
#endif
			if (top_mod == NULL)
				log_cmd_error("Module `%s' not found!\n", load_top_mod.c_str());
		} else {
#ifdef YOSYS_ENABLE_VERIFIC
			if (verific_import_pending)
				verific_import(design, parameters);
#endif
		}

		if (generate_mode) {
			generate(design, generate_cells, generate_ports);
			return;
		}

		log_push();

		if (top_mod == nullptr)
			for (auto &mod_it : design->modules_)
				if (mod_it.second->get_bool_attribute("\\top"))
					top_mod = mod_it.second;

		if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) {
			IdString top_name = top_mod->name.substr(strlen("$abstract"));

			dict<RTLIL::IdString, RTLIL::Const> top_parameters;
			for (auto &para : parameters) {
				SigSpec sig_value;
				if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
					log_cmd_error("Can't decode value '%s'!\n", para.second.c_str());
				top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const();
			}

			top_mod = design->module(top_mod->derive(design, top_parameters));

			if (top_mod != nullptr && top_mod->name != top_name) {
				Module *m = top_mod->clone();
				m->name = top_name;
				Module *old_mod = design->module(top_name);
				if (old_mod)
					design->remove(old_mod);
				design->add(m);
				top_mod = m;
			}
		}

		if (top_mod == nullptr && auto_top_mode) {
			log_header(design, "Finding top of design hierarchy..\n");
			dict<Module*, int> db;
			for (Module *mod : design->selected_modules()) {
				int score = find_top_mod_score(design, mod, db);
				log("root of %3d design levels: %-20s\n", score, log_id(mod));
				if (!top_mod || score > db[top_mod])
					top_mod = mod;
			}
			if (top_mod != nullptr)
				log("Automatically selected %s as design top module.\n", log_id(top_mod));
		}

		if (flag_simcheck && top_mod == nullptr)
			log_error("Design has no top module.\n");

		if (top_mod != NULL) {
			for (auto &mod_it : design->modules_)
				if (mod_it.second == top_mod)
					mod_it.second->attributes["\\initial_top"] = RTLIL::Const(1);
				else
					mod_it.second->attributes.erase("\\initial_top");
		}

		bool did_something = true;
		while (did_something)
		{
			did_something = false;

			std::set<RTLIL::Module*, IdString::compare_ptr_by_name<Module>> used_modules;
			if (top_mod != NULL) {
				log_header(design, "Analyzing design hierarchy..\n");
				hierarchy_worker(design, used_modules, top_mod, 0);
			} else {
				for (auto mod : design->modules())
					used_modules.insert(mod);
			}

			for (auto module : used_modules) {
				if (expand_module(design, module, flag_check, flag_simcheck, libdirs))
					did_something = true;
			}


			// The top module might have changed if interface instances have been detected in it:
			RTLIL::Module *tmp_top_mod = check_if_top_has_changed(design, top_mod);
			if (tmp_top_mod != NULL) {
				if (tmp_top_mod != top_mod){
					top_mod = tmp_top_mod;
					did_something = true;
				}
			}

			// Delete modules marked as 'to_delete':
			std::vector<RTLIL::Module *> modules_to_delete;
			for(auto &mod_it : design->modules_) {
				if (mod_it.second->get_bool_attribute("\\to_delete")) {
					modules_to_delete.push_back(mod_it.second);
				}
			}
			for(size_t i=0; i<modules_to_delete.size(); i++) {
				design->remove(modules_to_delete[i]);
			}
		}


		if (top_mod != NULL) {
			log_header(design, "Analyzing design hierarchy..\n");
			hierarchy_clean(design, top_mod, purge_lib);
		}

		if (top_mod != NULL) {
			for (auto &mod_it : design->modules_) {
				if (mod_it.second == top_mod)
					mod_it.second->attributes["\\top"] = RTLIL::Const(1);
				else
					mod_it.second->attributes.erase("\\top");
				mod_it.second->attributes.erase("\\initial_top");
			}
		}

		if (!nokeep_asserts) {
			std::map<RTLIL::Module*, bool> cache;
			for (auto mod : design->modules())
				if (set_keep_assert(cache, mod)) {
					log("Module %s directly or indirectly contains formal properties -> setting \"keep\" attribute.\n", log_id(mod));
					mod->set_bool_attribute("\\keep");
				}
		}

		if (!keep_positionals)
		{
			std::set<RTLIL::Module*> pos_mods;
			std::map<std::pair<RTLIL::Module*,int>, RTLIL::IdString> pos_map;
			std::vector<std::pair<RTLIL::Module*,RTLIL::Cell*>> pos_work;

			for (auto &mod_it : design->modules_)
			for (auto &cell_it : mod_it.second->cells_) {
				RTLIL::Cell *cell = cell_it.second;
				if (design->modules_.count(cell->type) == 0)
					continue;
				for (auto &conn : cell->connections())
					if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
						pos_mods.insert(design->modules_.at(cell->type));
						pos_work.push_back(std::pair<RTLIL::Module*,RTLIL::Cell*>(mod_it.second, cell));
						break;
					}
			}

			for (auto module : pos_mods)
			for (auto &wire_it : module->wires_) {
				RTLIL::Wire *wire = wire_it.second;
				if (wire->port_id > 0)
					pos_map[std::pair<RTLIL::Module*,int>(module, wire->port_id)] = wire->name;
			}

			for (auto &work : pos_work) {
				RTLIL::Module *module = work.first;
				RTLIL::Cell *cell = work.second;
				log("Mapping positional arguments of cell %s.%s (%s).\n",
						RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
				dict<RTLIL::IdString, RTLIL::SigSpec> new_connections;
				for (auto &conn : cell->connections())
					if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9') {
						int id = atoi(conn.first.c_str()+1);
						std::pair<RTLIL::Module*,int> key(design->modules_.at(cell->type), id);
						if (pos_map.count(key) == 0) {
							log("  Failed to map positional argument %d of cell %s.%s (%s).\n",
									id, RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
							new_connections[conn.first] = conn.second;
						} else
							new_connections[pos_map.at(key)] = conn.second;
					} else
						new_connections[conn.first] = conn.second;
				cell->connections_ = new_connections;
			}
		}

		if (!nodefaults)
		{
			dict<IdString, dict<IdString, Const>> defaults_db;

			for (auto module : design->modules())
				for (auto wire : module->wires())
					if (wire->port_input && wire->attributes.count("\\defaultvalue"))
						defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue");

			for (auto module : design->modules())
				for (auto cell : module->cells())
				{
					if (defaults_db.count(cell->type) == 0)
						continue;

					if (keep_positionals) {
						bool found_positionals = false;
						for (auto &conn : cell->connections())
							if (conn.first[0] == '$' && '0' <= conn.first[1] && conn.first[1] <= '9')
								found_positionals = true;
						if (found_positionals)
							continue;
					}

					for (auto &it : defaults_db.at(cell->type))
						if (!cell->hasPort(it.first))
							cell->setPort(it.first, it.second);
				}
		}

		std::set<Module*> blackbox_derivatives;
		std::vector<Module*> design_modules = design->modules();

		for (auto module : design_modules)
		{
			pool<Wire*> wand_wor_index;
			dict<Wire*, SigSpec> wand_map, wor_map;
			vector<SigSig> new_connections;

			for (auto wire : module->wires())
			{
				if (wire->get_bool_attribute("\\wand")) {
					wand_map[wire] = SigSpec();
					wand_wor_index.insert(wire);
				}
				if (wire->get_bool_attribute("\\wor")) {
					wor_map[wire] = SigSpec();
					wand_wor_index.insert(wire);
				}
			}

			for (auto &conn : module->connections())
			{
				SigSig new_conn;
				int cursor = 0;

				for (auto c : conn.first.chunks())
				{
					Wire *w = c.wire;
					SigSpec rhs = conn.second.extract(cursor, GetSize(c));

					if (wand_wor_index.count(w) == 0) {
						new_conn.first.append(c);
						new_conn.second.append(rhs);
					} else {
						if (wand_map.count(w)) {
							SigSpec sig = SigSpec(State::S1, GetSize(w));
							sig.replace(c.offset, rhs);
							wand_map.at(w).append(sig);
						} else {
							SigSpec sig = SigSpec(State::S0, GetSize(w));
							sig.replace(c.offset, rhs);
							wor_map.at(w).append(sig);
						}
					}
					cursor += GetSize(c);
				}
				new_connections.push_back(new_conn);
			}
			module->new_connections(new_connections);

			for (auto cell : module->cells())
			{
				if (!cell->known())
					continue;

				for (auto &conn : cell->connections())
				{
					if (!cell->output(conn.first))
						continue;

					SigSpec new_sig;
					bool update_port = false;

					for (auto c : conn.second.chunks())
					{
						Wire *w = c.wire;

						if (wand_wor_index.count(w) == 0) {
							new_sig.append(c);
							continue;
						}

						Wire *t = module->addWire(NEW_ID, GetSize(c));
						new_sig.append(t);
						update_port = true;

						if (wand_map.count(w)) {
							SigSpec sig = SigSpec(State::S1, GetSize(w));
							sig.replace(c.offset, t);
							wand_map.at(w).append(sig);
						} else {
							SigSpec sig = SigSpec(State::S0, GetSize(w));
							sig.replace(c.offset, t);
							wor_map.at(w).append(sig);
						}
					}

					if (update_port)
						cell->setPort(conn.first, new_sig);
				}
			}

			for (auto w : wand_wor_index)
			{
				bool wand = wand_map.count(w);
				SigSpec sigs = wand ? wand_map.at(w) : wor_map.at(w);

				if (GetSize(sigs) == 0)
					continue;

				if (GetSize(w) == 1) {
					if (wand)
						module->addReduceAnd(NEW_ID, sigs, w);
					else
						module->addReduceOr(NEW_ID, sigs, w);
					continue;
				}

				SigSpec s = sigs.extract(0, GetSize(w));
				for (int i = GetSize(w); i < GetSize(sigs); i += GetSize(w)) {
					if (wand)
						s = module->And(NEW_ID, s, sigs.extract(i, GetSize(w)));
					else
						s = module->Or(NEW_ID, s, sigs.extract(i, GetSize(w)));
				}
				module->connect(w, s);
			}

			for (auto cell : module->cells())
			{
				Module *m = design->module(cell->type);

				if (m == nullptr)
					continue;

				if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
					IdString new_m_name = m->derive(design, cell->parameters, true);
					if (new_m_name.empty())
						continue;
					if (new_m_name != m->name) {
						m = design->module(new_m_name);
						blackbox_derivatives.insert(m);
					}
				}

				for (auto &conn : cell->connections())
				{
					Wire *w = m->wire(conn.first);

					if (w == nullptr || w->port_id == 0)
						continue;

					if (GetSize(conn.second) == 0)
						continue;

					SigSpec sig = conn.second;

					if (!keep_portwidths && GetSize(w) != GetSize(conn.second))
					{
						if (GetSize(w) < GetSize(conn.second))
						{
							int n = GetSize(conn.second) - GetSize(w);
							if (!w->port_input && w->port_output)
								module->connect(sig.extract(GetSize(w), n), Const(0, n));
							sig.remove(GetSize(w), n);
						}
						else
						{
							int n = GetSize(w) - GetSize(conn.second);
							if (w->port_input && !w->port_output)
								sig.append(Const(0, n));
							else
								sig.append(module->addWire(NEW_ID, n));
						}

						if (!conn.second.is_fully_const() || !w->port_input || w->port_output)
							log_warning("Resizing cell port %s.%s.%s from %d bits to %d bits.\n", log_id(module), log_id(cell),
									log_id(conn.first), GetSize(conn.second), GetSize(sig));
						cell->setPort(conn.first, sig);
					}

					if (w->port_output && !w->port_input && sig.has_const())
						log_error("Output port %s.%s.%s (%s) is connected to constants: %s\n",
								log_id(module), log_id(cell), log_id(conn.first), log_id(cell->type), log_signal(sig));
				}
			}
		}

		for (auto module : blackbox_derivatives)
			design->remove(module);

		log_pop();
	}
} HierarchyPass;

PRIVATE_NAMESPACE_END
