mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Implement -specialize-from-file option for the qbfsat command.
				
					
				
			This commit is contained in:
		
							parent
							
								
									b9e79e0bb7
								
							
						
					
					
						commit
						3a4fd4a999
					
				
					 1 changed files with 55 additions and 22 deletions
				
			
		| 
						 | 
					@ -112,6 +112,33 @@ void write_solution(RTLIL::Module *module, const QbfSolutionType &sol, const std
 | 
				
			||||||
		fout << hole_loc_to_name[x.first] << "=" << x.second << std::endl;
 | 
							fout << hole_loc_to_name[x.first] << "=" << x.second << std::endl;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void specialize_from_file(RTLIL::Module *module, const std::string &file) {
 | 
				
			||||||
 | 
						YS_REGEX_TYPE hole_assn_regex = YS_REGEX_COMPILE_WITH_SUBS("^(.*)=([01]+)$");
 | 
				
			||||||
 | 
						YS_REGEX_MATCH_TYPE m;
 | 
				
			||||||
 | 
						std::ifstream fin(file.c_str());
 | 
				
			||||||
 | 
						if (!fin)
 | 
				
			||||||
 | 
							log_cmd_error("could not read solution file.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string buf;
 | 
				
			||||||
 | 
						while (std::getline(fin, buf)) {
 | 
				
			||||||
 | 
							log_assert(YS_REGEX_NS::regex_search(buf, m, hole_assn_regex));
 | 
				
			||||||
 | 
							std::string hole_name = m[1].str();
 | 
				
			||||||
 | 
							std::string hole_value = m[2].str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							RTLIL::Wire *wire = module->wire(hole_name);
 | 
				
			||||||
 | 
							log_assert(wire != nullptr);
 | 
				
			||||||
 | 
							log_assert(wire->width > 0 && hole_value.size() == static_cast<unsigned long>(wire->width));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log("Specializing %s from file with %s = %d'b%s.\n", module->name.c_str(), hole_name.c_str(), wire->width, hole_value.c_str());
 | 
				
			||||||
 | 
							std::vector<RTLIL::SigBit> value_bv;
 | 
				
			||||||
 | 
							value_bv.reserve(wire->width);
 | 
				
			||||||
 | 
							for (char c : hole_value)
 | 
				
			||||||
 | 
								value_bv.push_back(c == '1'? RTLIL::S1 : RTLIL::S0);
 | 
				
			||||||
 | 
							std::reverse(value_bv.begin(), value_bv.end());
 | 
				
			||||||
 | 
							module->connect(wire, value_bv);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void specialize(RTLIL::Module *module, const QbfSolutionType &sol) {
 | 
					void specialize(RTLIL::Module *module, const QbfSolutionType &sol) {
 | 
				
			||||||
	std::map<std::string, std::string> hole_loc_to_name = get_hole_loc_name_map(module, sol);
 | 
						std::map<std::string, std::string> hole_loc_to_name = get_hole_loc_name_map(module, sol);
 | 
				
			||||||
	for (auto &it : sol.hole_to_value) {
 | 
						for (auto &it : sol.hole_to_value) {
 | 
				
			||||||
| 
						 | 
					@ -124,6 +151,7 @@ void specialize(RTLIL::Module *module, const QbfSolutionType &sol) {
 | 
				
			||||||
		std::string hole_name = hole_loc_to_name[hole_loc];
 | 
							std::string hole_name = hole_loc_to_name[hole_loc];
 | 
				
			||||||
		RTLIL::Wire *wire = module->wire(hole_name);
 | 
							RTLIL::Wire *wire = module->wire(hole_name);
 | 
				
			||||||
		log_assert(wire != nullptr);
 | 
							log_assert(wire != nullptr);
 | 
				
			||||||
 | 
							log_assert(wire->width > 0 && hole_value.size() == static_cast<unsigned long>(wire->width));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log("Specializing %s with %s = %d'b%s.\n", module->name.c_str(), hole_name.c_str(), wire->width, hole_value.c_str());
 | 
							log("Specializing %s with %s = %d'b%s.\n", module->name.c_str(), hole_name.c_str(), wire->width, hole_value.c_str());
 | 
				
			||||||
		std::vector<RTLIL::SigBit> value_bv;
 | 
							std::vector<RTLIL::SigBit> value_bv;
 | 
				
			||||||
| 
						 | 
					@ -386,33 +414,38 @@ struct QbfSatPass : public Pass {
 | 
				
			||||||
		if (module == NULL)
 | 
							if (module == NULL)
 | 
				
			||||||
			log_cmd_error("Can't perform QBF-SAT on an empty selection!\n");
 | 
								log_cmd_error("Can't perform QBF-SAT on an empty selection!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//Save the design to restore after modiyfing the current module.
 | 
							if (!opt.specialize_from_file) {
 | 
				
			||||||
		std::string module_name = module->name.str();
 | 
								//Save the design to restore after modiyfing the current module.
 | 
				
			||||||
		Pass::call(design, "design -save _qbfsat_tmp");
 | 
								std::string module_name = module->name.str();
 | 
				
			||||||
 | 
								Pass::call(design, "design -save _qbfsat_tmp");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//Replace input wires with wires assigned $allconst cells.
 | 
								//Replace input wires with wires assigned $allconst cells.
 | 
				
			||||||
		std::set<std::string> input_wires = validate_design_and_get_inputs(module);
 | 
								std::set<std::string> input_wires = validate_design_and_get_inputs(module);
 | 
				
			||||||
		allconstify_inputs(module, input_wires);
 | 
								allconstify_inputs(module, input_wires);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		QbfSolutionType ret = qbf_solve(module, opt);
 | 
								QbfSolutionType ret = qbf_solve(module, opt);
 | 
				
			||||||
		Pass::call(design, "design -load _qbfsat_tmp");
 | 
								Pass::call(design, "design -load _qbfsat_tmp");
 | 
				
			||||||
		module = design->module(module_name);
 | 
								module = design->module(module_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (ret.unknown)
 | 
								if (ret.unknown)
 | 
				
			||||||
			log_warning("solver did not give an answer\n");
 | 
									log_warning("solver did not give an answer\n");
 | 
				
			||||||
		else if (ret.sat)
 | 
								else if (ret.sat)
 | 
				
			||||||
			print_qed();
 | 
									print_qed();
 | 
				
			||||||
		else
 | 
								else
 | 
				
			||||||
			print_proof_failed();
 | 
									print_proof_failed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(!ret.unknown && ret.sat) {
 | 
								if(!ret.unknown && ret.sat) {
 | 
				
			||||||
			if (opt.write_solution) {
 | 
									if (opt.write_solution) {
 | 
				
			||||||
				write_solution(module, ret, opt.write_soln_soln_file);
 | 
										write_solution(module, ret, opt.write_soln_soln_file);
 | 
				
			||||||
			}
 | 
									}
 | 
				
			||||||
			if (opt.specialize) {
 | 
									if (opt.specialize) {
 | 
				
			||||||
				specialize(module, ret);
 | 
										specialize(module, ret);
 | 
				
			||||||
				Pass::call(design, "opt_clean");
 | 
										Pass::call(design, "opt_clean");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								specialize_from_file(module, opt.specialize_soln_file);
 | 
				
			||||||
 | 
								Pass::call(design, "opt_clean");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} QbfSatPass;
 | 
					} QbfSatPass;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue