mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Only xaig if GetSize(output_bits) > 0
This commit is contained in:
		
							parent
							
								
									64d62710de
								
							
						
					
					
						commit
						7b646101e9
					
				
					 1 changed files with 154 additions and 152 deletions
				
			
		|  | @ -575,176 +575,178 @@ struct XAigerWriter | ||||||
| 
 | 
 | ||||||
| 		f << "c"; | 		f << "c"; | ||||||
| 
 | 
 | ||||||
| 		auto write_buffer = [](std::stringstream &buffer, int i32) { | 		if (GetSize(output_bits) > 0) { | ||||||
| 			int32_t i32_be = to_big_endian(i32); | 			auto write_buffer = [](std::stringstream &buffer, int i32) { | ||||||
| 			buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be)); | 				int32_t i32_be = to_big_endian(i32); | ||||||
| 		}; | 				buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be)); | ||||||
| 		std::stringstream h_buffer; | 			}; | ||||||
| 		auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); | 			std::stringstream h_buffer; | ||||||
| 		write_h_buffer(1); | 			auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); | ||||||
| 		log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); | 			write_h_buffer(1); | ||||||
| 		write_h_buffer(input_bits.size() + ci_bits.size()); | 			log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); | ||||||
| 		log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); | 			write_h_buffer(input_bits.size() + ci_bits.size()); | ||||||
| 		write_h_buffer(output_bits.size() + GetSize(co_bits)); | 			log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); | ||||||
| 		log_debug("piNum = %d\n", GetSize(input_bits)); | 			write_h_buffer(output_bits.size() + GetSize(co_bits)); | ||||||
| 		write_h_buffer(input_bits.size()); | 			log_debug("piNum = %d\n", GetSize(input_bits)); | ||||||
| 		log_debug("poNum = %d\n", GetSize(output_bits)); | 			write_h_buffer(input_bits.size()); | ||||||
| 		write_h_buffer(output_bits.size()); | 			log_debug("poNum = %d\n", GetSize(output_bits)); | ||||||
| 		log_debug("boxNum = %d\n", GetSize(box_list)); | 			write_h_buffer(output_bits.size()); | ||||||
| 		write_h_buffer(box_list.size()); | 			log_debug("boxNum = %d\n", GetSize(box_list)); | ||||||
|  | 			write_h_buffer(box_list.size()); | ||||||
| 
 | 
 | ||||||
| 		auto write_buffer_float = [](std::stringstream &buffer, float f32) { | 			auto write_buffer_float = [](std::stringstream &buffer, float f32) { | ||||||
| 			buffer.write(reinterpret_cast<const char*>(&f32), sizeof(f32)); | 				buffer.write(reinterpret_cast<const char*>(&f32), sizeof(f32)); | ||||||
| 		}; | 			}; | ||||||
| 		std::stringstream i_buffer; | 			std::stringstream i_buffer; | ||||||
| 		auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); | 			auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); | ||||||
| 		for (auto bit : input_bits) | 			for (auto bit : input_bits) | ||||||
| 			write_i_buffer(arrival_times.at(bit, 0)); | 				write_i_buffer(arrival_times.at(bit, 0)); | ||||||
| 		//std::stringstream o_buffer;
 | 			//std::stringstream o_buffer;
 | ||||||
| 		//auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1);
 | 			//auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1);
 | ||||||
| 		//for (auto bit : output_bits)
 | 			//for (auto bit : output_bits)
 | ||||||
| 		//	write_o_buffer(0);
 | 			//	write_o_buffer(0);
 | ||||||
| 
 | 
 | ||||||
