mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	Merge pull request #1248 from YosysHQ/eddie/abc9_speedup
abc9: speedup by using using "clean" more efficiently
This commit is contained in:
		
						commit
						3414ee1e3f
					
				
					 4 changed files with 49 additions and 41 deletions
				
			
		| 
						 | 
				
			
			@ -621,8 +621,7 @@ struct XAigerWriter
 | 
			
		|||
			log_debug("boxNum = %d\n", GetSize(box_list));
 | 
			
		||||
			write_h_buffer(box_list.size());
 | 
			
		||||
 | 
			
		||||
			RTLIL::Module *holes_module = nullptr;
 | 
			
		||||
			holes_module = module->design->addModule("$__holes__");
 | 
			
		||||
			RTLIL::Module *holes_module = module->design->addModule("$__holes__");
 | 
			
		||||
			log_assert(holes_module);
 | 
			
		||||
 | 
			
		||||
			int port_id = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -719,27 +718,33 @@ struct XAigerWriter
 | 
			
		|||
				Pass::call(holes_module->design, "flatten -wb");
 | 
			
		||||
 | 
			
		||||
				// TODO: Should techmap/aigmap/check all lib_whitebox-es just once,
 | 
			
		||||
				// instead of per write_xaiger call
 | 
			
		||||
				//       instead of per write_xaiger call
 | 
			
		||||
				Pass::call(holes_module->design, "techmap");
 | 
			
		||||
				Pass::call(holes_module->design, "aigmap");
 | 
			
		||||
				for (auto cell : holes_module->cells())
 | 
			
		||||
					if (!cell->type.in("$_NOT_", "$_AND_"))
 | 
			
		||||
						log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n");
 | 
			
		||||
 | 
			
		||||
				Pass::call(holes_module->design, "clean -purge");
 | 
			
		||||
				holes_module->design->selection_stack.pop_back();
 | 
			
		||||
 | 
			
		||||
				// Move into a new (temporary) design so that "clean" will only
 | 
			
		||||
				// operate (and run checks on) this one module
 | 
			
		||||
				RTLIL::Design *holes_design = new RTLIL::Design;
 | 
			
		||||
				holes_module->design->modules_.erase(holes_module->name);
 | 
			
		||||
				holes_design->add(holes_module);
 | 
			
		||||
				Pass::call(holes_design, "clean -purge");
 | 
			
		||||
 | 
			
		||||
				std::stringstream a_buffer;
 | 
			
		||||
				XAigerWriter writer(holes_module, true /* holes_mode */);
 | 
			
		||||
				writer.write_aiger(a_buffer, false /*ascii_mode*/);
 | 
			
		||||
 | 
			
		||||
				holes_module->design->selection_stack.pop_back();
 | 
			
		||||
				delete holes_design;
 | 
			
		||||
 | 
			
		||||
				f << "a";
 | 
			
		||||
				std::string buffer_str = a_buffer.str();
 | 
			
		||||
				int32_t buffer_size_be = to_big_endian(buffer_str.size());
 | 
			
		||||
				f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
 | 
			
		||||
				f.write(buffer_str.data(), buffer_str.size());
 | 
			
		||||
				holes_module->design->remove(holes_module);
 | 
			
		||||
 | 
			
		||||
				log_pop();
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -337,7 +337,7 @@ static RTLIL::Wire* createWireIfNotExists(RTLIL::Module *module, unsigned litera
 | 
			
		|||
	return wire;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AigerReader::parse_xaiger()
 | 
			
		||||
void AigerReader::parse_xaiger(const dict<int,IdString> &box_lookup)
 | 
			
		||||
{
 | 
			
		||||
	std::string header;
 | 
			
		||||
	f >> header;
 | 
			
		||||
| 
						 | 
				
			
			@ -373,21 +373,6 @@ void AigerReader::parse_xaiger()
 | 
			
		|||
	if (n0)
 | 
			
		||||
		module->connect(n0, RTLIL::S0);
 | 
			
		||||
 | 
			
		||||
	dict<int,IdString> box_lookup;
 | 
			
		||||
	for (auto m : design->modules()) {
 | 
			
		||||
		auto it = m->attributes.find("\\abc_box_id");
 | 
			
		||||
		if (it == m->attributes.end())
 | 
			
		||||
			continue;
 | 
			
		||||
		if (m->name.begins_with("$paramod"))
 | 
			
		||||
			continue;
 | 
			
		||||
		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_id(m), id, log_id(r.first->second));
 | 
			
		||||
		log_assert(r.second);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Parse footer (symbol table, comments, etc.)
 | 
			
		||||
	std::string s;
 | 
			
		||||
	bool comment_seen = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -986,16 +971,17 @@ void AigerReader::post_process()
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	module->fixup_ports();
 | 
			
		||||
 | 
			
		||||
	// Insert into a new (temporary) design so that "clean" will only
 | 
			
		||||
	// operate (and run checks on) this one module
 | 
			
		||||
	RTLIL::Design *mapped_design = new RTLIL::Design;
 | 
			
		||||
	mapped_design->add(module);
 | 
			
		||||
	Pass::call(mapped_design, "clean");
 | 
			
		||||
	mapped_design->modules_.erase(module->name);
 | 
			
		||||
	delete mapped_design;
 | 
			
		||||
 | 
			
		||||
	design->add(module);
 | 
			
		||||
 | 
			
		||||
	design->selection_stack.emplace_back(false);
 | 
			
		||||
	RTLIL::Selection& sel = design->selection_stack.back();
 | 
			
		||||
	sel.select(module);
 | 
			
		||||
 | 
			
		||||
	Pass::call(design, "clean");
 | 
			
		||||
 | 
			
		||||
	design->selection_stack.pop_back();
 | 
			
		||||
 | 
			
		||||
	for (auto cell : module->cells().to_vector()) {
 | 
			
		||||
		if (cell->type != "$lut") continue;
 | 
			
		||||
		auto y_port = cell->getPort("\\Y").as_bit();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ struct AigerReader
 | 
			
		|||
 | 
			
		||||
    AigerReader(RTLIL::Design *design, std::istream &f, RTLIL::IdString module_name, RTLIL::IdString clk_name, std::string map_filename, bool wideports);
 | 
			
		||||
    void parse_aiger();
 | 
			
		||||
    void parse_xaiger();
 | 
			
		||||
    void parse_xaiger(const dict<int,IdString> &box_lookup);
 | 
			
		||||
    void parse_aiger_ascii();
 | 
			
		||||
    void parse_aiger_binary();
 | 
			
		||||
    void post_process();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ void handle_loops(RTLIL::Design *design)
 | 
			
		|||
{
 | 
			
		||||
	Pass::call(design, "scc -set_attr abc_scc_id {}");
 | 
			
		||||
 | 
			
		||||
        dict<IdString, vector<IdString>> abc_scc_break;
 | 
			
		||||
	dict<IdString, vector<IdString>> abc_scc_break;
 | 
			
		||||
 | 
			
		||||
	// For every unique SCC found, (arbitrarily) find the first
 | 
			
		||||
	// cell in the component, and select (and mark) all its output
 | 
			
		||||
| 
						 | 
				
			
			@ -290,7 +290,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)
 | 
			
		||||
		std::string wire_delay, const dict<int,IdString> &box_lookup)
 | 
			
		||||
{
 | 
			
		||||
	module = current_module;
 | 
			
		||||
	map_autoidx = autoidx++;
 | 
			
		||||
| 
						 | 
				
			
			@ -429,10 +429,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
 | 
			
		|||
		RTLIL::Selection& sel = design->selection_stack.back();
 | 
			
		||||
		sel.select(module);
 | 
			
		||||
 | 
			
		||||
		Pass::call(design, "aigmap");
 | 
			
		||||
 | 
			
		||||
		handle_loops(design);
 | 
			
		||||
 | 
			
		||||
		Pass::call(design, "aigmap");
 | 
			
		||||
 | 
			
		||||
		//log("Extracted %d gates and %d wires to a netlist network with %d inputs and %d outputs.\n",
 | 
			
		||||
		//		count_gates, GetSize(signal_list), count_input, count_output);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -476,7 +476,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
 | 
			
		|||
		}
 | 
			
		||||
		module->fixup_ports();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		log_header(design, "Executing ABC9.\n");
 | 
			
		||||
 | 
			
		||||
		if (!lut_costs.empty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -520,8 +519,9 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
 | 
			
		|||
 | 
			
		||||
		buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym");
 | 
			
		||||
		log_assert(!design->module("$__abc9__"));
 | 
			
		||||
 | 
			
		||||
		AigerReader reader(design, ifs, "$__abc9__", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */);
 | 
			
		||||
		reader.parse_xaiger();
 | 
			
		||||
		reader.parse_xaiger(box_lookup);
 | 
			
		||||
		ifs.close();
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
| 
						 | 
				
			
			@ -646,6 +646,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
 | 
			
		|||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				existing_cell = module->cell(c->name);
 | 
			
		||||
				log_assert(existing_cell);
 | 
			
		||||
				cell = module->addCell(remap_name(c->name), c->type);
 | 
			
		||||
				module->swap_names(cell, existing_cell);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -1081,6 +1082,21 @@ struct Abc9Pass : public Pass {
 | 
			
		|||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		dict<int,IdString> box_lookup;
 | 
			
		||||
		for (auto m : design->modules()) {
 | 
			
		||||
			auto it = m->attributes.find("\\abc_box_id");
 | 
			
		||||
			if (it == m->attributes.end())
 | 
			
		||||
				continue;
 | 
			
		||||
			if (m->name.begins_with("$paramod"))
 | 
			
		||||
				continue;
 | 
			
		||||
			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_id(m), id, log_id(r.first->second));
 | 
			
		||||
			log_assert(r.second);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
		{
 | 
			
		||||
			if (mod->attributes.count("\\abc_box_id"))
 | 
			
		||||
| 
						 | 
				
			
			@ -1096,7 +1112,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_file, lut_file, wire_delay, box_lookup);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1242,15 +1258,16 @@ 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_file, lut_file, wire_delay, box_lookup);
 | 
			
		||||
				assign_map.set(mod);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Pass::call(design, "clean");
 | 
			
		||||
 | 
			
		||||
		assign_map.clear();
 | 
			
		||||
 | 
			
		||||
		// The "clean" pass also contains a design->check() call
 | 
			
		||||
		Pass::call(design, "clean");
 | 
			
		||||
 | 
			
		||||
		log_pop();
 | 
			
		||||
	}
 | 
			
		||||
} Abc9Pass;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue