mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Merge branch 'eddie/abc9_refactor' of github.com:YosysHQ/yosys into eddie/abc9_refactor
This commit is contained in:
		
						commit
						11128dccb5
					
				
					 4 changed files with 92 additions and 109 deletions
				
			
		|  | @ -756,12 +756,6 @@ void AigerReader::post_process() | |||
| 	} | ||||
| 
 | ||||
| 	for (uint32_t i = 0; i < flopNum; i++) { | ||||
| 		log_assert(co_count < outputs.size()); | ||||
| 		Wire *wire = outputs[co_count++]; | ||||
| 		log_assert(wire); | ||||
| 		log_assert(wire->port_output); | ||||
| 		wire->port_output = false; | ||||
| 
 | ||||
| 		RTLIL::Wire *d = outputs[outputs.size() - flopNum + i]; | ||||
| 		log_assert(d); | ||||
| 		log_assert(d->port_output); | ||||
|  | @ -803,6 +797,7 @@ void AigerReader::post_process() | |||
| 						wire->port_input = false; | ||||
| 						module->connect(wire, existing); | ||||
| 					} | ||||
| 					log_debug(" -> %s\n", log_id(escaped_s)); | ||||
| 				} | ||||
| 				else if (index > 0) { | ||||
| 					std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index); | ||||
|  | @ -816,8 +811,8 @@ void AigerReader::post_process() | |||
| 						module->connect(wire, existing); | ||||
| 						wire->port_input = false; | ||||
| 					} | ||||
| 					log_debug(" -> %s\n", log_id(indexed_name)); | ||||
| 				} | ||||
| 				log_debug(" -> %s\n", log_id(wire)); | ||||
| 			} | ||||
| 			else if (type == "output") { | ||||
| 				log_assert(static_cast<unsigned>(variable + co_count) < outputs.size()); | ||||
|  | @ -839,6 +834,7 @@ void AigerReader::post_process() | |||
| 						module->connect(wire, existing); | ||||
| 						wire = existing; | ||||
| 					} | ||||
| 					log_debug(" -> %s\n", log_id(escaped_s)); | ||||
| 				} | ||||
| 				else if (index > 0) { | ||||
| 					std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index); | ||||
|  | @ -852,8 +848,8 @@ void AigerReader::post_process() | |||
| 						module->connect(wire, existing); | ||||
| 						wire->port_output = false; | ||||
| 					} | ||||
| 					log_debug(" -> %s\n", log_id(indexed_name)); | ||||
| 				} | ||||
| 				log_debug(" -> %s\n", log_id(wire)); | ||||
| 				int init; | ||||
| 				mf >> init; | ||||
| 				if (init < 2) | ||||
|  |  | |||
|  | @ -26,9 +26,6 @@ | |||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| #define XC7_WIRE_DELAY 300 // Number with which ABC will map a 6-input gate
 | ||||
|                            // to one LUT6 (instead of a LUT5 + LUT2)
 | ||||
| 
 | ||||
| struct Abc9Pass : public ScriptPass | ||||
| { | ||||
| 	Abc9Pass() : ScriptPass("abc9", "use ABC9 for technology mapping") { } | ||||
|  | @ -39,8 +36,9 @@ struct Abc9Pass : public ScriptPass | |||
| 		log("\n"); | ||||
| 		log("    abc9 [options] [selection]\n"); | ||||
| 		log("\n"); | ||||
| 		log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); | ||||
| 		log("library to a target architecture. Only fully-selected modules are supported.\n"); | ||||
| 		log("This script pass performs a sequence of commands to facilitate the use of the ABC\n"); | ||||
| 		log("tool [1] for technology mapping of the current design to a target FPGA\n"); | ||||
| 		log("architecture. Only fully-selected modules are supported.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -exe <command>\n"); | ||||
| #ifdef ABCEXTERNAL | ||||
|  | @ -59,21 +57,13 @@ struct Abc9Pass : public ScriptPass | |||
| 		log("        replaced with blanks before the string is passed to ABC.\n"); | ||||
| 		log("\n"); | ||||
| 		log("        if no -script parameter is given, the following scripts are used:\n"); | ||||
| 		log("\n"); | ||||
| 		log("        for -lut/-luts (only one LUT size):\n"); | ||||
| 		// FIXME
 | ||||
