/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *                2019  Eddie Hung <eddie@fpgeh.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.
 *
 */

// https://stackoverflow.com/a/46137633
#ifdef _MSC_VER
#include <stdlib.h>
#define bswap32 _byteswap_ulong
#elif defined(__APPLE__)
#include <libkern/OSByteOrder.h>
#define bswap32 OSSwapInt32
#elif defined(__GNUC__)
#define bswap32 __builtin_bswap32
#else
#include <cstdint>
inline static uint32_t bswap32(uint32_t x)
{
	// https://stackoverflow.com/a/27796212
	register uint32_t value = number_to_be_reversed;
	uint8_t lolo = (value >> 0) & 0xFF;
	uint8_t lohi = (value >> 8) & 0xFF;
	uint8_t hilo = (value >> 16) & 0xFF;
	uint8_t hihi = (value >> 24) & 0xFF;
	return (hihi << 24)
		| (hilo << 16)
		| (lohi << 8)
		| (lolo << 0);
}
#endif

#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/utils.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

inline int32_t to_big_endian(int32_t i32) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
	return bswap32(i32);
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
	return i32;
#else
#error "Unknown endianness"
#endif
}

void aiger_encode(std::ostream &f, int x)
{
	log_assert(x >= 0);

	while (x & ~0x7f) {
		f.put((x & 0x7f) | 0x80);
		x = x >> 7;
	}

	f.put(x);
}

struct XAigerWriter
{
	Module *module;
	SigMap sigmap;

	pool<SigBit> input_bits, output_bits;
	dict<SigBit, SigBit> not_map, alias_map;
	dict<SigBit, pair<SigBit, SigBit>> and_map;
	vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int>> ci_bits;
	vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int,int>> co_bits;
	dict<SigBit, float> arrival_times;

	vector<pair<int, int>> aig_gates;
	vector<int> aig_outputs;
	int aig_m = 0, aig_i = 0, aig_l = 0, aig_o = 0, aig_a = 0;

	dict<SigBit, int> aig_map;
	dict<SigBit, int> ordered_outputs;

	vector<Cell*> box_list;
	bool omode = false;

	int mkgate(int a0, int a1)
	{
		aig_m++, aig_a++;
		aig_gates.push_back(a0 > a1 ? make_pair(a0, a1) : make_pair(a1, a0));
		return 2*aig_m;
	}

	int bit2aig(SigBit bit)
	{
		auto it = aig_map.find(bit);
		if (it != aig_map.end()) {
			log_assert(it->second >= 0);
			return it->second;
		}

		// NB: Cannot use iterator returned from aig_map.insert()
		//     since this function is called recursively

		int a = -1;
		if (not_map.count(bit)) {
			a = bit2aig(not_map.at(bit)) ^ 1;
		} else
		if (and_map.count(bit)) {
			auto args = and_map.at(bit);
			int a0 = bit2aig(args.first);
			int a1 = bit2aig(args.second);
			a = mkgate(a0, a1);
		} else
		if (alias_map.count(bit)) {
			a = bit2aig(alias_map.at(bit));
		}

		if (bit == State::Sx || bit == State::Sz) {
			log_debug("Design contains 'x' or 'z' bits. Treating as 1'b0.\n");
			a = aig_map.at(State::S0);
		}

		log_assert(a >= 0);
		aig_map[bit] = a;
		return a;
	}

