mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/eddie/abc9_refactor' into eddie/abc9_required
This commit is contained in:
		
						commit
						f9aae90e7a
					
				
					 11 changed files with 198 additions and 156 deletions
				
			
		|  | @ -98,7 +98,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; | ||||
|  | @ -174,7 +174,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; | ||||
| 
 | ||||
|  | @ -202,14 +202,16 @@ void prep_dff(RTLIL::Module *module) | |||
| 
 | ||||
| 	RTLIL::Module *holes_module = design->module(stringf("%s$holes", module->name.c_str())); | ||||
| 	if (holes_module) { | ||||
| 		dict<SigSig, SigSig> replace; | ||||
| 		SigMap sigmap(holes_module); | ||||
| 
 | ||||
| 		dict<SigSpec, SigSpec> replace; | ||||
| 		for (auto it = holes_module->cells_.begin(); it != holes_module->cells_.end(); ) { | ||||
| 			auto cell = it->second; | ||||
| 			if (cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_", | ||||
| 						"$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_")) { | ||||
| 				SigBit D = cell->getPort("\\D"); | ||||
| 				SigBit Q = cell->getPort("\\Q"); | ||||
| 				// Remove the DFF cell from what needs to be a combinatorial box
 | ||||
| 				// Remove the $_DFF_* cell from what needs to be a combinatorial box
 | ||||
| 				it = holes_module->cells_.erase(it); | ||||
| 				Wire *port; | ||||
| 				if (GetSize(Q.wire) == 1) | ||||
|  | @ -217,10 +219,10 @@ void prep_dff(RTLIL::Module *module) | |||
| 				else | ||||
| 					port = holes_module->wire(stringf("$abc%s[%d]", Q.wire->name.c_str(), Q.offset)); | ||||
| 				log_assert(port); | ||||
| 				// Prepare to replace "assign <port> = DFF.Q;" with "assign <port> = DFF.D;"
 | ||||
| 				//   in order to extract the combinatorial control logic that feeds the box
 | ||||
| 				// Prepare to replace "assign <port> = $_DFF_*.Q;" with "assign <port> = $_DFF_*.D;"
 | ||||
| 				//   in order to extract just the combinatorial control logic that feeds the box
 | ||||
| 				//   (i.e. clock enable, synchronous reset, etc.)
 | ||||
| 				replace.insert(std::make_pair(SigSig(port,Q), SigSig(port,D))); | ||||
| 				replace.insert(std::make_pair(Q,D)); | ||||
| 				// Since `flatten` above would have created wires named "<cell>.Q",
 | ||||
| 				//   extract the pre-techmap cell name
 | ||||
| 				auto pos = Q.wire->name.str().rfind("."); | ||||
|  | @ -228,7 +230,7 @@ void prep_dff(RTLIL::Module *module) | |||
| 				IdString driver = Q.wire->name.substr(0, pos); | ||||
| 				// And drive the signal that was previously driven by "DFF.Q" (typically
 | ||||
| 				//   used to implement clock-enable functionality) with the "<cell>.$abc9_currQ"
 | ||||
| 				//   wire (which itself is driven an input port) we inserted above
 | ||||
| 				//   wire (which itself is driven an by input port) we inserted above
 | ||||
| 				Wire *currQ = holes_module->wire(stringf("%s.abc9_ff.Q", driver.c_str())); | ||||
| 				log_assert(currQ); | ||||
| 				holes_module->connect(Q, currQ); | ||||
|  | @ -237,11 +239,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.second = replace.at(sigmap(conn.second), conn.second); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -256,7 +255,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; | ||||
| 
 | ||||
|  | @ -294,21 +293,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; | ||||
|  | @ -377,100 +378,97 @@ void prep_holes(RTLIL::Module *module, bool dff) | |||
| 		log_assert(orig_box_module); | ||||
| 		IdString derived_name = orig_box_module->derive(design, cell->parameters); | ||||
| 		RTLIL::Module* box_module = design->module(derived_name); | ||||
| 		cell->type = derived_name; | ||||
| 		cell->parameters.clear(); | ||||
| 		//cell->type = derived_name;
 | ||||
| 		//cell->parameters.clear();
 | ||||
| 
 | ||||
| 		int box_inputs = 0; | ||||
| 		auto r = cell_cache.insert(std::make_pair(derived_name, nullptr)); | ||||
| 		Cell *holes_cell = r.first->second; | ||||
| 		if (r.second && box_module->get_bool_attribute("\\whitebox")) { | ||||
| 			holes_cell = holes_module->addCell(cell->name, cell->type); | ||||
| 			holes_cell->parameters = cell->parameters; | ||||
| 			r.first->second = holes_cell; | ||||
| 
 | ||||
| 			if (box_module->has_processes()) | ||||
| 				Pass::call_on_module(design, box_module, "proc"); | ||||
| 		} | ||||
| 
 | ||||
| 		auto r2 = box_ports.insert(cell->type); | ||||
| 		if (r2.second) { | ||||
| 			// Make carry in the last PI, and carry out the last PO
 | ||||
| 			//   since ABC requires it this way
 | ||||
| 			IdString carry_in, carry_out; | ||||
| 			for (const auto &port_name : box_module->ports) { | ||||
| 				auto w = box_module->wire(port_name); | ||||
| 				log_assert(w); | ||||
| 				if (w->get_bool_attribute("\\abc9_carry")) { | ||||
| 					if (w->port_input) | ||||
| 						carry_in = port_name; | ||||
| 					if (w->port_output) | ||||
| 						carry_out = port_name; | ||||
| 		auto r = cell_cache.insert(derived_name); | ||||
| 		auto &holes_cell = r.first->second; | ||||
| 		if (r.second) { | ||||
| 			auto r2 = box_ports.insert(cell->type); | ||||
| 			if (r2.second) { | ||||
| 				// Make carry in the last PI, and carry out the last PO
 | ||||
| 				//   since ABC requires it this way
 | ||||
| 				IdString carry_in, carry_out; | ||||
| 				for (const auto &port_name : box_module->ports) { | ||||
| 					auto w = box_module->wire(port_name); | ||||
| 					log_assert(w); | ||||
| 					if (w->get_bool_attribute("\\abc9_carry")) { | ||||
| 						if (w->port_input) | ||||
| 							carry_in = port_name; | ||||
| 						if (w->port_output) | ||||
| 							carry_out = port_name; | ||||
| 					} | ||||
| 					else | ||||
| 						r2.first->second.push_back(port_name); | ||||
| 				} | ||||
| 
 | ||||
| 				if (carry_in != IdString()) { | ||||
| 					r2.first->second.push_back(carry_in); | ||||
| 					r2.first->second.push_back(carry_out); | ||||
| 				} | ||||
| 				else | ||||
| 					r2.first->second.push_back(port_name); | ||||
| 			} | ||||
| 
 | ||||
| 			if (carry_in != IdString()) { | ||||
| 				r2.first->second.push_back(carry_in); | ||||
| 				r2.first->second.push_back(carry_out); | ||||
| 			} | ||||
| 		} | ||||
| 			if (box_module->get_bool_attribute("\\whitebox")) { | ||||
| 				holes_cell = holes_module->addCell(cell->name, derived_name); | ||||
| 
 | ||||
| 		for (const auto &port_name : box_ports.at(cell->type)) { | ||||
| 			RTLIL::Wire *w = box_module->wire(port_name); | ||||
| 			log_assert(w); | ||||
| 			RTLIL::Wire *holes_wire; | ||||
| 			RTLIL::SigSpec port_sig; | ||||
| 			if (w->port_input) | ||||
| 				for (int i = 0; i < GetSize(w); i++) { | ||||
| 				if (box_module->has_processes()) | ||||
| 					Pass::call_on_module(design, box_module, "proc"); | ||||
| 
 | ||||
| 				int box_inputs = 0; | ||||
| 				for (auto port_name : box_ports.at(cell->type)) { | ||||
| 					RTLIL::Wire *w = box_module->wire(port_name); | ||||
| 					log_assert(w); | ||||
| 					log_assert(!w->port_input || !w->port_output); | ||||
| 					auto &conn = holes_cell->connections_[port_name]; | ||||
| 					if (w->port_input) { | ||||
| 						for (int i = 0; i < GetSize(w); i++) { | ||||
| 							box_inputs++; | ||||
| 							RTLIL::Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); | ||||
| 							if (!holes_wire) { | ||||
| 								holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); | ||||
| 								holes_wire->port_input = true; | ||||
| 								holes_wire->port_id = port_id++; | ||||
| 								holes_module->ports.push_back(holes_wire->name); | ||||
| 							} | ||||
| 							conn.append(holes_wire); | ||||
| 						} | ||||
| 					} | ||||
| 					else if (w->port_output) | ||||
| 						conn = holes_module->addWire(stringf("%s.%s", derived_name.c_str(), log_id(port_name)), GetSize(w)); | ||||
| 				} | ||||
| 
 | ||||
| 				// For flops only, create an extra 1-bit input that drives a new wire
 | ||||
| 				//   called "<cell>.abc9_ff.Q" that is used below
 | ||||
| 				if (box_module->get_bool_attribute("\\abc9_flop")) { | ||||
| 					box_inputs++; | ||||
| 					holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); | ||||
| 					Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); | ||||
| 					if (!holes_wire) { | ||||
| 						holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); | ||||
| 						holes_wire->port_input = true; | ||||
| 						holes_wire->port_id = port_id++; | ||||
| 						holes_module->ports.push_back(holes_wire->name); | ||||
| 					} | ||||
| 					if (holes_cell) | ||||
| 						port_sig.append(holes_wire); | ||||
| 					Wire *Q = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); | ||||
| 					holes_module->connect(Q, holes_wire); | ||||
| 				} | ||||
| 			if (w->port_output) | ||||
| 				for (int i = 0; i < GetSize(w); i++) { | ||||
| 					if (GetSize(w) == 1) | ||||
| 						holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(w->name))); | ||||
| 					else | ||||
| 						holes_wire = holes_module->addWire(stringf("$abc%s.%s[%d]", cell->name.c_str(), log_id(w->name), i)); | ||||
| 					holes_wire->port_output = true; | ||||
| 					holes_wire->port_id = port_id++; | ||||
| 					holes_module->ports.push_back(holes_wire->name); | ||||
| 					if (holes_cell) | ||||
| 						port_sig.append(holes_wire); | ||||
| 					else | ||||
| 						holes_module->connect(holes_wire, State::S0); | ||||
| 				} | ||||
| 			if (!port_sig.empty()) { | ||||
| 				if (r.second) | ||||
| 					holes_cell->setPort(w->name, port_sig); | ||||
| 				else | ||||
| 					holes_module->connect(holes_cell->getPort(w->name), port_sig); | ||||
| 			} | ||||
| 			else // box_module is a blackbox
 | ||||
| 				log_assert(holes_cell == nullptr); | ||||
| 		} | ||||
| 
 | ||||
| 		// For flops only, create an extra 1-bit input that drives a new wire
 | ||||
| 		//   called "<cell>.$abc9_currQ" that is used below
 | ||||
| 		if (box_module->get_bool_attribute("\\abc9_flop")) { | ||||
| 			log_assert(holes_cell); | ||||
| 
 | ||||
| 			box_inputs++; | ||||
| 			Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); | ||||
| 			if (!holes_wire) { | ||||
| 				holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); | ||||
| 				holes_wire->port_input = true; | ||||
| 				holes_wire->port_id = port_id++; | ||||
| 				holes_module->ports.push_back(holes_wire->name); | ||||
| 			} | ||||
| 			Wire *w = holes_module->addWire(stringf("%s.abc9_ff.Q", cell->name.c_str())); | ||||
| 			holes_module->connect(w, holes_wire); | ||||
| 		for (auto port_name : box_ports.at(cell->type)) { | ||||
| 			RTLIL::Wire *w = box_module->wire(port_name); | ||||
| 			log_assert(w); | ||||
| 			if (!w->port_output) | ||||
| 				continue; | ||||
| 			Wire *holes_wire = holes_module->addWire(stringf("$abc%s.%s", cell->name.c_str(), log_id(port_name)), GetSize(w)); | ||||
| 			holes_wire->port_output = true; | ||||
| 			holes_wire->port_id = port_id++; | ||||
| 			holes_module->ports.push_back(holes_wire->name); | ||||
| 			if (holes_cell) // whitebox
 | ||||
| 				holes_module->connect(holes_wire, holes_cell->getPort(port_name)); | ||||
| 			else // blackbox
 | ||||
| 				holes_module->connect(holes_wire, Const(State::S0, GetSize(w))); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -1059,7 +1057,11 @@ struct Abc9OpsPass : public Pass { | |||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		// TODO: Check at least one mode given
 | ||||
| 		if (!(check_mode || break_scc_mode || unbreak_scc_mode || prep_times_mode || prep_holes_mode || prep_dff_mode || !write_box_src.empty() || reintegrate_mode)) | ||||
| 			log_cmd_error("At least one of -check, -{,un}break_scc, -prep_{times,holes,dff}, -write_box, -reintegrate must be specified.\n"); | ||||
| 
 | ||||
| 		if (dff_mode && !prep_holes_mode) | ||||
| 			log_cmd_error("'-dff' option is only relevant for -prep_holes.\n"); | ||||
| 
 | ||||
| 		if (check_mode) | ||||
| 			check(design); | ||||
|  | @ -1075,6 +1077,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