| 		//log("%s\n", fold_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str());
 | ||||
| 		log("\n"); | ||||
| 		log("        for -lut/-luts (different LUT sizes):\n"); | ||||
| 		// FIXME
 | ||||
| 		//FIXME:
 | ||||
| 		//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"); | ||||
| 		// FIXME
 | ||||
| 		//FIXME:
 | ||||
| 		//log("%s\n", fold_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str());
 | ||||
| 		log("\n"); | ||||
| 		log("    -D <picoseconds>\n"); | ||||
|  |  | |||
|  | @ -289,10 +289,12 @@ struct Abc9ExePass : public Pass { | |||
| 	{ | ||||
| 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||
| 		log("\n"); | ||||
| 		log("    abc9_exe [options] [selection]\n"); | ||||
| 		log("    abc9_exe [options]\n"); | ||||
| 		log("\n"); | ||||
| 		log("This pass uses the ABC tool [1] for technology mapping of yosys's internal gate\n"); | ||||
| 		log("library to a target architecture.\n"); | ||||
| 		log(" \n"); | ||||
| 		log("This pass uses the ABC tool [1] for technology mapping of the top module\n"); | ||||
| 		log("(according to the (* top *) attribute or if only one module is currently selected)\n"); | ||||
| 		log("to a target FPGA architecture.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -exe <command>\n"); | ||||
| #ifdef ABCEXTERNAL | ||||
|  | @ -311,18 +313,11 @@ struct Abc9ExePass : public Pass { | |||
| 		log("        replaced with blanks before the string is passed to ABC.\n"); | ||||
| 		log("\n"); | ||||
| 		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_abc9_cmd(ABC_COMMAND_LUT /*"; lutpack {S}"*/).c_str()); | ||||
| 		log("\n"); | ||||
| 		log("        for -lut/-luts (different LUT sizes):\n"); | ||||
| 		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_abc9_cmd(ABC_FAST_COMMAND_LUT).c_str()); | ||||
| 		log("\n"); | ||||
| 		log("    -D <picoseconds>\n"); | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ void break_scc(RTLIL::Module *module) | |||
| 	//   its output ports into a new PO, and drive its previous
 | ||||
| 	//   sinks with a new PI
 | ||||
| 	pool<RTLIL::Const> ids_seen; | ||||
| 	for (auto cell : module->selected_cells()) { | ||||
| 	for (auto cell : module->cells()) { | ||||
| 		auto it = cell->attributes.find(ID(abc9_scc_id)); | ||||
| 		if (it == cell->attributes.end()) | ||||
| 			continue; | ||||
|  | @ -116,7 +116,7 @@ void prep_dff(RTLIL::Module *module) | |||
| 	typedef SigSpec clkdomain_t; | ||||
| 	dict<clkdomain_t, int> clk_to_mergeability; | ||||
| 
 | ||||
| 	for (auto cell : module->selected_cells()) { | ||||
| 	for (auto cell : module->cells()) { | ||||
| 		if (cell->type != "$__ABC9_FF_") | ||||
| 			continue; | ||||
| 
 | ||||
|  | @ -179,11 +179,8 @@ void prep_dff(RTLIL::Module *module) | |||
| 				++it; | ||||
| 		} | ||||
| 
 | ||||
| 		for (auto &conn : holes_module->connections_) { | ||||
| 			auto it = replace.find(conn); | ||||
| 			if (it != replace.end()) | ||||
| 				conn = it->second; | ||||
| 		} | ||||
| 		for (auto &conn : holes_module->connections_) | ||||
| 			conn = replace.at(conn, conn); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -198,7 +195,7 @@ void prep_holes(RTLIL::Module *module, bool dff) | |||
| 	TopoSort<IdString, RTLIL::sort_by_id_str> toposort; | ||||
| 	bool abc9_box_seen = false; | ||||
| 
 | ||||
| 	for (auto cell : module->selected_cells()) { | ||||
| 	for (auto cell : module->cells()) { | ||||
| 		if (cell->type == "$__ABC9_FF_") | ||||
| 			continue; | ||||
| 
 | ||||
|  | @ -236,21 +233,23 @@ void prep_holes(RTLIL::Module *module, bool dff) | |||
| 			for (auto user_cell : it.second) | ||||
| 				toposort.edge(driver_cell, user_cell); | ||||
| 
 | ||||
| #if 0 | ||||
| 	toposort.analyze_loops = true; | ||||
| #endif | ||||
| 	if (ys_debug(1)) | ||||
| 		toposort.analyze_loops = true; | ||||
| 
 | ||||
| 	bool no_loops YS_ATTRIBUTE(unused) = toposort.sort(); | ||||
| #if 0 | ||||
| 	unsigned i = 0; | ||||
| 	for (auto &it : toposort.loops) { | ||||
| 		log("  loop %d\n", i++); | ||||
| 		for (auto cell_name : it) { | ||||
| 			auto cell = module->cell(cell_name); | ||||
| 			log_assert(cell); | ||||
| 			log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute().c_str()); | ||||
| 
 | ||||
| 	if (ys_debug(1)) { | ||||
| 		unsigned i = 0; | ||||
| 		for (auto &it : toposort.loops) { | ||||
| 			log("  loop %d\n", i++); | ||||
| 			for (auto cell_name : it) { | ||||
| 				auto cell = module->cell(cell_name); | ||||
| 				log_assert(cell); | ||||
| 				log("\t%s (%s @ %s)\n", log_id(cell), log_id(cell->type), cell->get_src_attribute().c_str()); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	log_assert(no_loops); | ||||
| 
 | ||||
| 	vector<Cell*> box_list; | ||||
|  | @ -488,11 +487,13 @@ void reintegrate(RTLIL::Module *module) | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto it = module->cells_.begin(); it != module->cells_.end(); ) | ||||
| 		if (it->second->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) | ||||
| 			it = module->cells_.erase(it); | ||||
| 		else | ||||
| 			++it; | ||||
| 	std::vector<Cell*> boxes; | ||||
| 	for (auto cell : module->cells().to_vector()) { | ||||
| 		if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_))) | ||||
| 			module->remove(cell); | ||||
| 		else if (cell->attributes.erase("\\abc9_box_seq")) | ||||
| 			boxes.emplace_back(cell); | ||||
| 	} | ||||
| 
 | ||||
| 	dict<SigBit, pool<IdString>> bit_drivers, bit_users; | ||||
| 	TopoSort<IdString, RTLIL::sort_by_id_str> toposort; | ||||
|  | @ -504,7 +505,6 @@ void reintegrate(RTLIL::Module *module) | |||
| 	{ | ||||
| 		toposort.node(mapped_cell->name); | ||||
| 
 | ||||
| 		RTLIL::Cell *cell = nullptr; | ||||
| 		if (mapped_cell->type == ID($_NOT_)) { | ||||
| 			RTLIL::SigBit a_bit = mapped_cell->getPort(ID::A); | ||||
| 			RTLIL::SigBit y_bit = mapped_cell->getPort(ID::Y); | ||||
|  | @ -536,7 +536,7 @@ void reintegrate(RTLIL::Module *module) | |||
| 				if (!driver_lut) { | ||||
| 					// If a driver couldn't be found (could be from PI or box CI)
 | ||||
| 					// then implement using a LUT
 | ||||
| 					cell = module->addLut(remap_name(stringf("%s$lut", mapped_cell->name.c_str())), | ||||
| 					RTLIL::Cell *cell = module->addLut(remap_name(stringf("%s$lut", mapped_cell->name.c_str())), | ||||
| 							RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), | ||||
| 							RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), | ||||
| 							RTLIL::Const::from_string("01")); | ||||
|  | @ -548,10 +548,9 @@ void reintegrate(RTLIL::Module *module) | |||
| 			} | ||||
| 			continue; | ||||
| 		} | ||||
| 		cell_stats[mapped_cell->type]++; | ||||
| 
 | ||||
| 		RTLIL::Cell *existing_cell = nullptr; | ||||
| 		if (mapped_cell->type.in(ID($lut), ID($__ABC9_FF_))) { | ||||
| 			// Convert buffer into direct connection
 | ||||
| 			if (mapped_cell->type == ID($lut) && | ||||
| 					GetSize(mapped_cell->getPort(ID::A)) == 1 && | ||||
| 					mapped_cell->getParam(ID(LUT)) == RTLIL::Const::from_string("01")) { | ||||
|  | @ -561,22 +560,48 @@ void reintegrate(RTLIL::Module *module) | |||
| 				log_abort(); | ||||
| 				continue; | ||||
| 			} | ||||
| 			cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); | ||||
| 			RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); | ||||
| 			cell->parameters = mapped_cell->parameters; | ||||
| 			cell->attributes = mapped_cell->attributes; | ||||
| 
 | ||||
| 			for (auto &mapped_conn : mapped_cell->connections()) { | ||||
| 				RTLIL::SigSpec newsig; | ||||
| 				for (auto c : mapped_conn.second.chunks()) { | ||||
| 					if (c.width == 0) | ||||
| 						continue; | ||||
| 					//log_assert(c.width == 1);
 | ||||
| 					if (c.wire) | ||||
| 						c.wire = module->wires_.at(remap_name(c.wire->name)); | ||||
| 					newsig.append(c); | ||||
| 				} | ||||
| 				cell->setPort(mapped_conn.first, newsig); | ||||
| 
 | ||||
| 				if (cell->input(mapped_conn.first)) { | ||||
| 					for (auto i : newsig) | ||||
| 						bit2sinks[i].push_back(cell); | ||||
| 					for (auto i : mapped_conn.second) | ||||
| 						bit_users[i].insert(mapped_cell->name); | ||||
| 				} | ||||
| 				if (cell->output(mapped_conn.first)) | ||||
| 					for (auto i : mapped_conn.second) | ||||
| 						bit_drivers[i].insert(mapped_cell->name); | ||||
| 			} | ||||
| 		} | ||||
| 		else { | ||||
| 			existing_cell = module->cell(mapped_cell->name); | ||||
| 			RTLIL::Cell *existing_cell = module->cell(mapped_cell->name); | ||||
| 			log_assert(existing_cell); | ||||
| 			log_assert(mapped_cell->type.begins_with("$__boxid")); | ||||
| 
 | ||||
| 			if (mapped_cell->type.begins_with("$__boxid")) { | ||||
| 				auto type = box_lookup.at(mapped_cell->type, IdString()); | ||||
| 				if (type == IdString()) | ||||
| 					log_error("No module with abc9_box_id = %s found.\n", mapped_cell->type.c_str() + strlen("$__boxid")); | ||||
| 				mapped_cell->type = type; | ||||
| 			} | ||||
| 			cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); | ||||
| 		} | ||||
| 			auto type = box_lookup.at(mapped_cell->type, IdString()); | ||||
| 			if (type == IdString()) | ||||
| 				log_error("No module with abc9_box_id = %s found.\n", mapped_cell->type.c_str() + strlen("$__boxid")); | ||||
| 			mapped_cell->type = type; | ||||
| 
 | ||||
| 			RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type); | ||||
| 			cell->parameters = existing_cell->parameters; | ||||
| 			cell->attributes = existing_cell->attributes; | ||||
| 			module->swap_names(cell, existing_cell); | ||||
| 
 | ||||
| 		if (existing_cell) { | ||||
| 			auto it = mapped_cell->connections_.find("\\i"); | ||||
| 			log_assert(it != mapped_cell->connections_.end()); | ||||
| 			SigSpec inputs = std::move(it->second); | ||||
|  | @ -635,45 +660,13 @@ void reintegrate(RTLIL::Module *module) | |||
| 						bit2sinks[i].push_back(cell); | ||||
| 			} | ||||
| 		} | ||||
| 		else { | ||||
| 			for (auto &mapped_conn : mapped_cell->connections()) { | ||||
| 				RTLIL::SigSpec newsig; | ||||
| 				for (auto c : mapped_conn.second.chunks()) { | ||||
| 					if (c.width == 0) | ||||
| 						continue; | ||||
| 					//log_assert(c.width == 1);
 | ||||
| 					if (c.wire) | ||||
| 						c.wire = module->wires_.at(remap_name(c.wire->name)); | ||||
| 					newsig.append(c); | ||||
| 				} | ||||
| 				cell->setPort(mapped_conn.first, newsig); | ||||
| 
 | ||||
| 				if (cell->input(mapped_conn.first)) { | ||||
| 					for (auto i : newsig) | ||||
| 						bit2sinks[i].push_back(cell); | ||||
| 					for (auto i : mapped_conn.second) | ||||
| 						bit_users[i].insert(mapped_cell->name); | ||||
| 				} | ||||
| 				if (cell->output(mapped_conn.first)) | ||||
| 					for (auto i : mapped_conn.second) | ||||
| 						bit_drivers[i].insert(mapped_cell->name); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if (existing_cell) { | ||||
| 			cell->parameters = existing_cell->parameters; | ||||
| 			cell->attributes = existing_cell->attributes; | ||||
| 			if (cell->attributes.erase("\\abc9_box_seq")) { | ||||
| 				module->swap_names(cell, existing_cell); | ||||
| 				module->remove(existing_cell); | ||||
| 			} | ||||
| 		} | ||||
| 		else { | ||||
| 			cell->parameters = mapped_cell->parameters; | ||||
| 			cell->attributes = mapped_cell->attributes; | ||||
| 		} | ||||
| 		cell_stats[mapped_cell->type]++; | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto cell : boxes) | ||||
| 		module->remove(cell); | ||||
| 
 | ||||
| 	// Copy connections (and rename) from mapped_mod to module
 | ||||
| 	for (auto conn : mapped_mod->connections()) { | ||||
| 		if (!conn.first.is_fully_const()) { | ||||
|  | @ -851,6 +844,12 @@ struct Abc9OpsPass : public Pass { | |||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		if (!(break_scc_mode || unbreak_scc_mode || prep_dff_mode || reintegrate_mode)) | ||||
| 			log_cmd_error("At least one of -{,un}break_scc, -prep_{dff,holes}, -reintegrate must be specified.\n"); | ||||
| 
 | ||||
| 		if (dff_mode && !prep_holes_mode) | ||||
| 			log_cmd_error("'-dff' option is only relevant for -prep_holes.\n"); | ||||
| 
 | ||||
| 		for (auto mod : design->selected_modules()) { | ||||
| 			if (mod->get_bool_attribute("\\abc9_holes")) | ||||
| 				continue; | ||||
|  | @ -860,6 +859,9 @@ struct Abc9OpsPass : public Pass { | |||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			if (!design->selected_whole_module(mod)) | ||||
| 				log_error("Can't handle partially selected module %s!\n", log_id(mod)); | ||||
| 
 | ||||
| 			if (break_scc_mode) | ||||
| 				break_scc(mod); | ||||
| 			if (unbreak_scc_mode) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue