diff options
Diffstat (limited to 'passes/techmap')
| -rw-r--r-- | passes/techmap/abc9.cc | 145 | ||||
| -rw-r--r-- | passes/techmap/aigmap.cc | 46 | 
2 files changed, 117 insertions, 74 deletions
| diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 09d6e9670..27106cc5d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -71,21 +71,21 @@ RTLIL::Module *module;  bool clk_polarity, en_polarity;  RTLIL::SigSpec clk_sig, en_sig; -inline std::string remap_name(RTLIL::IdString abc_name) +inline std::string remap_name(RTLIL::IdString abc9_name)  { -	return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1); +	return stringf("$abc$%d$%s", map_autoidx, abc9_name.c_str()+1);  }  void handle_loops(RTLIL::Design *design)  { -	Pass::call(design, "scc -set_attr abc_scc_id {}"); +	Pass::call(design, "scc -set_attr abc9_scc_id {}");  	// For every unique SCC found, (arbitrarily) find the first  	// cell in the component, and select (and mark) all its output  	// wires  	pool<RTLIL::Const> ids_seen;  	for (auto cell : module->cells()) { -		auto it = cell->attributes.find(ID(abc_scc_id)); +		auto it = cell->attributes.find(ID(abc9_scc_id));  		if (it != cell->attributes.end()) {  			auto r = ids_seen.insert(it->second);  			if (r.second) { @@ -105,7 +105,7 @@ void handle_loops(RTLIL::Design *design)  							log_assert(w->port_input);  							log_assert(b.offset < GetSize(w));  						} -						w->set_bool_attribute(ID(abc_scc_break)); +						w->set_bool_attribute(ID(abc9_scc_break));  						module->swap_names(b.wire, w);  						c.second = RTLIL::SigBit(w, b.offset);  					} @@ -118,7 +118,7 @@ void handle_loops(RTLIL::Design *design)  	module->fixup_ports();  } -std::string add_echos_to_abc_cmd(std::string str) +std::string add_echos_to_abc9_cmd(std::string str)  {  	std::string new_str, token;  	for (size_t i = 0; i < str.size(); i++) { @@ -140,7 +140,7 @@ std::string add_echos_to_abc_cmd(std::string str)  	return new_str;  } -std::string fold_abc_cmd(std::string str) +std::string fold_abc9_cmd(std::string str)  {  	std::string token, new_str = "          ";  	int char_counter = 10; @@ -184,7 +184,7 @@ std::string replace_tempdir(std::string text, std::string tempdir_name, bool sho  	return text;  } -struct abc_output_filter +struct abc9_output_filter  {  	bool got_cr;  	int escape_seq_state; @@ -192,7 +192,7 @@ struct abc_output_filter  	std::string tempdir_name;  	bool show_tempdir; -	abc_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir) +	abc9_output_filter(std::string tempdir_name, bool show_tempdir) : tempdir_name(tempdir_name), show_tempdir(show_tempdir)  	{  		got_cr = false;  		escape_seq_state = 0; @@ -247,7 +247,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  		bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str,  		bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode,  		bool show_tempdir, std::string box_file, std::string lut_file, -		std::string wire_delay, const dict<int,IdString> &box_lookup +		std::string wire_delay, const dict<int,IdString> &box_lookup, bool nomfs  )  {  	module = current_module; @@ -293,68 +293,72 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  	log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n",  			module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str()); -	std::string abc_script; +	std::string abc9_script;  	if (!lut_costs.empty()) { -		abc_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str()); +		abc9_script += stringf("read_lut %s/lutdefs.txt; ", tempdir_name.c_str());  		if (!box_file.empty()) -			abc_script += stringf("read_box -v %s; ", box_file.c_str()); +			abc9_script += stringf("read_box -v %s; ", box_file.c_str());  	}  	else  	if (!lut_file.empty()) { -		abc_script += stringf("read_lut %s; ", lut_file.c_str()); +		abc9_script += stringf("read_lut %s; ", lut_file.c_str());  		if (!box_file.empty()) -			abc_script += stringf("read_box -v %s; ", box_file.c_str()); +			abc9_script += stringf("read_box -v %s; ", box_file.c_str());  	}  	else  		log_abort(); -	abc_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str()); +	abc9_script += stringf("&read %s/input.xaig; &ps; ", tempdir_name.c_str());  	if (!script_file.empty()) {  		if (script_file[0] == '+') {  			for (size_t i = 1; i < script_file.size(); i++)  				if (script_file[i] == '\'') -					abc_script += "'\\''"; +					abc9_script += "'\\''";  				else if (script_file[i] == ',') -					abc_script += " "; +					abc9_script += " ";  				else -					abc_script += script_file[i]; +					abc9_script += script_file[i];  		} else -			abc_script += stringf("source %s", script_file.c_str()); +			abc9_script += stringf("source %s", script_file.c_str());  	} else if (!lut_costs.empty() || !lut_file.empty()) {  		//bool all_luts_cost_same = true;  		//for (int this_cost : lut_costs)  		//	if (this_cost != lut_costs.front())  		//		all_luts_cost_same = false; -		abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT; +		abc9_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT;  		//if (all_luts_cost_same && !fast_mode) -		//	abc_script += "; lutpack {S}"; +		//	abc9_script += "; lutpack {S}";  	} else  		log_abort();  	//if (script_file.empty() && !delay_target.empty()) -	//	for (size_t pos = abc_script.find("dretime;"); pos != std::string::npos; pos = abc_script.find("dretime;", pos+1)) -	//		abc_script = abc_script.substr(0, pos) + "dretime; retime -o {D};" + abc_script.substr(pos+8); +	//	for (size_t pos = abc9_script.find("dretime;"); pos != std::string::npos; pos = abc9_script.find("dretime;", pos+1)) +	//		abc9_script = abc9_script.substr(0, pos) + "dretime; retime -o {D};" + abc9_script.substr(pos+8); -	for (size_t pos = abc_script.find("{D}"); pos != std::string::npos; pos = abc_script.find("{D}", pos)) -		abc_script = abc_script.substr(0, pos) + delay_target + abc_script.substr(pos+3); +	for (size_t pos = abc9_script.find("{D}"); pos != std::string::npos; pos = abc9_script.find("{D}", pos)) +		abc9_script = abc9_script.substr(0, pos) + delay_target + abc9_script.substr(pos+3); -	//for (size_t pos = abc_script.find("{S}"); pos != std::string::npos; pos = abc_script.find("{S}", pos)) -	//	abc_script = abc_script.substr(0, pos) + lutin_shared + abc_script.substr(pos+3); +	//for (size_t pos = abc9_script.find("{S}"); pos != std::string::npos; pos = abc9_script.find("{S}", pos)) +	//	abc9_script = abc9_script.substr(0, pos) + lutin_shared + abc9_script.substr(pos+3); -	for (size_t pos = abc_script.find("{W}"); pos != std::string::npos; pos = abc_script.find("{W}", pos)) -		abc_script = abc_script.substr(0, pos) + wire_delay + abc_script.substr(pos+3); +	for (size_t pos = abc9_script.find("{W}"); pos != std::string::npos; pos = abc9_script.find("{W}", pos)) +		abc9_script = abc9_script.substr(0, pos) + wire_delay + abc9_script.substr(pos+3); -	abc_script += stringf("; &write %s/output.aig", tempdir_name.c_str()); -	abc_script = add_echos_to_abc_cmd(abc_script); +	if (nomfs) +		for (size_t pos = abc9_script.find("&mfs"); pos != std::string::npos; pos = abc9_script.find("&mfs", pos)) +			abc9_script = abc9_script.erase(pos, strlen("&mfs")); -	for (size_t i = 0; i+1 < abc_script.size(); i++) -		if (abc_script[i] == ';' && abc_script[i+1] == ' ') -			abc_script[i+1] = '\n'; +	abc9_script += stringf("; &write %s/output.aig", tempdir_name.c_str()); +	abc9_script = add_echos_to_abc9_cmd(abc9_script); + +	for (size_t i = 0; i+1 < abc9_script.size(); i++) +		if (abc9_script[i] == ';' && abc9_script[i+1] == ' ') +			abc9_script[i+1] = '\n';  	FILE *f = fopen(stringf("%s/abc.script", tempdir_name.c_str()).c_str(), "wt"); -	fprintf(f, "%s\n", abc_script.c_str()); +	fprintf(f, "%s\n", abc9_script.c_str());  	fclose(f);  	if (dff_mode || !clk_str.empty()) @@ -420,7 +424,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  		// the expose operation -- remove them from PO/PI  		// and re-connecting them back together  		for (auto wire : module->wires()) { -			auto it = wire->attributes.find(ID(abc_scc_break)); +			auto it = wire->attributes.find(ID(abc9_scc_break));  			if (it != wire->attributes.end()) {  				wire->attributes.erase(it);  				log_assert(wire->port_output); @@ -450,22 +454,22 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  		log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str());  #ifndef YOSYS_LINK_ABC -		abc_output_filter filt(tempdir_name, show_tempdir); -		int ret = run_command(buffer, std::bind(&abc_output_filter::next_line, filt, std::placeholders::_1)); +		abc9_output_filter filt(tempdir_name, show_tempdir); +		int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1));  #else  		// These needs to be mutable, supposedly due to getopt -		char *abc_argv[5]; +		char *abc9_argv[5];  		string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); -		abc_argv[0] = strdup(exe_file.c_str()); -		abc_argv[1] = strdup("-s"); -		abc_argv[2] = strdup("-f"); -		abc_argv[3] = strdup(tmp_script_name.c_str()); -		abc_argv[4] = 0; -		int ret = Abc_RealMain(4, abc_argv); -		free(abc_argv[0]); -		free(abc_argv[1]); -		free(abc_argv[2]); -		free(abc_argv[3]); +		abc9_argv[0] = strdup(exe_file.c_str()); +		abc9_argv[1] = strdup("-s"); +		abc9_argv[2] = strdup("-f"); +		abc9_argv[3] = strdup(tmp_script_name.c_str()); +		abc9_argv[4] = 0; +		int ret = Abc_RealMain(4, abc9_argv); +		free(abc9_argv[0]); +		free(abc9_argv[1]); +		free(abc9_argv[2]); +		free(abc9_argv[3]);  #endif  		if (ret != 0)  			log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); @@ -513,7 +517,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  			signal = std::move(bits);  		} -		dict<IdString, bool> abc_box; +		dict<IdString, bool> abc9_box;  		vector<RTLIL::Cell*> boxes;  		for (const auto &it : module->cells_) {  			auto cell = it.second; @@ -521,10 +525,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  				module->remove(cell);  				continue;  			} -			auto jt = abc_box.find(cell->type); -			if (jt == abc_box.end()) { +			auto jt = abc9_box.find(cell->type); +			if (jt == abc9_box.end()) {  				RTLIL::Module* box_module = design->module(cell->type); -				jt = abc_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc_box_id)))).first; +				jt = abc9_box.insert(std::make_pair(cell->type, box_module && box_module->attributes.count(ID(abc9_box_id)))).first;  			}  			if (jt->second)  				boxes.emplace_back(cell); @@ -648,7 +652,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  					if (!conn.second.is_wire())  						continue;  					Wire *wire = conn.second.as_wire(); -					if (!wire->get_bool_attribute(ID(abc_padding))) +					if (!wire->get_bool_attribute(ID(abc9_padding)))  						continue;  					cell->unsetPort(conn.first);  					log_debug("Dropping padded port connection for %s (%s) .%s (%s )\n", log_id(cell), cell->type.c_str(), log_id(conn.first), log_signal(conn.second)); @@ -827,17 +831,17 @@ struct Abc9Pass : public Pass {  		log("        if no -script parameter is given, the following scripts are used:\n");  		log("\n");  		log("        for -lut/-luts (only one LUT size):\n"); -		log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); +		log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str());  		log("\n");  		log("        for -lut/-luts (different LUT sizes):\n"); -		log("%s\n", fold_abc_cmd(ABC_COMMAND_LUT).c_str()); +		log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT).c_str());  		log("\n");  		log("    -fast\n");  		log("        use different default scripts that are slightly faster (at the cost\n");  		log("        of output quality):\n");  		log("\n");  		log("        for -lut/-luts:\n"); -		log("%s\n", fold_abc_cmd(ABC_FAST_COMMAND_LUT).c_str()); +		log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str());  		log("\n");  		log("    -D <picoseconds>\n");  		log("        set delay target. the string {D} in the default scripts above is\n"); @@ -921,6 +925,7 @@ struct Abc9Pass : public Pass {  		std::string delay_target, lutin_shared = "-S 1", wire_delay;  		bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true;  		bool show_tempdir = false; +		bool nomfs = false;  		vector<int> lut_costs;  		markgroups = false; @@ -1043,6 +1048,10 @@ struct Abc9Pass : public Pass {  				wire_delay = "-W " + args[++argidx];  				continue;  			} +			if (arg == "-nomfs") { +				nomfs = true; +				continue; +			}  			break;  		}  		extra_args(args, argidx, design); @@ -1057,7 +1066,7 @@ struct Abc9Pass : public Pass {  		dict<int,IdString> box_lookup;  		for (auto m : design->modules()) { -			auto it = m->attributes.find(ID(abc_box_id)); +			auto it = m->attributes.find(ID(abc9_box_id));  			if (it == m->attributes.end())  				continue;  			if (m->name.begins_with("$paramod")) @@ -1065,7 +1074,7 @@ struct Abc9Pass : public Pass {  			auto id = it->second.as_int();  			auto r = box_lookup.insert(std::make_pair(id, m->name));  			if (!r.second) -				log_error("Module '%s' has the same abc_box_id = %d value as '%s'.\n", +				log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n",  						log_id(m), id, log_id(r.first->second));  			log_assert(r.second); @@ -1073,24 +1082,24 @@ struct Abc9Pass : public Pass {  			for (auto p : m->ports) {  				auto w = m->wire(p);  				log_assert(w); -				if (w->attributes.count(ID(abc_carry))) { +				if (w->attributes.count(ID(abc9_carry))) {  					if (w->port_input) {  						if (carry_in) -							log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m)); +							log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m));  						carry_in = w;  					}  					else if (w->port_output) {  						if (carry_out) -							log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m)); +							log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m));  						carry_out = w;  					}  				}  			}  			if (carry_in || carry_out) {  				if (carry_in && !carry_out) -					log_error("Module '%s' contains an 'abc_carry' input port but no output port.\n", log_id(m)); +					log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m));  				if (!carry_in && carry_out) -					log_error("Module '%s' contains an 'abc_carry' output port but no input port.\n", log_id(m)); +					log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m));  				// Make carry_in the last PI, and carry_out the last PO  				//   since ABC requires it this way  				auto &ports = m->ports; @@ -1118,7 +1127,7 @@ struct Abc9Pass : public Pass {  		for (auto mod : design->selected_modules())  		{ -			if (mod->attributes.count(ID(abc_box_id))) +			if (mod->attributes.count(ID(abc9_box_id)))  				continue;  			if (mod->processes.size() > 0) { @@ -1131,7 +1140,7 @@ struct Abc9Pass : public Pass {  			if (!dff_mode || !clk_str.empty()) {  				abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff,  						delay_target, lutin_shared, fast_mode, show_tempdir, -						box_file, lut_file, wire_delay, box_lookup); +						box_file, lut_file, wire_delay, box_lookup, nomfs);  				continue;  			} @@ -1277,7 +1286,7 @@ struct Abc9Pass : public Pass {  				en_sig = assign_map(std::get<3>(it.first));  				abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$",  						keepff, delay_target, lutin_shared, fast_mode, show_tempdir, -						box_file, lut_file, wire_delay, box_lookup); +						box_file, lut_file, wire_delay, box_lookup, nomfs);  				assign_map.set(mod);  			}  		} diff --git a/passes/techmap/aigmap.cc b/passes/techmap/aigmap.cc index 1d5e1286b..2ecb2f35a 100644 --- a/passes/techmap/aigmap.cc +++ b/passes/techmap/aigmap.cc @@ -27,6 +27,7 @@ struct AigmapPass : public Pass {  	AigmapPass() : Pass("aigmap", "map logic to and-inverter-graph circuit") { }  	void help() YS_OVERRIDE  	{ +		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|  		log("\n");  		log("    aigmap [options] [selection]\n");  		log("\n"); @@ -36,10 +37,15 @@ struct AigmapPass : public Pass {  		log("    -nand\n");  		log("        Enable creation of $_NAND_ cells\n");  		log("\n"); +		log("    -select\n"); +		log("        Overwrite replaced cells in the current selection with new $_AND_,\n"); +		log("        $_NOT_, and $_NAND_, cells\n"); + +		log("\n");  	}  	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE  	{ -		bool nand_mode = false; +		bool nand_mode = false, select_mode = false;  		log_header(design, "Executing AIGMAP pass (map logic to AIG).\n"); @@ -50,6 +56,10 @@ struct AigmapPass : public Pass {  				nand_mode = true;  				continue;  			} +			if (args[argidx] == "-select") { +				select_mode = true; +				continue; +			}  			break;  		}  		extra_args(args, argidx, design); @@ -62,6 +72,7 @@ struct AigmapPass : public Pass {  			dict<IdString, int> stat_not_replaced;  			int orig_num_cells = GetSize(module->cells()); +			pool<IdString> new_sel;  			for (auto cell : module->selected_cells())  			{  				Aig aig(cell); @@ -75,6 +86,8 @@ struct AigmapPass : public Pass {  				if (aig.name.empty()) {  					not_replaced_count++;  					stat_not_replaced[cell->type]++; +					if (select_mode) +						new_sel.insert(cell->name);  					continue;  				} @@ -95,19 +108,33 @@ struct AigmapPass : public Pass {  						SigBit A = sigs.at(node.left_parent);  						SigBit B = sigs.at(node.right_parent);  						if (nand_mode && node.inverter) { -							bit = module->NandGate(NEW_ID, A, B); +							bit = module->addWire(NEW_ID); +							auto gate = module->addNandGate(NEW_ID, A, B, bit); +							if (select_mode) +								new_sel.insert(gate->name); +  							goto skip_inverter;  						} else {  							pair<int, int> key(node.left_parent, node.right_parent);  							if (and_cache.count(key))  								bit = and_cache.at(key); -							else -								bit = module->AndGate(NEW_ID, A, B); +							else { +								bit = module->addWire(NEW_ID); +								auto gate = module->addAndGate(NEW_ID, A, B, bit); +								if (select_mode) +									new_sel.insert(gate->name); +							}  						}  					} -					if (node.inverter) -						bit = module->NotGate(NEW_ID, bit); +					if (node.inverter) { +						SigBit new_bit = module->addWire(NEW_ID); +						auto gate = module->addNotGate(NEW_ID, bit, new_bit); +						bit = new_bit; +						if (select_mode) +							new_sel.insert(gate->name); + +					}  				skip_inverter:  					for (auto &op : node.outports) @@ -142,6 +169,13 @@ struct AigmapPass : public Pass {  			for (auto cell : replaced_cells)  				module->remove(cell); + +			if (select_mode) { +				log_assert(!design->selection_stack.empty()); +				RTLIL::Selection& sel = design->selection_stack.back(); +				sel.selected_members[module->name] = std::move(new_sel); +			} +  		}  	}  } AigmapPass; | 