| 		if (!box_list.empty()) { | 			if (!box_list.empty()) { | ||||||
| 			RTLIL::Module *holes_module = module->design->addModule("$__holes__"); | 				RTLIL::Module *holes_module = module->design->addModule("$__holes__"); | ||||||
| 			log_assert(holes_module); | 				log_assert(holes_module); | ||||||
| 
 | 
 | ||||||
| 			int port_id = 1; | 				int port_id = 1; | ||||||
| 			int box_count = 0; | 				int box_count = 0; | ||||||
| 			for (auto cell : box_list) { | 				for (auto cell : box_list) { | ||||||
| 				RTLIL::Module* box_module = module->design->module(cell->type); | 					RTLIL::Module* box_module = module->design->module(cell->type); | ||||||
| 				int box_inputs = 0, box_outputs = 0; | 					int box_inputs = 0, box_outputs = 0; | ||||||
| 				Cell *holes_cell = nullptr; | 					Cell *holes_cell = nullptr; | ||||||
| 				if (box_module->get_bool_attribute("\\whitebox")) { | 					if (box_module->get_bool_attribute("\\whitebox")) { | ||||||
| 					holes_cell = holes_module->addCell(cell->name, cell->type); | 						holes_cell = holes_module->addCell(cell->name, cell->type); | ||||||
| 					holes_cell->parameters = cell->parameters; | 						holes_cell->parameters = cell->parameters; | ||||||
| 				} | 					} | ||||||
| 
 | 
 | ||||||
| 				// NB: Assume box_module->ports are sorted alphabetically
 | 					// NB: Assume box_module->ports are sorted alphabetically
 | ||||||
| 				//     (as RTLIL::Module::fixup_ports() would do)
 | 					//     (as RTLIL::Module::fixup_ports() would do)
 | ||||||
| 				for (const auto &port_name : box_module->ports) { | 					for (const auto &port_name : box_module->ports) { | ||||||
| 					RTLIL::Wire *w = box_module->wire(port_name); | 						RTLIL::Wire *w = box_module->wire(port_name); | ||||||
| 					log_assert(w); | 						log_assert(w); | ||||||
| 					RTLIL::Wire *holes_wire; | 						RTLIL::Wire *holes_wire; | ||||||
| 					RTLIL::SigSpec port_wire; | 						RTLIL::SigSpec port_wire; | ||||||
| 					if (w->port_input) { | 						if (w->port_input) { | ||||||
| 						for (int i = 0; i < GetSize(w); i++) { | 							for (int i = 0; i < GetSize(w); i++) { | ||||||
| 							box_inputs++; | 								box_inputs++; | ||||||
| 							holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); | 								holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); | ||||||
| 							if (!holes_wire) { | 								if (!holes_wire) { | ||||||
| 								holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); | 									holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); | ||||||
| 								holes_wire->port_input = true; | 									holes_wire->port_input = true; | ||||||
|  | 									holes_wire->port_id = port_id++; | ||||||
|  | 									holes_module->ports.push_back(holes_wire->name); | ||||||
|  | 								} | ||||||
|  | 								if (holes_cell) | ||||||
|  | 									port_wire.append(holes_wire); | ||||||
|  | 							} | ||||||
|  | 							if (!port_wire.empty()) | ||||||
|  | 								holes_cell->setPort(w->name, port_wire); | ||||||
|  | 						} | ||||||
|  | 						if (w->port_output) { | ||||||
|  | 							box_outputs += GetSize(w); | ||||||
|  | 							for (int i = 0; i < GetSize(w); i++) { | ||||||
|  | 								if (GetSize(w) == 1) | ||||||
|  | 									holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); | ||||||
|  | 								else | ||||||
|  | 									holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); | ||||||
|  | 								holes_wire->port_output = true; | ||||||
| 								holes_wire->port_id = port_id++; | 								holes_wire->port_id = port_id++; | ||||||
| 								holes_module->ports.push_back(holes_wire->name); | 								holes_module->ports.push_back(holes_wire->name); | ||||||
|  | 								if (holes_cell) | ||||||
|  | 									port_wire.append(holes_wire); | ||||||
|  | 								else | ||||||
|  | 									holes_module->connect(holes_wire, State::S0); | ||||||
| 							} | 							} | ||||||
| 							if (holes_cell) | 							if (!port_wire.empty()) | ||||||
| 								port_wire.append(holes_wire); | 								holes_cell->setPort(w->name, port_wire); | ||||||
| 						} | 						} | ||||||
| 						if (!port_wire.empty()) |  | ||||||
| 							holes_cell->setPort(w->name, port_wire); |  | ||||||
| 					} |  | ||||||
| 					if (w->port_output) { |  | ||||||
| 						box_outputs += GetSize(w); |  | ||||||
| 						for (int i = 0; i < GetSize(w); i++) { |  | ||||||
| 							if (GetSize(w) == 1) |  | ||||||
| 								holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); |  | ||||||
| 							else |  | ||||||
| 								holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); |  | ||||||
| 							holes_wire->port_output = true; |  | ||||||
| 							holes_wire->port_id = port_id++; |  | ||||||
| 							holes_module->ports.push_back(holes_wire->name); |  | ||||||
| 							if (holes_cell) |  | ||||||
| 								port_wire.append(holes_wire); |  | ||||||
| 							else |  | ||||||
| 								holes_module->connect(holes_wire, State::S0); |  | ||||||
| 						} |  | ||||||
| 						if (!port_wire.empty()) |  | ||||||
| 							holes_cell->setPort(w->name, port_wire); |  | ||||||
| 					} | 					} | ||||||
|  | 
 | ||||||
