/*
 *  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;
	};

	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;
			}

			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 (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;
			}

			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("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