	XAigerWriter(Module *module, bool holes_mode=false) : module(module), sigmap(module)
	{
		pool<SigBit> undriven_bits;
		pool<SigBit> unused_bits;
		pool<SigBit> keep_bits;

		// promote public wires
		for (auto wire : module->wires())
			if (wire->name[0] == '\\')
				sigmap.add(wire);

		// promote input wires
		for (auto wire : module->wires())
			if (wire->port_input)
				sigmap.add(wire);

		// promote output wires
		for (auto wire : module->wires())
			if (wire->port_output)
				sigmap.add(wire);

		for (auto wire : module->wires())
		{
			bool keep = wire->attributes.count("\\keep");

			for (int i = 0; i < GetSize(wire); i++)
			{
				SigBit wirebit(wire, i);
				SigBit bit = sigmap(wirebit);

				if (bit.wire) {
					undriven_bits.insert(bit);
					unused_bits.insert(bit);
				}

				if (keep)
					keep_bits.insert(bit);

				if (wire->port_input || keep) {
					if (bit != wirebit)
						alias_map[bit] = wirebit;
					input_bits.insert(wirebit);
				}

				if (wire->port_output || keep) {
					if (bit != RTLIL::Sx) {
						if (bit != wirebit)
							alias_map[wirebit] = bit;
						output_bits.insert(wirebit);
					}
					else
						log_debug("Skipping PO '%s' driven by 1'bx\n", log_signal(wirebit));
				}
			}
		}

		for (auto bit : input_bits)
			undriven_bits.erase(sigmap(bit));
		for (auto bit : output_bits)
			if (!bit.wire->port_input)
				unused_bits.erase(bit);

		// TODO: Speed up toposort -- ultimately we care about
		//       box ordering, but not individual AIG cells
		dict<SigBit, pool<IdString>> bit_drivers, bit_users;
		TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
		bool abc9_box_seen = false;

		for (auto cell : module->selected_cells()) {
			if (cell->type == "$_NOT_")
			{
				SigBit A = sigmap(cell->getPort("\\A").as_bit());
				SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
				unused_bits.erase(A);
				undriven_bits.erase(Y);
				not_map[Y] = A;
				if (!holes_mode) {
					toposort.node(cell->name);
					bit_users[A].insert(cell->name);
					bit_drivers[Y].insert(cell->name);
				}
				continue;
			}

			if (cell->type == "$_AND_")
			{
				SigBit A = sigmap(cell->getPort("\\A").as_bit());
				SigBit B = sigmap(cell->getPort("\\B").as_bit());
				SigBit Y = sigmap(cell->getPort("\\Y").as_bit());
				unused_bits.erase(A);
				unused_bits.erase(B);
				undriven_bits.erase(Y);
				and_map[Y] = make_pair(A, B);
				if (!holes_mode) {
					toposort.node(cell->name);
					bit_users[A].insert(cell->name);
					bit_users[B].insert(cell->name);
					bit_drivers[Y].insert(cell->name);
				}
				continue;
			}

			log_assert(!holes_mode);

			RTLIL::Module* inst_module = module->design->module(cell->type);
			if (inst_module && inst_module->attributes.count("\\abc9_box_id")) {
				abc9_box_seen = true;

				if (!holes_mode) {
					toposort.node(cell->name);
					for (const auto &conn : cell->connections()) {
						auto port_wire = inst_module->wire(conn.first);
						if (port_wire->port_input) {
							// Ignore inout for the sake of topographical ordering
							if (port_wire->port_output) continue;
							for (auto bit : sigmap(conn.second))
								bit_users[bit].insert(cell->name);
						}

						if (port_wire->port_output)
							for (auto bit : sigmap(conn.second))
								bit_drivers[bit].insert(cell->name);
					}
				}
			}
			else {
				bool cell_known = inst_module || cell->known();
				for (const auto &c : cell->connections()) {
					if (c.second.is_fully_const()) continue;
					auto port_wire = inst_module ? inst_module->wire(c.first) : nullptr;
					auto is_input = (port_wire && port_wire->port_input) || !cell_known || cell->input(c.first);
					auto is_output = (port_wire && port_wire->port_output) || !cell_known || cell->output(c.first);
					if (!is_input && !is_output)
						log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type));

					if (is_input) {
						for (auto b : c.second) {
							Wire *w = b.wire;
							if (!w) continue;
							if (!w->port_output || !cell_known) {
								SigBit I = sigmap(b);
								if (I != b)
									alias_map[b] = I;
								output_bits.insert(b);
								unused_bits.erase(b);

								if (!cell_known)
									keep_bits.insert(b);
							}
						}
					}
					if (is_output) {
						int arrival = 0;
						if (port_wire) {
							auto it = port_wire->attributes.find("\\abc9_arrival");
							if (it != port_wire->attributes.end()) {
								if (it->second.flags != 0)
									log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(port_wire), log_id(cell->type));
								arrival = it->second.as_int();
							}
						}

						for (auto b : c.second) {
							Wire *w = b.wire;
							if (!w) continue;
							input_bits.insert(b);
							SigBit O = sigmap(b);
							if (O != b)
								alias_map[O] = b;
							undriven_bits.erase(O);

							if (arrival)
								arrival_times[b] = arrival;
						}
					}
				}
			}

			//log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
		}

		if (abc9_box_seen) {
			for (auto &it : bit_users)
				if (bit_drivers.count(it.first))
					for (auto driver_cell : bit_drivers.at(it.first))
					for (auto user_cell : it.second)
						toposort.edge(driver_cell, user_cell);

#if 0
			toposort.analyze_loops = true;
#endif
			bool no_loops YS_ATTRIBUTE(unused) = toposort.sort();
#if 0
			unsigned i = 0;
			for (auto &it : toposort.loops) {
				log("  loop %d\n", i++);
				for (auto cell_name : it) {
					auto cell = module->cell(cell_name);
					log_assert(cell);
					log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute().c_str());
				}
			}
#endif
			log_assert(no_loops);

			for (auto cell_name : toposort.sorted) {
				RTLIL::Cell *cell = module->cell(cell_name);
				log_assert(cell);

				RTLIL::Module* box_module = module->design->module(cell->type);
				if (!box_module || !box_module->attributes.count("\\abc9_box_id"))
					continue;

				bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */);

				// Fully pad all unused input connections of this box cell with S0
				// Fully pad all undriven output connections of this box cell with anonymous wires
				// NB: Assume box_module->ports are sorted alphabetically
				//     (as RTLIL::Module::fixup_ports() would do)
				for (const auto &port_name : box_module->ports) {
					RTLIL::Wire* w = box_module->wire(port_name);
					log_assert(w);
					auto it = cell->connections_.find(port_name);
					if (w->port_input) {
						RTLIL::SigSpec rhs;
						if (it != cell->connections_.end()) {
							if (GetSize(it->second) < GetSize(w))
								it->second.append(RTLIL::SigSpec(State::S0, GetSize(w)-GetSize(it->second)));
							rhs = it->second;
						}
						else {
							rhs = RTLIL::SigSpec(State::S0, GetSize(w));
							cell->setPort(port_name, rhs);
						}

						int offset = 0;
						for (auto b : rhs.bits()) {
							SigBit I = sigmap(b);
							if (b == RTLIL::Sx)
								b = State::S0;
							else if (I != b) {
								if (I == RTLIL::Sx)
									alias_map[b] = State::S0;
								else
									alias_map[b] = I;
							}
							co_bits.emplace_back(b, cell, port_name, offset++, 0);
							unused_bits.erase(b);
						}
					}
					if (w->port_output) {
						RTLIL::SigSpec rhs;
						auto it = cell->connections_.find(w->name);
						if (it != cell->connections_.end()) {
							if (GetSize(it->second) < GetSize(w))
								it->second.append(module->addWire(NEW_ID, GetSize(w)-GetSize(it->second)));
							rhs = it->second;
						}
						else {
							Wire *wire = module->addWire(NEW_ID, GetSize(w));
							if (blackbox)
								wire->set_bool_attribute(ID(abc9_padding));
							rhs = wire;
							cell->setPort(port_name, rhs);
						}

						int offset = 0;
						for (const auto &b : rhs.bits()) {
							ci_bits.emplace_back(b, cell, port_name, offset++);
							SigBit O = sigmap(b);
							if (O != b)
								alias_map[O] = b;
							undriven_bits.erase(O);
							input_bits.erase(b);
						}
					}
				}
				box_list.emplace_back(cell);
			}

			// TODO: Free memory from toposort, bit_drivers, bit_users
		}

		for (auto bit : input_bits) {
			if (!output_bits.count(bit))
				continue;
			RTLIL::Wire *wire = bit.wire;
			// If encountering an inout port, or a keep-ed wire, then create a new wire
			// with $inout.out suffix, make it a PO driven by the existing inout, and
			// inherit existing inout's drivers
			if ((wire->port_input && wire->port_output && !undriven_bits.count(bit))
					|| keep_bits.count(bit)) {
				RTLIL::IdString wire_name = stringf("$%s$inout.out", wire->name.c_str());
				RTLIL::Wire *new_wire = module->wire(wire_name);
				if (!new_wire)
					new_wire = module->addWire(wire_name, GetSize(wire));
				SigBit new_bit(new_wire, bit.offset);
				module->connect(new_bit, bit);
				if (not_map.count(bit)) {
					auto a = not_map.at(bit);
					not_map[new_bit] = a;
				}
				else if (and_map.count(bit)) {
					auto a = and_map.at(bit);
					and_map[new_bit] = a;
				}
				else if (alias_map.count(bit)) {
					auto a = alias_map.at(bit);
					alias_map[new_bit] = a;
				}
				else
					alias_map[new_bit] = bit;
				output_bits.erase(bit);
				output_bits.insert(new_bit);
			}
		}

		for (auto bit : unused_bits)
			undriven_bits.erase(bit);

		if (!undriven_bits.empty() && !holes_mode) {
			undriven_bits.sort();
			for (auto bit : undriven_bits) {
				log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit));
				input_bits.insert(bit);
			}
			log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module));
		}

		if (holes_mode) {
			struct sort_by_port_id {
				bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const {
					return a.wire->port_id < b.wire->port_id;
				}
			};
			input_bits.sort(sort_by_port_id());
			output_bits.sort(sort_by_port_id());
		}
		else {
			input_bits.sort();
			output_bits.sort();
		}

		not_map.sort();
		and_map.sort();

		aig_map[State::S0] = 0;
		aig_map[State::S1] = 1;

		for (auto bit : input_bits) {
			aig_m++, aig_i++;
			log_assert(!aig_map.count(bit));
			aig_map[bit] = 2*aig_m;
		}

		for (auto &c : ci_bits) {
			RTLIL::SigBit bit = std::get<0>(c);
			aig_m++, aig_i++;
			aig_map[bit] = 2*aig_m;
		}

		for (auto &c : co_bits) {
			RTLIL::SigBit bit = std::get<0>(c);
			std::get<4>(c) = ordered_outputs[bit] = aig_o++;
			aig_outputs.push_back(bit2aig(bit));
		}

		if (output_bits.empty()) {
			output_bits.insert(State::S0);
			omode = true;
		}

		for (auto bit : output_bits) {
			ordered_outputs[bit] = aig_o++;
			aig_outputs.push_back(bit2aig(bit));
		}

	}

	void write_aiger(std::ostream &f, bool ascii_mode)
	{
		int aig_obc = aig_o;
		int aig_obcj = aig_obc;
		int aig_obcjf = aig_obcj;

		log_assert(aig_m == aig_i + aig_l + aig_a);
		log_assert(aig_obcjf == GetSize(aig_outputs));

		f << stringf("%s %d %d %d %d %d", ascii_mode ? "aag" : "aig", aig_m, aig_i, aig_l, aig_o, aig_a);
		f << stringf("\n");

		if (ascii_mode)
		{
			for (int i = 0; i < aig_i; i++)
				f << stringf("%d\n", 2*i+2);

			for (int i = 0; i < aig_obc; i++)
				f << stringf("%d\n", aig_outputs.at(i));

			for (int i = aig_obc; i < aig_obcj; i++)
				f << stringf("1\n");

			for (int i = aig_obc; i < aig_obcj; i++)
				f << stringf("%d\n", aig_outputs.at(i));

			for (int i = aig_obcj; i < aig_obcjf; i++)
				f << stringf("%d\n", aig_outputs.at(i));

			for (int i = 0; i < aig_a; i++)
				f << stringf("%d %d %d\n", 2*(aig_i+aig_l+i)+2, aig_gates.at(i).first, aig_gates.at(i).second);
		}
		else
		{
			for (int i = 0; i < aig_obc; i++)
				f << stringf("%d\n", aig_outputs.at(i));

			for (int i = aig_obc; i < aig_obcj; i++)
				f << stringf("1\n");

			for (int i = aig_obc; i < aig_obcj; i++)
				f << stringf("%d\n", aig_outputs.at(i));

			for (int i = aig_obcj; i < aig_obcjf; i++)
				f << stringf("%d\n", aig_outputs.at(i));

			for (int i = 0; i < aig_a; i++) {
				int lhs = 2*(aig_i+aig_l+i)+2;
				int rhs0 = aig_gates.at(i).first;
				int rhs1 = aig_gates.at(i).second;
				int delta0 = lhs - rhs0;
				int delta1 = rhs0 - rhs1;
				aiger_encode(f, delta0);
				aiger_encode(f, delta1);
			}
		}

		f << "c";

		log_assert(!output_bits.empty());
		auto write_buffer = [](std::stringstream &buffer, int i32) {
			int32_t i32_be = to_big_endian(i32);
			buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be));
		};
		std::stringstream h_buffer;
		auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1);
		write_h_buffer(1);
		log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits));
		write_h_buffer(input_bits.size() + ci_bits.size());
		log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits));
		write_h_buffer(output_bits.size() + GetSize(co_bits));
		log_debug("piNum = %d\n", GetSize(input_bits));
		write_h_buffer(input_bits.size());
		log_debug("poNum = %d\n", GetSize(output_bits));
		write_h_buffer(output_bits.size());
		log_debug("boxNum = %d\n", GetSize(box_list));
		write_h_buffer(box_list.size());

		auto write_buffer_float = [](std::stringstream &buffer, float f32) {
			buffer.write(reinterpret_cast<const char*>(&f32), sizeof(f32));
		};
		std::stringstream i_buffer;
		auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1);
		for (auto bit : input_bits)
			write_i_buffer(arrival_times.at(bit, 0));
		//std::stringstream o_buffer;
		//auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1);
		//for (auto bit : output_bits)
		//	write_o_buffer(0);

		if (!box_list.empty()) {
			RTLIL::Module *holes_module = module->design->addModule("$__holes__");
			log_assert(holes_module);

			int port_id = 1;
			int box_count = 0;
			for (auto cell : box_list) {
				RTLIL::Module* box_module = module->design->module(cell->type);
				int box_inputs = 0, box_outputs = 0;
				Cell *holes_cell = nullptr;
				if (box_module->get_bool_attribute("\\whitebox")) {
					holes_cell = holes_module->addCell(cell->name, cell->type);
					holes_cell->parameters = cell->parameters;
				}

				// NB: Assume box_module->ports are sorted alphabetically
				//     (as RTLIL::Module::fixup_ports() would do)
				for (const auto &port_name : box_module->ports) {
					RTLIL::Wire *w = box_module->wire(port_name);
					log_assert(w);
					RTLIL::Wire *holes_wire;
					RTLIL::SigSpec port_wire;
					if (w->port_input) {
						for (int i = 0; i < GetSize(w); i++) {
							box_inputs++;
							holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
							if (!holes_wire) {
								holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs));
								holes_wire->port_input = true;
								holes_wire->port_id = port_id++;
								holes_module->ports.push_back(holes_wire->name);
							}
							if (holes_cell)
								port_wire.append(holes_wire);
						}
						if (!port_wire.empty())
							holes_cell->setPort(w->name, port_wire);
					}
					if (w->port_output) {
						box_outputs += GetSize(w);
						for (int i = 0; i < GetSize(w); i++) {
							if (GetSize(w) == 1)
								holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str()));
							else
								holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i));
							holes_wire->port_output = true;
							holes_wire->port_id = port_id++;
							holes_module->ports.push_back(holes_wire->name);
							if (holes_cell)
								port_wire.append(holes_wire);
							else
								holes_module->connect(holes_wire, State::S0);
						}
						if (!port_wire.empty())
							holes_cell->setPort(w->name, port_wire);
					}
				}

				write_h_buffer(box_inputs);
				write_h_buffer(box_outputs);
				write_h_buffer(box_module->attributes.at("\\abc9_box_id").as_int());
				write_h_buffer(box_count++);
			}

			std::stringstream r_buffer;
			auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1);
			write_r_buffer(0);
			f << "r";
			std::string buffer_str = r_buffer.str();
			int32_t buffer_size_be = to_big_endian(buffer_str.size());
			f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
			f.write(buffer_str.data(), buffer_str.size());

			if (holes_module) {
				log_push();

				// NB: fixup_ports() will sort ports by name
				//holes_module->fixup_ports();
				holes_module->check();

				holes_module->design->selection_stack.emplace_back(false);
				RTLIL::Selection& sel = holes_module->design->selection_stack.back();
				sel.select(holes_module);

				// TODO: Should not need to opt_merge if we only instantiate
				//       each box type once...
				Pass::call(holes_module->design, "opt_merge -share_all");

				Pass::call(holes_module->design, "flatten -wb");

				// TODO: Should techmap/aigmap/check all lib_whitebox-es just once,
				//       instead of per write_xaiger call
				Pass::call(holes_module->design, "techmap");
				Pass::call(holes_module->design, "aigmap");
				for (auto cell : holes_module->cells())
					if (!cell->type.in("$_NOT_", "$_AND_"))
						log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n");

				holes_module->design->selection_stack.pop_back();

				// Move into a new (temporary) design so that "clean" will only
				// operate (and run checks on) this one module
				RTLIL::Design *holes_design = new RTLIL::Design;
				holes_module->design->modules_.erase(holes_module->name);
				holes_design->add(holes_module);
				Pass::call(holes_design, "clean -purge");

				std::stringstream a_buffer;
				XAigerWriter writer(holes_module, true /* holes_mode */);
				writer.write_aiger(a_buffer, false /*ascii_mode*/);

				delete holes_design;

				f << "a";
				std::string buffer_str = a_buffer.str();
				int32_t buffer_size_be = to_big_endian(buffer_str.size());
				f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
				f.write(buffer_str.data(), buffer_str.size());

				log_pop();
			}
		}

		f << "h";
		std::string buffer_str = h_buffer.str();
		int32_t buffer_size_be = to_big_endian(buffer_str.size());
		f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
		f.write(buffer_str.data(), buffer_str.size());

		f << "i";
		buffer_str = i_buffer.str();
		buffer_size_be = to_big_endian(buffer_str.size());
		f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
		f.write(buffer_str.data(), buffer_str.size());
		//f << "o";
		//buffer_str = o_buffer.str();
		//buffer_size_be = to_big_endian(buffer_str.size());
		//f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
		//f.write(buffer_str.data(), buffer_str.size());

		f << stringf("Generated by %s\n", yosys_version_str);
	}

	void write_map(std::ostream &f, bool verbose_map)
	{
		dict<int, string> input_lines;
		dict<int, string> output_lines;
		dict<int, string> wire_lines;

		for (auto wire : module->wires())
		{
			//if (!verbose_map && wire->name[0] == '$')
			//	continue;

			SigSpec sig = sigmap(wire);

			for (int i = 0; i < GetSize(wire); i++)
			{
				RTLIL::SigBit b(wire, i);
				if (input_bits.count(b)) {
					int a = aig_map.at(b);
					log_assert((a & 1) == 0);
					input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, i, log_id(wire));
				}

				if (output_bits.count(b)) {
					int o = ordered_outputs.at(b);
					output_lines[o] += stringf("output %d %d %s\n", o - GetSize(co_bits), i, log_id(wire));
					continue;
				}

				if (verbose_map) {
					if (aig_map.count(sig[i]) == 0)
						continue;

					int a = aig_map.at(sig[i]);
					wire_lines[a] += stringf("wire %d %d %s\n", a, i, log_id(wire));
				}
			}
		}

		input_lines.sort();
		for (auto &it : input_lines)
			f << it.second;
		log_assert(input_lines.size() == input_bits.size());

		int box_count = 0;
		for (auto cell : box_list)
			f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name));

		output_lines.sort();
		if (omode)
			output_lines[State::S0] = "output 0 0 $__dummy__\n";
		for (auto &it : output_lines)
			f << it.second;
		log_assert(output_lines.size() == output_bits.size());

		wire_lines.sort();
		for (auto &it : wire_lines)
			f << it.second;
	}
};