|  | 					write_h_buffer(box_inputs); | ||||||
|  | 					write_h_buffer(box_outputs); | ||||||
|  | 					write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); | ||||||
|  | 					write_h_buffer(box_count++); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				write_h_buffer(box_inputs); | 				std::stringstream r_buffer; | ||||||
| 				write_h_buffer(box_outputs); | 				auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); | ||||||
| 				write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); | 				write_r_buffer(0); | ||||||
| 				write_h_buffer(box_count++); | 				f << "r"; | ||||||
| 			} | 				std::string buffer_str = r_buffer.str(); | ||||||
| 
 |  | ||||||
| 			std::stringstream r_buffer; |  | ||||||
| 			auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); |  | ||||||
| 			write_r_buffer(0); |  | ||||||
| 			f << "r"; |  | ||||||
| 			std::string buffer_str = r_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()); |  | ||||||
| 
 |  | ||||||
| 			if (holes_module) { |  | ||||||
| 				log_push(); |  | ||||||
| 
 |  | ||||||
| 				// NB: fixup_ports() will sort ports by name
 |  | ||||||
| 				//holes_module->fixup_ports();
 |  | ||||||
| 				holes_module->check(); |  | ||||||
| 
 |  | ||||||
| 				holes_module->design->selection_stack.emplace_back(false); |  | ||||||
| 				RTLIL::Selection& sel = holes_module->design->selection_stack.back(); |  | ||||||
| 				sel.select(holes_module); |  | ||||||
| 
 |  | ||||||
| 				// TODO: Should not need to opt_merge if we only instantiate
 |  | ||||||
| 				//       each box type once...
 |  | ||||||
| 				Pass::call(holes_module->design, "opt_merge -share_all"); |  | ||||||
| 
 |  | ||||||
| 				Pass::call(holes_module->design, "flatten -wb"); |  | ||||||
| 
 |  | ||||||
| 				// TODO: Should techmap/aigmap/check all lib_whitebox-es just once,
 |  | ||||||
| 				//       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"); |  | ||||||
| 
 |  | ||||||
| 				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*/); |  | ||||||
| 
 |  | ||||||
| 				delete holes_design; |  | ||||||
| 
 |  | ||||||
| 				f << "a"; |  | ||||||
| 				std::string buffer_str = a_buffer.str(); |  | ||||||
| 				int32_t buffer_size_be = to_big_endian(buffer_str.size()); | 				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(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be)); | ||||||
| 				f.write(buffer_str.data(), buffer_str.size()); | 				f.write(buffer_str.data(), buffer_str.size()); | ||||||
| 
 | 
 | ||||||
| 				log_pop(); | 				if (holes_module) { | ||||||
|  | 					log_push(); | ||||||
|  | 
 | ||||||
|  | 					// NB: fixup_ports() will sort ports by name
 | ||||||
|  | 					//holes_module->fixup_ports();
 | ||||||
|  | 					holes_module->check(); | ||||||
|  | 
 | ||||||
|  | 					holes_module->design->selection_stack.emplace_back(false); | ||||||
|  | 					RTLIL::Selection& sel = holes_module->design->selection_stack.back(); | ||||||
|  | 					sel.select(holes_module); | ||||||
|  | 
 | ||||||
|  | 					// TODO: Should not need to opt_merge if we only instantiate
 | ||||||
|  | 					//       each box type once...
 | ||||||
|  | 					Pass::call(holes_module->design, "opt_merge -share_all"); | ||||||
|  | 
 | ||||||
|  | 					Pass::call(holes_module->design, "flatten -wb"); | ||||||
|  | 
 | ||||||
|  | 					// TODO: Should techmap/aigmap/check all lib_whitebox-es just once,
 | ||||||
|  | 					//       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"); | ||||||
|  | 
 | ||||||
|  | 					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*/); | ||||||
|  | 
 | ||||||
|  | 					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()); | ||||||
|  | 
 | ||||||
|  | 					log_pop(); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			f << "h"; | ||||||
|  | 			std::string buffer_str = h_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()); | ||||||
|  | 
 | ||||||
|  | 			f << "i"; | ||||||
|  | 			buffer_str = i_buffer.str(); | ||||||
|  | 			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()); | ||||||
|  | 			//f << "o";
 | ||||||
|  | 			//buffer_str = o_buffer.str();
 | ||||||
|  | 			//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());
 | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		f << "h"; |  | ||||||
| 		std::string buffer_str = h_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()); |  | ||||||
| 
 |  | ||||||
| 		f << "i"; |  | ||||||
| 		buffer_str = i_buffer.str(); |  | ||||||
| 		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()); |  | ||||||
| 		//f << "o";
 |  | ||||||
| 		//buffer_str = o_buffer.str();
 |  | ||||||
| 		//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());
 |  | ||||||
| 
 |  | ||||||
| 		f << stringf("Generated by %s\n", yosys_version_str); | 		f << stringf("Generated by %s\n", yosys_version_str); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue