diff options
| -rw-r--r-- | backends/aiger/xaiger.cc | 82 | ||||
| -rw-r--r-- | frontends/aiger/aigerparse.cc | 68 | ||||
| -rw-r--r-- | techlibs/ecp5/cells_sim.v | 8 | ||||
| -rw-r--r-- | techlibs/ice40/cells_sim.v | 4 | ||||
| -rw-r--r-- | techlibs/xilinx/cells_sim.v | 4 | 
5 files changed, 84 insertions, 82 deletions
diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 92df899c2..ae690ec49 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -284,8 +284,6 @@ struct XAigerWriter  					for (auto user_cell : it.second)  						toposort.edge(driver_cell, user_cell); -			pool<RTLIL::Module*> abc_carry_modules; -  #if 0  			toposort.analyze_loops = true;  #endif @@ -303,54 +301,54 @@ struct XAigerWriter  #endif  			log_assert(no_loops); +			pool<IdString> seen_boxes;  			for (auto cell_name : toposort.sorted) {  				RTLIL::Cell *cell = module->cell(cell_name); +				log_assert(cell); +  				RTLIL::Module* box_module = module->design->module(cell->type);  				if (!box_module || !box_module->attributes.count("\\abc_box_id"))  					continue; -				if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) { -					RTLIL::Wire* carry_in = nullptr, *carry_out = nullptr; -					auto &ports = box_module->ports; -					for (auto it = ports.begin(); it != ports.end(); ) { -						RTLIL::Wire* w = box_module->wire(*it); -						log_assert(w); -						if (w->port_input && w->attributes.count("\\abc_carry_in")) { -							if (carry_in) -								log_error("More than one port with attribute 'abc_carry_in' found in module '%s'\n", log_id(box_module)); -							carry_in = w; -							it = ports.erase(it); -							continue; -						} -						if (w->port_output && w->attributes.count("\\abc_carry_out")) { -							if (carry_out) -								log_error("More than one port with attribute 'abc_carry_out' found in module '%s'\n", log_id(box_module)); -							carry_out = w; -							it = ports.erase(it); -							continue; +				if (seen_boxes.insert(cell->type).second) { +					auto it = box_module->attributes.find("\\abc_carry"); +					if (it != box_module->attributes.end()) { +						RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; +						auto carry_in_out = it->second.decode_string(); +						auto pos = carry_in_out.find(','); +						if (pos == std::string::npos) +							log_error("'abc_carry' attribute on module '%s' does not contain ','.\n", log_id(cell->type)); +						auto carry_in_name = RTLIL::escape_id(carry_in_out.substr(0, pos)); +						carry_in = box_module->wire(carry_in_name); +						if (!carry_in || !carry_in->port_input) +							log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an input port.\n", log_id(cell->type), carry_in_name.c_str()); + +						auto carry_out_name = RTLIL::escape_id(carry_in_out.substr(pos+1)); +						carry_out = box_module->wire(carry_out_name); +						if (!carry_out || !carry_out->port_output) +							log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an output port.\n", log_id(cell->type), carry_out_name.c_str()); + +						auto &ports = box_module->ports; +						for (auto jt = ports.begin(); jt != ports.end(); ) { +							RTLIL::Wire* w = box_module->wire(*jt); +							log_assert(w); +							if (w == carry_in || w == carry_out) { +								jt = ports.erase(jt); +								continue; +							} +							if (w->port_id > carry_in->port_id) +								--w->port_id; +							if (w->port_id > carry_out->port_id) +								--w->port_id; +							log_assert(w->port_input || w->port_output); +							log_assert(ports[w->port_id-1] == w->name); +							++jt;  						} -						++it; -					} - -					if (!carry_in) -						log_error("Port with attribute 'abc_carry_in' not found in module '%s'\n", log_id(box_module)); -					if (!carry_out) -						log_error("Port with attribute 'abc_carry_out' not found in module '%s'\n", log_id(box_module)); - -					for (const auto port_name : ports) { -						RTLIL::Wire* w = box_module->wire(port_name); -						log_assert(w); -						if (w->port_id > carry_in->port_id) -							--w->port_id; -						if (w->port_id > carry_out->port_id) -							--w->port_id; -						log_assert(w->port_input || w->port_output); -						log_assert(ports[w->port_id-1] == w->name); +						ports.push_back(carry_in->name); +						carry_in->port_id = ports.size(); +						ports.push_back(carry_out->name); +						carry_out->port_id = ports.size();  					} -					ports.push_back(carry_in->name); -					carry_in->port_id = ports.size(); -					ports.push_back(carry_out->name); -					carry_out->port_id = ports.size();  				}  				// Fully pad all unused input connections of this box cell with S0 diff --git a/frontends/aiger/aigerparse.cc b/frontends/aiger/aigerparse.cc index 43337f4c2..7008d0542 100644 --- a/frontends/aiger/aigerparse.cc +++ b/frontends/aiger/aigerparse.cc @@ -732,44 +732,50 @@ void AigerReader::parse_aiger_binary()  void AigerReader::post_process()  { -	pool<RTLIL::Module*> abc_carry_modules; +	pool<IdString> seen_boxes;  	unsigned ci_count = 0, co_count = 0;  	for (auto cell : boxes) {  		RTLIL::Module* box_module = design->module(cell->type);  		log_assert(box_module); -		if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) { -			RTLIL::Wire* carry_in = nullptr, *carry_out = nullptr; -			RTLIL::Wire* last_in = nullptr, *last_out = nullptr; -			for (const auto &port_name : box_module->ports) { -				RTLIL::Wire* w = box_module->wire(port_name); -				log_assert(w); -				if (w->port_input) { -					if (w->attributes.count("\\abc_carry_in")) { -						log_assert(!carry_in); -						carry_in = w; -					} -					log_assert(!last_in || last_in->port_id < w->port_id); -					last_in = w; -				} -				if (w->port_output) { -					if (w->attributes.count("\\abc_carry_out")) { -						log_assert(!carry_out); -						carry_out = w; +		if (seen_boxes.insert(cell->type).second) { +			auto it = box_module->attributes.find("\\abc_carry"); +			if (it != box_module->attributes.end()) { +				RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr; +				auto carry_in_out = it->second.decode_string(); +				auto pos = carry_in_out.find(','); +				if (pos == std::string::npos) +					log_error("'abc_carry' attribute on module '%s' does not contain ','.\n", log_id(cell->type)); +				auto carry_in_name = RTLIL::escape_id(carry_in_out.substr(0, pos)); +				carry_in = box_module->wire(carry_in_name); +				if (!carry_in || !carry_in->port_input) +					log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an input port.\n", log_id(cell->type), carry_in_name.c_str()); + +				auto carry_out_name = RTLIL::escape_id(carry_in_out.substr(pos+1)); +				carry_out = box_module->wire(carry_out_name); +				if (!carry_out || !carry_out->port_output) +					log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an output port.\n", log_id(cell->type), carry_out_name.c_str()); + +				auto &ports = box_module->ports; +				for (auto jt = ports.begin(); jt != ports.end(); ) { +					RTLIL::Wire* w = box_module->wire(*jt); +					log_assert(w); +					if (w == carry_in || w == carry_out) { +						jt = ports.erase(jt); +						continue;  					} -					log_assert(!last_out || last_out->port_id < w->port_id); -					last_out = w; +					if (w->port_id > carry_in->port_id) +						--w->port_id; +					if (w->port_id > carry_out->port_id) +						--w->port_id; +					log_assert(w->port_input || w->port_output); +					log_assert(ports[w->port_id-1] == w->name); +					++jt;  				} -			} - -			if (carry_in != last_in) { -				std::swap(box_module->ports[carry_in->port_id], box_module->ports[last_in->port_id]); -				std::swap(carry_in->port_id, last_in->port_id); -			} -			if (carry_out != last_out) { -				log_assert(last_out); -				std::swap(box_module->ports[carry_out->port_id], box_module->ports[last_out->port_id]); -				std::swap(carry_out->port_id, last_out->port_id); +				ports.push_back(carry_in->name); +				carry_in->port_id = ports.size(); +				ports.push_back(carry_out->name); +				carry_out->port_id = ports.size();  			}  		} diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 08ae0a112..98f915777 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -15,11 +15,9 @@ module L6MUX21 (input D0, D1, SD, output Z);  endmodule  // --------------------------------------- -(* abc_box_id=1, abc_carry, lib_whitebox *) -module CCU2C((* abc_carry_in *) input CIN, -			   input A0, B0, C0, D0, A1, B1, C1, D1, -	           output S0, S1, -	         (* abc_carry_out *) output COUT); +(* abc_box_id=1, abc_carry="CIN,COUT", lib_whitebox *) +module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1, +	           output S0, S1, COUT);  	parameter [15:0] INIT0 = 16'h0000;  	parameter [15:0] INIT1 = 16'h0000; diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 317ae2c1f..c7e4101e1 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -136,8 +136,8 @@ module SB_LUT4 (output O, input I0, I1, I2, I3);  	assign O = I0 ? s1[1] : s1[0];  endmodule -(* abc_box_id = 1, abc_carry, lib_whitebox *) -module SB_CARRY ((* abc_carry_out *) output CO, input I0, I1, (* abc_carry_in *) input CI); +(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *) +module SB_CARRY (output CO, input I0, I1, CI);  	assign CO = (I0 && I1) || ((I0 || I1) && CI);  endmodule diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 5fd9973f4..5a148be01 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -173,8 +173,8 @@ module XORCY(output O, input CI, LI);    assign O = CI ^ LI;  endmodule -(* abc_box_id = 3, abc_carry, lib_whitebox *) -module CARRY4((* abc_carry_out *) output [3:0] CO, output [3:0] O, (* abc_carry_in *) input CI, input CYINIT, input [3:0] DI, S); +(* abc_box_id = 3, abc_carry="CI,CO", lib_whitebox *) +module CARRY4(output [3:0] CO, O, input CI, CYINIT, input [3:0] DI, S);    assign O = S ^ {CO[2:0], CI | CYINIT};    assign CO[0] = S[0] ? CI | CYINIT : DI[0];    assign CO[1] = S[1] ? CO[0] : DI[1];  | 