struct XAigerBackend : public Backend {
	XAigerBackend() : Backend("xaiger", "write design to XAIGER file") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    write_xaiger [options] [filename]\n");
		log("\n");
		log("Write the current design to an XAIGER file. The design must be flattened and\n");
		log("all unsupported cells will be converted into psuedo-inputs and pseudo-outputs.\n");
		log("\n");
		log("    -ascii\n");
		log("        write ASCII version of AIGER format\n");
		log("\n");
		log("    -map <filename>\n");
		log("        write an extra file with port and latch symbols\n");
		log("\n");
		log("    -vmap <filename>\n");
		log("        like -map, but more verbose\n");
		log("\n");
	}
	void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		bool ascii_mode = false;
		bool verbose_map = false;
		std::string map_filename;

		log_header(design, "Executing XAIGER backend.\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-ascii") {
				ascii_mode = true;
				continue;
			}
			if (map_filename.empty() && args[argidx] == "-map" && argidx+1 < args.size()) {
				map_filename = args[++argidx];
				continue;
			}
			if (map_filename.empty() && args[argidx] == "-vmap" && argidx+1 < args.size()) {
				map_filename = args[++argidx];
				verbose_map = true;
				continue;
			}
			break;
		}
		extra_args(f, filename, args, argidx, !ascii_mode);

		Module *top_module = design->top_module();

		if (top_module == nullptr)
			log_error("Can't find top module in current design!\n");

		XAigerWriter writer(top_module);
		writer.write_aiger(*f, ascii_mode);

		if (!map_filename.empty()) {
			std::ofstream mapf;
			mapf.open(map_filename.c_str(), std::ofstream::trunc);
			if (mapf.fail())
				log_error("Can't open file `%s' for writing: %s\n", map_filename.c_str(), strerror(errno));
			writer.write_map(mapf, verbose_map);
		}
	}
} XAigerBackend;

PRIVATE_NAMESPACE_END
