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

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct rules_t
{
	struct portinfo_t {
		int group, index, dupidx;
		int wrmode, enable, transp, clocks, clkpol;

		SigBit sig_clock;
		SigSpec sig_addr, sig_data, sig_en;
		bool effective_clkpol;
		bool make_transp;
		bool make_outreg;
		int mapped_port;
	};

	struct bram_t {
		IdString name;
		int variant;

		int groups, abits, dbits, init;
		vector<int> ports, wrmode, enable, transp, clocks, clkpol;

		void dump_config() const
		{
			log("      bram %s # variant %d\n", log_id(name), variant);
			log("        init %d\n", init);
			log("        abits %d\n", abits);
			log("        dbits %d\n", dbits);
			log("        groups %d\n", groups);

			log("        ports "); for (int v : ports)  log("%4d", v); log("\n");
			log("        wrmode"); for (int v : wrmode) log("%4d", v); log("\n");
			log("        enable"); for (int v : enable) log("%4d", v); log("\n");
			log("        transp"); for (int v : transp) log("%4d", v); log("\n");
			log("        clocks"); for (int v : clocks) log("%4d", v); log("\n");
			log("        clkpol"); for (int v : clkpol) log("%4d", v); log("\n");
			log("      endbram\n");
		}

		void check_vectors() const
		{
			if (groups != GetSize(ports))  log_error("Bram %s variant %d has %d groups but only %d entries in 'ports'.\n",  log_id(name), variant, groups, GetSize(ports));
			if (groups != GetSize(wrmode)) log_error("Bram %s variant %d has %d groups but only %d entries in 'wrmode'.\n", log_id(name), variant, groups, GetSize(wrmode));
			if (groups != GetSize(enable)) log_error("Bram %s variant %d has %d groups but only %d entries in 'enable'.\n", log_id(name), variant, groups, GetSize(enable));
			if (groups != GetSize(transp)) log_error("Bram %s variant %d has %d groups but only %d entries in 'transp'.\n", log_id(name), variant, groups, GetSize(transp));
			if (groups != GetSize(clocks)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clocks'.\n", log_id(name), variant, groups, GetSize(clocks));
			if (groups != GetSize(clkpol)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clkpol'.\n", log_id(name), variant, groups, GetSize(clkpol));

			int group = 0;
			for (auto e : enable)
				if (e > dbits) log_error("Bram %s variant %d group %d has %d enable bits but only %d dbits.\n", log_id(name), variant, group, e, dbits);
		}

		vector<portinfo_t> make_portinfos() const
		{
			vector<portinfo_t> portinfos;
			for (int i = 0; i < groups; i++)
			for (int j = 0; j < ports[i]; j++) {
				portinfo_t pi;
				pi.group = i;
				pi.index = j;
				pi.dupidx = 0;
				pi.wrmode = wrmode[i];
				pi.enable = enable[i];
				pi.transp = transp[i];
				pi.clocks = clocks[i];
				pi.clkpol = clkpol[i];
				pi.mapped_port = -1;
				pi.make_transp = false;
				pi.make_outreg = false;
				pi.effective_clkpol = false;
				portinfos.push_back(pi);
			}
			return portinfos;
		}

		void find_variant_params(dict<IdString, Const> &variant_params, const bram_t &other) const
		{
			log_assert(name == other.name);

			if (groups != other.groups)
				log_error("Bram %s variants %d and %d have different values for 'groups'.\n", log_id(name), variant, other.variant);

			if (abits != other.abits)
				variant_params["\\CFG_ABITS"] = abits;
			if (dbits != other.dbits)
				variant_params["\\CFG_DBITS"] = dbits;
			if (init != other.init)
				variant_params["\\CFG_INIT"] = init;

			for (int i = 0; i < groups; i++)
			{
				if (ports[i] != other.ports[i])
					log_error("Bram %s variants %d and %d have different number of %c-ports.\n", log_id(name), variant, other.variant, 'A'+i);
				if (wrmode[i] != other.wrmode[i])
					variant_params[stringf("\\CFG_WRMODE_%c", 'A' + i)] = wrmode[i];
				if (enable[i] != other.enable[i])
					variant_params[stringf("\\CFG_ENABLE_%c", 'A' + i)] = enable[i];
				if (transp[i] != other.transp[i])
					variant_params[stringf("\\CFG_TRANSP_%c", 'A' + i)] = transp[i];
				if (clocks[i] != other.clocks[i])
					variant_params[stringf("\\CFG_CLOCKS_%c", 'A' + i)] = clocks[i];
				if (clkpol[i] != other.clkpol[i])
					variant_params[stringf("\\CFG_CLKPOL_%c", 'A' + i)] = clkpol[i];
			}
		}
	};

	struct match_t {
		IdString name;
		dict<string, int> min_limits, max_limits;
		bool or_next_if_better, make_transp, make_outreg;
		char shuffle_enable;
		IdString attr;
		Const value;
	};

	dict<IdString, vector<bram_t>> brams;
	vector<match_t> matches;

	std::ifstream infile;
	vector<string> tokens;
	vector<string> labels;
	int linecount;

	void syntax_error()
	{
		if (tokens.empty())
			log_error("Unexpected end of rules file in line %d.\n", linecount);
		log_error("Syntax error in rules file line %d.\n", linecount);
	}

	bool next_line()
	{
		string line;
		while (std::getline(infile, line)) {
			tokens.clear();
			labels.clear();
			linecount++;
			for (string tok = next_token(line); !tok.empty(); tok = next_token(line)) {
				if (tok[0] == '@') {
					labels.push_back(tok.substr(1));
					continue;
				}
				if (tok[0] == '#')
					break;
				tokens.push_back(tok);
			}
			if (!tokens.empty())
				return true;
		}
		return false;
	}

	bool parse_single_int(const char *stmt, int &value)
	{
		if (GetSize(tokens) == 2 && tokens[0] == stmt) {
			value = atoi(tokens[1].c_str());
			return true;
		}
		return false;
	}

	bool parse_int_vect(const char *stmt, vector<int> &value)
	{
		if (GetSize(tokens) >= 2 && tokens[0] == stmt) {
			value.resize(GetSize(tokens)-1);
			for (int i = 1; i < GetSize(tokens); i++)
				value[i-1] = atoi(tokens[i].c_str());
			return true;
		}
		return false;
	}

	void parse_bram()
	{
		IdString bram_name = RTLIL::escape_id(tokens[1]);

		if (GetSize(tokens) != 2)
			syntax_error();

		vector<vector<string>> lines_nolabels;
		std::map<string, vector<vector<string>>> lines_labels;

		while (next_line())
		{
			if (GetSize(tokens) == 1 && tokens[0] == "endbram")
				break;
			if (labels.empty())
				lines_nolabels.push_back(tokens);
			for (auto lab : labels)
				lines_labels[lab].push_back(tokens);
		}

		std::map<string, vector<vector<string>>> variant_lines;

		if (lines_labels.empty())
			variant_lines[""] = lines_nolabels;
		for (auto &it : lines_labels) {
			variant_lines[it.first] = lines_nolabels;
			variant_lines[it.first].insert(variant_lines[it.first].end(), it.second.begin(), it.second.end());
		}

		for (auto &it : variant_lines)
		{
			bram_t data;
			data.name = bram_name;
			data.variant = GetSize(brams[data.name]) + 1;
			data.groups = 0;
			data.abits = 0;
			data.dbits = 0;
			data.init = 0;

			for (auto &line_tokens : it.second)
			{
				tokens = line_tokens;

				if (parse_single_int("groups", data.groups))
					continue;

				if (parse_single_int("abits", data.abits))
					continue;

				if (parse_single_int("dbits", data.dbits))
					continue;

				if (parse_single_int("init", data.init))
					continue;

				if (parse_int_vect("ports", data.ports))
					continue;

				if (parse_int_vect("wrmode", data.wrmode))
					continue;

				if (parse_int_vect("enable", data.enable))
					continue;

				if (parse_int_vect("transp", data.transp))
					continue;

				if (parse_int_vect("clocks", data.clocks))
					continue;

				if (parse_int_vect("clkpol", data.clkpol))
					continue;

				syntax_error();
			}

			data.check_vectors();
			brams[data.name].push_back(data);
		}
	}

	void parse_match()
	{
		if (GetSize(tokens) != 2)
			syntax_error();

		match_t data;
		data.name = RTLIL::escape_id(tokens[1]);
		data.or_next_if_better = false;
		data.make_transp = false;
		data.make_outreg = false;
		data.shuffle_enable = 0;

		while (next_line())
		{
			if (!labels.empty())
				syntax_error();

			if (GetSize(tokens) == 1 && tokens[0] == "endmatch") {
				matches.push_back(data);
				break;
			}

			if (GetSize(tokens) == 3 && tokens[0] == "min") {
				data.min_limits[tokens[1]] = atoi(tokens[2].c_str());
				continue;
			}

			if (GetSize(tokens) == 3 && tokens[0] == "max") {
				data.max_limits[tokens[1]] = atoi(tokens[2].c_str());
				continue;
			}

			if (GetSize(tokens) == 2 && tokens[0] == "shuffle_enable" && GetSize(tokens[1]) == 1 && 'A' <= tokens[1][0] && tokens[1][0] <= 'Z') {
				data.shuffle_enable = tokens[1][0];
				continue;
			}

			if (GetSize(tokens) == 1 && tokens[0] == "make_transp") {
				data.make_transp = true;
				continue;
			}

			if (GetSize(tokens) == 1 && tokens[0] == "make_outreg") {
				data.make_transp = true;
				data.make_outreg = true;
				continue;
			}

			if (GetSize(tokens) == 1 && tokens[0] == "or_next_if_better") {
				data.or_next_if_better = true;
				continue;
			}

			if (GetSize(tokens) >= 2 && tokens[0] == "attribute") {
				data.attr = RTLIL::escape_id(tokens[1]);
				if (GetSize(tokens) > 2)
					data.value = tokens[2];
				continue;
			}

			syntax_error();
		}
	}

	void parse(string filename)
	{
		rewrite_filename(filename);
		infile.open(filename);
		linecount = 0;

		if (infile.fail())
			log_error("Can't open rules file `%s'.\n", filename.c_str());

		while (next_line())
		{
			if (!labels.empty())
				syntax_error();

			if (tokens[0] == "bram") {
				parse_bram();
				continue;
			}

			if (tokens[0] == "match") {
				parse_match();
				continue;
			}

			syntax_error();
		}

		infile.close();
	}
};

bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram, const rules_t::match_t &match, dict<string, int> &match_properties, int mode)
{
	Module *module = cell->module;

	auto portinfos = bram.make_portinfos();
	int dup_count = 1;

	pair<SigBit, bool> make_transp_clk;
	bool enable_make_transp = false;
	int make_transp_enbits = 0;

	dict<int, pair<SigBit, bool>> clock_domains;
	dict<int, bool> clock_polarities;
	dict<int, bool> read_transp;
	pool<int> clocks_wr_ports;
	pool<int> clkpol_wr_ports;
	int clocks_max = 0;
	int clkpol_max = 0;
	int transp_max = 0;

	clock_polarities[0] = false;
	clock_polarities[1] = true;

	for (auto &pi : portinfos) {
		if (pi.wrmode) {
			clocks_wr_ports.insert(pi.clocks);
			if (pi.clkpol > 1)
				clkpol_wr_ports.insert(pi.clkpol);
		}
		clocks_max = max(clocks_max, pi.clocks);
		clkpol_max = max(clkpol_max, pi.clkpol);
		transp_max = max(transp_max, pi.transp);
	}

	log("    Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant);
	// bram.dump_config();

	int mem_size = cell->getParam("\\SIZE").as_int();
	int mem_abits = cell->getParam("\\ABITS").as_int();
	int mem_width = cell->getParam("\\WIDTH").as_int();
	// int mem_offset = cell->getParam("\\OFFSET").as_int();

	bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
	vector<Const> initdata;

	if (cell_init) {
		Const initparam = cell->getParam("\\INIT");
		initdata.reserve(mem_size);
		for (int i=0; i < mem_size; i++)
			initdata.push_back(initparam.extract(mem_width*i, mem_width, State::Sx));
	}

	int wr_ports = cell->getParam("\\WR_PORTS").as_int();
	auto wr_clken = SigSpec(cell->getParam("\\WR_CLK_ENABLE"));
	auto wr_clkpol = SigSpec(cell->getParam("\\WR_CLK_POLARITY"));
	wr_clken.extend_u0(wr_ports);
	wr_clkpol.extend_u0(wr_ports);

	SigSpec wr_en = cell->getPort("\\WR_EN");
	SigSpec wr_clk = cell->getPort("\\WR_CLK");
	SigSpec wr_data = cell->getPort("\\WR_DATA");
	SigSpec wr_addr = cell->getPort("\\WR_ADDR");

	int rd_ports = cell->getParam("\\RD_PORTS").as_int();
	auto rd_clken = SigSpec(cell->getParam("\\RD_CLK_ENABLE"));
	auto rd_clkpol = SigSpec(cell->getParam("\\RD_CLK_POLARITY"));
	auto rd_transp = SigSpec(cell->getParam("\\RD_TRANSPARENT"));
	rd_clken.extend_u0(rd_ports);
	rd_clkpol.extend_u0(rd_ports);
	rd_transp.extend_u0(rd_ports);

	SigSpec rd_en = cell->getPort("\\RD_EN");
	SigSpec rd_clk = cell->getPort("\\RD_CLK");
	SigSpec rd_data = cell->getPort("\\RD_DATA");
	SigSpec rd_addr = cell->getPort("\\RD_ADDR");

	if (match.shuffle_enable && bram.dbits >= portinfos.at(match.shuffle_enable - 'A').enable*2 && portinfos.at(match.shuffle_enable - 'A').enable > 0 && wr_ports > 0)
	{
		int bucket_size = bram.dbits / portinfos.at(match.shuffle_enable - 'A').enable;
		log("      Shuffle bit order to accommodate enable buckets of size %d..\n", bucket_size);

		// extract unshuffled data/enable bits

		std::vector<SigSpec> old_wr_en;
		std::vector<SigSpec> old_wr_data;
		std::vector<SigSpec> old_rd_data;

		for (int i = 0; i < wr_ports; i++) {
			old_wr_en.push_back(wr_en.extract(i*mem_width, mem_width));
			old_wr_data.push_back(wr_data.extract(i*mem_width, mem_width));
		}

		for (int i = 0; i < rd_ports; i++)
			old_rd_data.push_back(rd_data.extract(i*mem_width, mem_width));

		// analyze enable structure

		std::vector<SigSpec> en_order;
		dict<SigSpec, vector<int>> bits_wr_en;

		for (int i = 0; i < mem_width; i++) {
			SigSpec sig;
			for (int j = 0; j < wr_ports; j++)
				sig.append(old_wr_en[j][i]);
			if (bits_wr_en.count(sig) == 0)
				en_order.push_back(sig);
			bits_wr_en[sig].push_back(i);
		}

		// re-create memory ports

		std::vector<SigSpec> new_wr_en(GetSize(old_wr_en));
		std::vector<SigSpec> new_wr_data(GetSize(old_wr_data));
		std::vector<SigSpec> new_rd_data(GetSize(old_rd_data));
		std::vector<std::vector<State>> new_initdata;
		std::vector<int> shuffle_map;

		if (cell_init)
			new_initdata.resize(mem_size);

		for (auto &it : en_order)
		{
			auto &bits = bits_wr_en.at(it);
			int buckets = (GetSize(bits) + bucket_size - 1) / bucket_size;
			int fillbits = buckets*bucket_size - GetSize(bits);
			SigBit fillbit;

			for (int i = 0; i < GetSize(bits); i++) {
				for (int j = 0; j < wr_ports; j++) {
					new_wr_en[j].append(old_wr_en[j][bits[i]]);
					new_wr_data[j].append(old_wr_data[j][bits[i]]);
					fillbit = old_wr_en[j][bits[i]];
				}
				for (int j = 0; j < rd_ports; j++)
					new_rd_data[j].append(old_rd_data[j][bits[i]]);
				if (cell_init) {
					for (int j = 0; j < mem_size; j++)
						new_initdata[j].push_back(initdata[j][bits[i]]);
				}
				shuffle_map.push_back(bits[i]);
			}

			for (int i = 0; i < fillbits; i++) {
				for (int j = 0; j < wr_ports; j++) {
					new_wr_en[j].append(fillbit);
					new_wr_data[j].append(State::S0);
				}
				for (int j = 0; j < rd_ports; j++)
					new_rd_data[j].append(State::Sx);
				if (cell_init) {
					for (int j = 0; j < mem_size; j++)
						new_initdata[j].push_back(State::Sx);
				}
				shuffle_map.push_back(-1);
			}
		}

		log("      Results of bit order shuffling:");
		for (int v : shuffle_map)
			log(" %d", v);
		log("\n");

		// update mem_*, wr_*, and rd_* variables

		mem_width = GetSize(new_wr_en.front());
		wr_en = SigSpec(0, wr_ports * mem_width);
		wr_data = SigSpec(0, wr_ports * mem_width);
		rd_data = SigSpec(0, rd_ports * mem_width);

		for (int i = 0; i < wr_ports; i++) {
			wr_en.replace(i*mem_width, new_wr_en[i]);
			wr_data.replace(i*mem_width, new_wr_data[i]);
		}

		for (int i = 0; i < rd_ports; i++)
			rd_data.replace(i*mem_width, new_rd_data[i]);

		if (cell_init) {
			for (int i = 0; i < mem_size; i++)
				initdata[i] = Const(new_initdata[i]);
		}
	}

	// assign write ports
	pair<SigBit, bool> wr_clkdom;
	for (int cell_port_i = 0, bram_port_i = 0; cell_port_i < wr_ports; cell_port_i++)
	{
		bool clken = wr_clken[cell_port_i] == State::S1;
		bool clkpol = wr_clkpol[cell_port_i] == State::S1;
		SigBit clksig = wr_clk[cell_port_i];

		pair<SigBit, bool> clkdom(clksig, clkpol);
		if (!clken)
			clkdom = pair<SigBit, bool>(State::S1, false);
		wr_clkdom = clkdom;
		log("      Write port #%d is in clock domain %s%s.\n",
				cell_port_i, clkdom.second ? "" : "!",
				clken ? log_signal(clkdom.first) : "~async~");

		for (; bram_port_i < GetSize(portinfos); bram_port_i++)
		{
			auto &pi = portinfos[bram_port_i];
			make_transp_enbits = pi.enable;
			make_transp_clk = clkdom;

			if (pi.wrmode != 1)
		skip_bram_wport:
				continue;

			if (clken) {
				if (pi.clocks == 0) {
					log("        Bram port %c%d has incompatible clock type.\n", pi.group + 'A', pi.index + 1);
					goto skip_bram_wport;
				}
				if (clock_domains.count(pi.clocks) && clock_domains.at(pi.clocks) != clkdom) {
					log("        Bram port %c%d is in a different clock domain.\n", pi.group + 'A', pi.index + 1);
					goto skip_bram_wport;
				}
				if (clock_polarities.count(pi.clkpol) && clock_polarities.at(pi.clkpol) != clkpol) {
					log("        Bram port %c%d has incompatible clock polarity.\n", pi.group + 'A', pi.index + 1);
					goto skip_bram_wport;
				}
			} else {
				if (pi.clocks != 0) {
					log("        Bram port %c%d has incompatible clock type.\n", pi.group + 'A', pi.index + 1);
					goto skip_bram_wport;
				}
			}

			SigSpec sig_en;
			SigBit last_en_bit = State::S1;
			for (int i = 0; i < mem_width; i++) {
				if (pi.enable && i % (bram.dbits / pi.enable) == 0) {
					last_en_bit = wr_en[i + cell_port_i*mem_width];
					sig_en.append(last_en_bit);
				}
				if (last_en_bit != wr_en[i + cell_port_i*mem_width]) {
					log("        Bram port %c%d has incompatible enable structure.\n", pi.group + 'A', pi.index + 1);
					goto skip_bram_wport;
				}
			}

			log("        Mapped to bram port %c%d.\n", pi.group + 'A', pi.index + 1);
			pi.mapped_port = cell_port_i;

			if (clken) {
				clock_domains[pi.clocks] = clkdom;
				clock_polarities[pi.clkpol] = clkdom.second;
				pi.sig_clock = clkdom.first;
				pi.effective_clkpol = clkdom.second;
			}

			pi.sig_en = sig_en;
			pi.sig_addr = wr_addr.extract(cell_port_i*mem_abits, mem_abits);
			pi.sig_data = wr_data.extract(cell_port_i*mem_width, mem_width);

			bram_port_i++;
			goto mapped_wr_port;
		}

		log("        Failed to map write port #%d.\n", cell_port_i);
		return false;
	mapped_wr_port:;
	}

	// housekeeping stuff for growing more read ports and restarting read port assignments

	int grow_read_ports_cursor = -1;
	bool try_growing_more_read_ports = false;
	auto backup_clock_domains = clock_domains;
	auto backup_clock_polarities = clock_polarities;

	if (0) {
grow_read_ports:;
		vector<rules_t::portinfo_t> new_portinfos;
		for (auto &pi : portinfos) {
			if (pi.wrmode == 0) {
				pi.mapped_port = -1;
				pi.sig_clock = SigBit();
				pi.sig_addr = SigSpec();
				pi.sig_data = SigSpec();
				pi.sig_en = SigSpec();
				pi.make_outreg = false;
				pi.make_transp = false;
			}
			new_portinfos.push_back(pi);
			if (pi.dupidx == dup_count-1) {
				if (pi.clocks && !clocks_wr_ports[pi.clocks])
					pi.clocks += clocks_max;
				if (pi.clkpol > 1 && !clkpol_wr_ports[pi.clkpol])
					pi.clkpol += clkpol_max;
				if (pi.transp > 1)
					pi.transp += transp_max;
				pi.dupidx++;
				new_portinfos.push_back(pi);
			}
		}
		try_growing_more_read_ports = false;
		portinfos.swap(new_portinfos);
		clock_domains = backup_clock_domains;
		clock_polarities = backup_clock_polarities;
		dup_count++;
	}

	read_transp.clear();
	read_transp[0] = false;
	read_transp[1] = true;

	// assign read ports

	for (int cell_port_i = 0; cell_port_i < rd_ports; cell_port_i++)
	{
		bool clken = rd_clken[cell_port_i] == State::S1;
		bool clkpol = rd_clkpol[cell_port_i] == State::S1;
		bool transp = rd_transp[cell_port_i] == State::S1;
		SigBit clksig = rd_clk[cell_port_i];

		if (wr_ports == 0)
			transp = false;

		pair<SigBit, bool> clkdom(clksig, clkpol);
		if (!clken)
			clkdom = pair<SigBit, bool>(State::S1, false);

		log("      Read port #%d is in clock domain %s%s.\n",
				cell_port_i, clkdom.second ? "" : "!",
				clken ? log_signal(clkdom.first) : "~async~");

		for (int bram_port_i = 0; bram_port_i < GetSize(portinfos); bram_port_i++)
		{
			auto &pi = portinfos[bram_port_i];

			if (pi.wrmode != 0 || pi.mapped_port >= 0)
		skip_bram_rport:
				continue;

			if (clken) {
				if (pi.clocks == 0) {
					if (match.make_outreg) {
						pi.make_outreg = true;
						goto skip_bram_rport_clkcheck;
					}
					log("        Bram port %c%d.%d has incompatible clock type.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
					goto skip_bram_rport;
				}
				if (clock_domains.count(pi.clocks) && clock_domains.at(pi.clocks) != clkdom) {
					log("        Bram port %c%d.%d is in a different clock domain.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
					goto skip_bram_rport;
				}
				if (clock_polarities.count(pi.clkpol) && clock_polarities.at(pi.clkpol) != clkpol) {
					log("        Bram port %c%d.%d has incompatible clock polarity.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
					goto skip_bram_rport;
				}
				if (rd_en[cell_port_i] != State::S1 && pi.enable == 0) {
					log("        Bram port %c%d.%d has no read enable input.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
					goto skip_bram_rport;
				}
			skip_bram_rport_clkcheck:
				if (read_transp.count(pi.transp) && read_transp.at(pi.transp) != transp) {
					if (match.make_transp && wr_ports <= 1) {
						pi.make_transp = true;
						if (pi.clocks != 0) {
							if (wr_ports == 1 && wr_clkdom != clkdom) {								
								log("        Bram port %c%d.%d cannot have soft transparency logic added as read and write clock domains differ.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
								goto skip_bram_rport;
							}
							enable_make_transp = true;
						}
					} else {
						log("        Bram port %c%d.%d has incompatible read transparency.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
						goto skip_bram_rport;
					}
				}
			} else {
				if (pi.clocks != 0) {
					log("        Bram port %c%d.%d has incompatible clock type.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
					goto skip_bram_rport;
				}
			}

			log("        Mapped to bram port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
			pi.mapped_port = cell_port_i;

			if (clken) {
				clock_domains[pi.clocks] = clkdom;
				clock_polarities[pi.clkpol] = clkdom.second;
				if (!pi.make_transp)
					read_transp[pi.transp] = transp;
				pi.sig_clock = clkdom.first;
				pi.sig_en = rd_en[cell_port_i];
				pi.effective_clkpol = clkdom.second;
			}

			pi.sig_addr = rd_addr.extract(cell_port_i*mem_abits, mem_abits);
			pi.sig_data = rd_data.extract(cell_port_i*mem_width, mem_width);

			if (grow_read_ports_cursor < cell_port_i) {
				grow_read_ports_cursor = cell_port_i;
				try_growing_more_read_ports = true;
			}

			goto mapped_rd_port;
		}

		log("        Failed to map read port #%d.\n", cell_port_i);
		if (try_growing_more_read_ports) {
			log("      Growing more read ports by duplicating bram cells.\n");
			goto grow_read_ports;
		}
		return false;
	mapped_rd_port:;
	}

	// update properties and re-check conditions

	if (mode <= 1)
	{
		match_properties["dups"] = dup_count;
		match_properties["waste"] = match_properties["dups"] * match_properties["bwaste"];

		int cells = ((mem_width + bram.dbits - 1) / bram.dbits) * ((mem_size + (1 << bram.abits) - 1) / (1 << bram.abits));
		match_properties["efficiency"] = (100 * match_properties["bits"]) / (dup_count * cells * bram.dbits * (1 << bram.abits));

		match_properties["dcells"] = ((mem_width + bram.dbits - 1) / bram.dbits);
		match_properties["acells"] = ((mem_size + (1 << bram.abits) - 1) / (1 << bram.abits));
		match_properties["cells"] = match_properties["dcells"] *  match_properties["acells"] * match_properties["dups"];

		log("      Updated properties: dups=%d waste=%d efficiency=%d\n",
				match_properties["dups"], match_properties["waste"], match_properties["efficiency"]);

		for (auto it : match.min_limits) {
			if (!match_properties.count(it.first))
				log_error("Unknown property '%s' in match rule for bram type %s.\n",
						it.first.c_str(), log_id(match.name));
			if (match_properties[it.first] >= it.second)
				continue;
			log("    Rule for bram type %s rejected: requirement 'min %s %d' not met.\n",
					log_id(match.name), it.first.c_str(), it.second);
			return false;
		}
		for (auto it : match.max_limits) {
			if (!match_properties.count(it.first))
				log_error("Unknown property '%s' in match rule for bram type %s.\n",
						it.first.c_str(), log_id(match.name));
			if (match_properties[it.first] <= it.second)
				continue;
			log("    Rule for bram type %s rejected: requirement 'max %s %d' not met.\n",
					log_id(match.name), it.first.c_str(), it.second);
			return false;
		}

		if (!match.attr.empty()) {
			auto it = cell->attributes.find(match.attr);
			if (it == cell->attributes.end()) {
				if (!match.value.empty())
					log("    Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n",
							log_id(match.name), log_id(match.attr), match.value.decode_string().c_str());
					return false;
			}
			else {
				if (it->second != match.value) {
					log("    Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n",
							log_id(match.name), log_id(match.attr), match.value.decode_string().c_str());
					return false;
				}
			}
		}

		if (mode == 1)
			return true;
	}

	// prepare variant parameters

	dict<IdString, Const> variant_params;
	for (auto &other_bram : rules.brams.at(bram.name))
		bram.find_variant_params(variant_params, other_bram);

	// actually replace that memory cell

	dict<SigSpec, pair<SigSpec, SigSpec>> dout_cache;

	for (int grid_d = 0; grid_d*bram.dbits < mem_width; grid_d++)
	{
		SigSpec mktr_wraddr, mktr_wrdata, mktr_wrdata_q;
		vector<SigSpec> mktr_wren;

		if (enable_make_transp) {
			mktr_wraddr = module->addWire(NEW_ID, bram.abits);
			mktr_wrdata = module->addWire(NEW_ID, bram.dbits);
			mktr_wrdata_q = module->addWire(NEW_ID, bram.dbits);
			module->addDff(NEW_ID, make_transp_clk.first, mktr_wrdata, mktr_wrdata_q, make_transp_clk.second);
			for (int grid_a = 0; grid_a*(1 << bram.abits) < mem_size; grid_a++)
				mktr_wren.push_back(module->addWire(NEW_ID, make_transp_enbits));
		}

		for (int grid_a = 0; grid_a*(1 << bram.abits) < mem_size; grid_a++)
		for (int dupidx = 0; dupidx < dup_count; dupidx++)
		{
			Cell *c = module->addCell(module->uniquify(stringf("%s.%d.%d.%d", cell->name.c_str(), grid_d, grid_a, dupidx)), bram.name);
			log("      Creating %s cell at grid position <%d %d %d>: %s\n", log_id(bram.name), grid_d, grid_a, dupidx, log_id(c));

			for (auto &vp : variant_params)
				c->setParam(vp.first, vp.second);

			if (cell_init) {
				int init_offset = grid_a*(1 << bram.abits);
				int init_shift = grid_d*bram.dbits;
				int init_size = (1 << bram.abits);
				Const initparam(State::Sx, init_size*bram.dbits);
				for (int i = 0; i < init_size; i++) {
					State padding = State::Sx;
					for (int j = 0; j < bram.dbits; j++)
						if (init_offset+i < GetSize(initdata) && init_shift+j < GetSize(initdata[init_offset+i]))
							initparam[i*bram.dbits+j] = initdata[init_offset+i][init_shift+j];
						else
							initparam[i*bram.dbits+j] = padding;
				}
				c->setParam("\\INIT", initparam);
			}

			for (auto &pi : portinfos)
			{
				if (pi.dupidx != dupidx)
					continue;

				string prefix = stringf("%c%d", pi.group + 'A', pi.index + 1);
				const char *pf = prefix.c_str();

				if (pi.clocks && (!c->hasPort(stringf("\\CLK%d", (pi.clocks-1) % clocks_max + 1)) || pi.sig_clock.wire)) {
					c->setPort(stringf("\\CLK%d", (pi.clocks-1) % clocks_max + 1), pi.sig_clock);
					if (pi.clkpol > 1 && pi.sig_clock.wire)
						c->setParam(stringf("\\CLKPOL%d", (pi.clkpol-1) % clkpol_max + 1), clock_polarities.at(pi.clkpol));
					if (pi.transp > 1 && pi.sig_clock.wire)
						c->setParam(stringf("\\TRANSP%d", (pi.transp-1) % transp_max + 1), read_transp.at(pi.transp));
				}

				SigSpec addr_ok;
				if (GetSize(pi.sig_addr) > bram.abits) {
					SigSpec extra_addr = pi.sig_addr.extract(bram.abits, GetSize(pi.sig_addr) - bram.abits);
					SigSpec extra_addr_sel = SigSpec(grid_a, GetSize(extra_addr));
					addr_ok = module->Eq(NEW_ID, extra_addr, extra_addr_sel);
				}

				if (pi.enable)
				{
					SigSpec sig_en = pi.sig_en;

					if (pi.wrmode == 1) {
						sig_en.extend_u0((grid_d+1) * pi.enable);
						sig_en = sig_en.extract(grid_d * pi.enable, pi.enable);
					}

					if (!addr_ok.empty())
						sig_en = module->Mux(NEW_ID, SigSpec(0, GetSize(sig_en)), sig_en, addr_ok);

					c->setPort(stringf("\\%sEN", pf), sig_en);

					if (pi.wrmode == 1 && enable_make_transp)
						module->connect(mktr_wren[grid_a], sig_en);
				}

				SigSpec sig_addr = pi.sig_addr;
				sig_addr.extend_u0(bram.abits);
				c->setPort(stringf("\\%sADDR", pf), sig_addr);

				if (pi.wrmode == 1 && enable_make_transp && grid_a == 0)
					module->connect(mktr_wraddr, sig_addr);

				SigSpec sig_data = pi.sig_data;
				sig_data.extend_u0((grid_d+1) * bram.dbits);
				sig_data = sig_data.extract(grid_d * bram.dbits, bram.dbits);

				if (pi.wrmode == 1) {
					c->setPort(stringf("\\%sDATA", pf), sig_data);
					if (enable_make_transp && grid_a == 0)
						module->connect(mktr_wrdata, sig_data);
				} else {
					SigSpec bram_dout = module->addWire(NEW_ID, bram.dbits);
					c->setPort(stringf("\\%sDATA", pf), bram_dout);
					if (pi.make_outreg && pi.make_transp) {
						log("        Moving output register to address for transparent port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);
						SigSpec sig_addr_q = module->addWire(NEW_ID, bram.abits);
						module->addDff(NEW_ID, pi.sig_clock, sig_addr, sig_addr_q, pi.effective_clkpol);
						c->setPort(stringf("\\%sADDR", pf), sig_addr_q);
					} else if (pi.make_outreg) {
						SigSpec bram_dout_q = module->addWire(NEW_ID, bram.dbits);
						if (!pi.sig_en.empty())
							bram_dout = module->Mux(NEW_ID, bram_dout_q, bram_dout, pi.sig_en);
						module->addDff(NEW_ID, pi.sig_clock, bram_dout, bram_dout_q, pi.effective_clkpol);
						bram_dout = bram_dout_q;
					} else if (pi.make_transp) {
						log("        Adding extra logic for transparent port %c%d.%d.\n", pi.group + 'A', pi.index + 1, pi.dupidx + 1);

						SigSpec transp_en_d = module->Mux(NEW_ID, SigSpec(0, make_transp_enbits),
								mktr_wren[grid_a], module->Eq(NEW_ID, mktr_wraddr, sig_addr));

						SigSpec transp_en_q = module->addWire(NEW_ID, make_transp_enbits);
						module->addDff(NEW_ID, make_transp_clk.first, transp_en_d, transp_en_q, make_transp_clk.second);

						for (int i = 0; i < make_transp_enbits; i++) {
							int en_width = bram.dbits / make_transp_enbits;
							SigSpec orig_bram_dout = bram_dout.extract(i * en_width, en_width);
							SigSpec bypass_dout = mktr_wrdata_q.extract(i * en_width, en_width);
							bram_dout.replace(i * en_width, module->Mux(NEW_ID, orig_bram_dout, bypass_dout, transp_en_q[i]));
						}
					}

					for (int i = bram.dbits-1; i >= 0; i--)
						if (sig_data[i].wire == nullptr) {
							sig_data.remove(i);
							bram_dout.remove(i);
						}

					SigSpec addr_ok_q = addr_ok;
					if ((pi.clocks || pi.make_outreg) && !addr_ok.empty()) {
						addr_ok_q = module->addWire(NEW_ID);
						if (!pi.sig_en.empty())
							addr_ok = module->Mux(NEW_ID, addr_ok_q, addr_ok, pi.sig_en);
						module->addDff(NEW_ID, pi.sig_clock, addr_ok, addr_ok_q, pi.effective_clkpol);
					}

					dout_cache[sig_data].first.append(addr_ok_q);
					dout_cache[sig_data].second.append(bram_dout);
				}
			}
		}
	}

	for (auto &it : dout_cache)
	{
		if (it.second.first.empty())
		{
			log_assert(GetSize(it.first) == GetSize(it.second.second));
			module->connect(it.first, it.second.second);
		}
		else
		{
			log_assert(GetSize(it.first)*GetSize(it.second.first) == GetSize(it.second.second));
			module->addPmux(NEW_ID, SigSpec(State::Sx, GetSize(it.first)), it.second.second, it.second.first, it.first);
		}
	}

	module->remove(cell);
	return true;
}

void handle_cell(Cell *cell, const rules_t &rules)
{
	log("Processing %s.%s:\n", log_id(cell->module), log_id(cell));

	bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();

	dict<string, int> match_properties;
	match_properties["words"]  = cell->getParam("\\SIZE").as_int();
	match_properties["abits"]  = cell->getParam("\\ABITS").as_int();
	match_properties["dbits"]  = cell->getParam("\\WIDTH").as_int();
	match_properties["wports"] = cell->getParam("\\WR_PORTS").as_int();
	match_properties["rports"] = cell->getParam("\\RD_PORTS").as_int();
	match_properties["bits"]   = match_properties["words"] * match_properties["dbits"];
	match_properties["ports"]  = match_properties["wports"] + match_properties["rports"];

	log("  Properties:");
	for (auto &it : match_properties)
		log(" %s=%d", it.first.c_str(), it.second);
	log("\n");

	pool<pair<IdString, int>> failed_brams;
	dict<pair<int, int>, tuple<int, int, int>> best_rule_cache;

	for (int i = 0; i < GetSize(rules.matches); i++)
	{
		auto &match = rules.matches.at(i);

		if (!rules.brams.count(rules.matches[i].name))
			log_error("No bram description for resource %s found!\n", log_id(rules.matches[i].name));

		for (int vi = 0; vi < GetSize(rules.brams.at(match.name)); vi++)
		{
			auto &bram = rules.brams.at(match.name).at(vi);
			bool or_next_if_better = match.or_next_if_better || vi+1 < GetSize(rules.brams.at(match.name));

			if (failed_brams.count(pair<IdString, int>(bram.name, bram.variant)))
				continue;

			int avail_rd_ports = 0;
			int avail_wr_ports = 0;
			for (int j = 0; j < bram.groups; j++) {
				if (GetSize(bram.wrmode) < j || bram.wrmode.at(j) == 0)
					avail_rd_ports += GetSize(bram.ports) < j ? bram.ports.at(j) : 0;
				if (GetSize(bram.wrmode) < j || bram.wrmode.at(j) != 0)
					avail_wr_ports += GetSize(bram.ports) < j ? bram.ports.at(j) : 0;
			}

			log("  Checking rule #%d for bram type %s (variant %d):\n", i+1, log_id(bram.name), bram.variant);
			log("    Bram geometry: abits=%d dbits=%d wports=%d rports=%d\n", bram.abits, bram.dbits, avail_wr_ports, avail_rd_ports);

			int dups = avail_rd_ports ? (match_properties["rports"] + avail_rd_ports - 1) / avail_rd_ports : 1;
			match_properties["dups"] = dups;

			log("    Estimated number of duplicates for more read ports: dups=%d\n", match_properties["dups"]);

			int aover = match_properties["words"] % (1 << bram.abits);
			int awaste = aover ? (1 << bram.abits) - aover : 0;
			match_properties["awaste"] = awaste;

			int dover = match_properties["dbits"] % bram.dbits;
			int dwaste = dover ? bram.dbits - dover : 0;
			match_properties["dwaste"] = dwaste;

			int bwaste = awaste * bram.dbits + dwaste * (1 << bram.abits) - awaste * dwaste;
			match_properties["bwaste"] = bwaste;

			int waste = match_properties["dups"] * bwaste;
			match_properties["waste"] = waste;

			int cells = ((match_properties["dbits"] + bram.dbits - 1) / bram.dbits) * ((match_properties["words"] + (1 << bram.abits) - 1) / (1 << bram.abits));
			int efficiency = (100 * match_properties["bits"]) / (dups * cells * bram.dbits * (1 << bram.abits));
			match_properties["efficiency"] = efficiency;

			log("    Metrics for %s: awaste=%d dwaste=%d bwaste=%d waste=%d efficiency=%d\n",
					log_id(match.name), awaste, dwaste, bwaste, waste, efficiency);

			if (cell_init && bram.init == 0) {
				log("    Rule #%d for bram type %s (variant %d) rejected: cannot be initialized.\n",
						i+1, log_id(bram.name), bram.variant);
				goto next_match_rule;
			}

			for (auto it : match.min_limits) {
				if (it.first == "waste" || it.first == "dups" || it.first == "acells" || it.first == "dcells" || it.first == "cells")
					continue;
				if (!match_properties.count(it.first))
					log_error("Unknown property '%s' in match rule for bram type %s.\n",
							it.first.c_str(), log_id(match.name));
				if (match_properties[it.first] >= it.second)
					continue;
				log("    Rule #%d for bram type %s (variant %d) rejected: requirement 'min %s %d' not met.\n",
						i+1, log_id(bram.name), bram.variant, it.first.c_str(), it.second);
				goto next_match_rule;
			}

			for (auto it : match.max_limits) {
				if (it.first == "acells" || it.first == "dcells" || it.first == "cells")
					continue;
				if (!match_properties.count(it.first))
					log_error("Unknown property '%s' in match rule for bram type %s.\n",
							it.first.c_str(), log_id(match.name));
				if (match_properties[it.first] <= it.second)
					continue;
				log("    Rule #%d for bram type %s (variant %d) rejected: requirement 'max %s %d' not met.\n",
						i+1, log_id(bram.name), bram.variant, it.first.c_str(), it.second);
				goto next_match_rule;
			}

			if (!match.attr.empty()) {
				auto it = cell->attributes.find(match.attr);
				if (it == cell->attributes.end()) {
					if (!match.value.empty()) {
						log("    Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n",
								log_id(match.name), log_id(match.attr), match.value.decode_string().c_str());
						goto next_match_rule;
					}
				}
				else {
					if (it->second != match.value) {
						log("    Rule for bram type %s rejected: requirement 'attribute %s=\"%s\"' not met.\n",
								log_id(match.name), log_id(match.attr), match.value.decode_string().c_str());
						goto next_match_rule;
					}
				}
			}

			log("    Rule #%d for bram type %s (variant %d) accepted.\n", i+1, log_id(bram.name), bram.variant);

			if (or_next_if_better || !best_rule_cache.empty())
			{
				if (or_next_if_better && i+1 == GetSize(rules.matches) && vi+1 == GetSize(rules.brams.at(match.name)))
					log_error("Found 'or_next_if_better' in last match rule.\n");

				if (!replace_cell(cell, rules, bram, match, match_properties, 1)) {
					log("    Mapping to bram type %s failed.\n", log_id(match.name));
					failed_brams.insert(pair<IdString, int>(bram.name, bram.variant));
					goto next_match_rule;
				}

				log("      Storing for later selection.\n");
				best_rule_cache[pair<int, int>(i, vi)] = tuple<int, int, int>(match_properties["efficiency"], -match_properties["cells"], -match_properties["acells"]);

		next_match_rule:
				if (or_next_if_better || best_rule_cache.empty())
					continue;

				log("  Selecting best of %d rules:\n", GetSize(best_rule_cache));
				pair<int, int> best_rule = best_rule_cache.begin()->first;

				for (auto &it : best_rule_cache) {
					if (it.second > best_rule_cache[best_rule])
						best_rule = it.first;
					log("    Efficiency for rule %d.%d: efficiency=%d, cells=%d, acells=%d\n", it.first.first+1, it.first.second+1,
							std::get<0>(it.second), -std::get<1>(it.second), -std::get<2>(it.second));
				}

				log("    Selected rule %d.%d with efficiency %d.\n", best_rule.first+1, best_rule.second+1, std::get<0>(best_rule_cache[best_rule]));
				best_rule_cache.clear();

				auto &best_bram = rules.brams.at(rules.matches.at(best_rule.first).name).at(best_rule.second);
				if (!replace_cell(cell, rules, best_bram, rules.matches.at(best_rule.first), match_properties, 2))
					log_error("Mapping to bram type %s (variant %d) after pre-selection failed.\n", log_id(best_bram.name), best_bram.variant);
				return;
			}

			if (!replace_cell(cell, rules, bram, match, match_properties, 0)) {
				log("    Mapping to bram type %s failed.\n", log_id(match.name));
				failed_brams.insert(pair<IdString, int>(bram.name, bram.variant));
				goto next_match_rule;
			}
			return;
		}
	}

	log("  No acceptable bram resources found.\n");
}

struct MemoryBramPass : public Pass {
	MemoryBramPass() : Pass("memory_bram", "map memories to block rams") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    memory_bram -rules <rule_file> [selection]\n");
		log("\n");
		log("This pass converts the multi-port $mem memory cells into block ram instances.\n");
		log("The given rules file describes the available resources and how they should be\n");
		log("used.\n");
		log("\n");
		log("The rules file contains a set of block ram description and a sequence of match\n");
		log("rules. A block ram description looks like this:\n");
		log("\n");
		log("    bram RAMB1024X32     # name of BRAM cell\n");
		log("      init 1             # set to '1' if BRAM can be initialized\n");
		log("      abits 10           # number of address bits\n");
		log("      dbits 32           # number of data bits\n");
		log("      groups 2           # number of port groups\n");
		log("      ports  1 1         # number of ports in each group\n");
		log("      wrmode 1 0         # set to '1' if this groups is write ports\n");
		log("      enable 4 1         # number of enable bits\n");
		log("      transp 0 2         # transparent (for read ports)\n");
		log("      clocks 1 2         # clock configuration\n");
		log("      clkpol 2 2         # clock polarity configuration\n");
		log("    endbram\n");
		log("\n");
		log("For the option 'transp' the value 0 means non-transparent, 1 means transparent\n");
		log("and a value greater than 1 means configurable. All groups with the same\n");
		log("value greater than 1 share the same configuration bit.\n");
		log("\n");
		log("For the option 'clocks' the value 0 means non-clocked, and a value greater\n");
		log("than 0 means clocked. All groups with the same value share the same clock\n");
		log("signal.\n");
		log("\n");
		log("For the option 'clkpol' the value 0 means negative edge, 1 means positive edge\n");
		log("and a value greater than 1 means configurable. All groups with the same value\n");
		log("greater than 1 share the same configuration bit.\n");
		log("\n");
		log("Using the same bram name in different bram blocks will create different variants\n");
		log("of the bram. Verilog configuration parameters for the bram are created as needed.\n");
		log("\n");
		log("It is also possible to create variants by repeating statements in the bram block\n");
		log("and appending '@<label>' to the individual statements.\n");
		log("\n");
		log("A match rule looks like this:\n");
		log("\n");
		log("    match RAMB1024X32\n");
		log("      max waste 16384    # only use this bram if <= 16k ram bits are unused\n");
		log("      min efficiency 80  # only use this bram if efficiency is at least 80%%\n");
		log("    endmatch\n");
		log("\n");
		log("It is possible to match against the following values with min/max rules:\n");
		log("\n");
		log("    words  ........  number of words in memory in design\n");
		log("    abits  ........  number of address bits on memory in design\n");
		log("    dbits  ........  number of data bits on memory in design\n");
		log("    wports  .......  number of write ports on memory in design\n");
		log("    rports  .......  number of read ports on memory in design\n");
		log("    ports  ........  number of ports on memory in design\n");
		log("    bits  .........  number of bits in memory in design\n");
		log("    dups ..........  number of duplications for more read ports\n");
		log("\n");
		log("    awaste  .......  number of unused address slots for this match\n");
		log("    dwaste  .......  number of unused data bits for this match\n");
		log("    bwaste  .......  number of unused bram bits for this match\n");
		log("    waste  ........  total number of unused bram bits (bwaste*dups)\n");
		log("    efficiency  ...  total percentage of used and non-duplicated bits\n");
		log("\n");
		log("    acells  .......  number of cells in 'address-direction'\n");
		log("    dcells  .......  number of cells in 'data-direction'\n");
		log("    cells  ........  total number of cells (acells*dcells*dups)\n");
		log("\n");
		log("A match containing the condition 'attribute' followed by a name and optional\n");
		log("value requires that the memory contains the given attribute name and value\n");
		log("(if specified) or that the attribute is not present or the value is empty (if\n");
		log("value is not specified\n).");
		log("\n");
		log("The interface for the created bram instances is derived from the bram\n");
		log("description. Use 'techmap' to convert the created bram instances into\n");
		log("instances of the actual bram cells of your target architecture.\n");
		log("\n");
		log("A match containing the command 'or_next_if_better' is only used if it\n");
		log("has a higher efficiency than the next match (and the one after that if\n");
		log("the next also has 'or_next_if_better' set, and so forth).\n");
		log("\n");
		log("A match containing the command 'make_transp' will add external circuitry\n");
		log("to simulate 'transparent read', if necessary.\n");
		log("\n");
		log("A match containing the command 'make_outreg' will add external flip-flops\n");
		log("to implement synchronous read ports, if necessary.\n");
		log("\n");
		log("A match containing the command 'shuffle_enable A' will re-organize\n");
		log("the data bits to accommodate the enable pattern of port A.\n");
		log("\n");
	}
	void execute(vector<string> args, Design *design) YS_OVERRIDE
	{
		rules_t rules;

		log_header(design, "Executing MEMORY_BRAM pass (mapping $mem cells to block memories).\n");

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

		for (auto mod : design->selected_modules())
		for (auto cell : mod->selected_cells())
			if (cell->type == "$mem")
				handle_cell(cell, rules);
	}
} MemoryBramPass;

PRIVATE_NAMESPACE_END
