mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Implement the -assume-outputs, -sat, and -unsat options for the qbfsat` command.
				
					
				
			This commit is contained in:
		
							parent
							
								
									5527063f66
								
							
						
					
					
						commit
						bb101e0b3a
					
				
					 1 changed files with 66 additions and 3 deletions
				
			
		|  | @ -49,14 +49,16 @@ struct QbfSolutionType { | |||
| }; | ||||
| 
 | ||||
| struct QbfSolveOptions { | ||||
| 	bool timeout, specialize, specialize_from_file, write_solution, nocleanup, dump_final_smt2; | ||||
| 	bool timeout, specialize, specialize_from_file, write_solution, nocleanup, dump_final_smt2, assume_outputs; | ||||
| 	bool sat, unsat; | ||||
| 	long timeout_sec; | ||||
| 	std::string specialize_soln_file; | ||||
| 	std::string write_soln_soln_file; | ||||
| 	std::string dump_final_smt2_file; | ||||
| 	size_t argidx; | ||||
| 	QbfSolveOptions() : timeout(false), specialize(false), specialize_from_file(false), write_solution(false),	 | ||||
| 				nocleanup(false), dump_final_smt2(false), timeout_sec(-1), argidx(0) {}; | ||||
| 				nocleanup(false), dump_final_smt2(false), assume_outputs(false), sat(false), unsat(false), | ||||
| 				timeout_sec(-1), argidx(0) {}; | ||||
| }; | ||||
| 
 | ||||
| void recover_solution(QbfSolutionType &sol) { | ||||
|  | @ -178,7 +180,7 @@ void specialize(RTLIL::Module *module, const QbfSolutionType &sol) { | |||
| } | ||||
| 
 | ||||
| void allconstify_inputs(RTLIL::Module *module, const std::set<std::string> &input_wires) { | ||||
| 	for(auto &n : input_wires) { | ||||
| 	for (auto &n : input_wires) { | ||||
| 		RTLIL::Wire *input = module->wire(n); | ||||
| #ifndef NDEBUG | ||||
| 		log_assert(input != nullptr); | ||||
|  | @ -194,6 +196,40 @@ void allconstify_inputs(RTLIL::Module *module, const std::set<std::string> &inpu | |||
| 	module->fixup_ports(); | ||||
| } | ||||
| 
 | ||||
| void assume_miter_outputs(RTLIL::Module *module) { | ||||
| 	std::vector<RTLIL::Wire *> wires_to_assume; | ||||
| 	for (auto w : module->wires()) | ||||
| 		if (w->port_output) { | ||||
| 			if (w->width == 1) | ||||
| 				wires_to_assume.push_back(w); | ||||
| 		} | ||||
| 	if (wires_to_assume.size() == 0) | ||||
| 		return; | ||||
| 	else { | ||||
| 		log("Adding $assume cell for outputs: "); | ||||
| 		for (auto w : wires_to_assume) | ||||
| 			log("\"%s\" ", w->name.c_str()); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	std::vector<RTLIL::Wire *>::size_type i; | ||||
| 	while (wires_to_assume.size() > 1) { | ||||
| 		std::vector<RTLIL::Wire *> buf; | ||||
| 		for (i = 0; i + 1 < wires_to_assume.size(); i += 2) { | ||||
| 			std::stringstream strstr; strstr << i; | ||||
| 			RTLIL::Wire *and_wire = module->addWire("\\_qbfsat_and_" + strstr.str(), 1); | ||||
| 			module->addLogicAnd("$_qbfsat_and_" + strstr.str(), wires_to_assume[i], wires_to_assume[i+1], and_wire, false, wires_to_assume[i]->get_src_attribute()); | ||||
| 			buf.push_back(and_wire); | ||||
| 		} | ||||
| 		wires_to_assume.swap(buf); | ||||
| 	} | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| 	log_assert(wires_to_assume.size() == 1); | ||||
| #endif | ||||
| 	module->addAssume("$assume_qbfsat_miter_outputs", wires_to_assume[0], RTLIL::S1); | ||||
| } | ||||
| 
 | ||||
| QbfSolutionType qbf_solve(RTLIL::Module *mod, const QbfSolveOptions &opt) { | ||||
| 	QbfSolutionType ret; | ||||
| 	std::string yosys_smtbmc_exe = proc_self_dirname() + "yosys-smtbmc"; | ||||
|  | @ -322,6 +358,18 @@ QbfSolveOptions parse_args(const std::vector<std::string> &args) { | |||
| 			opt.specialize = true; | ||||
| 			continue; | ||||
| 		} | ||||
| 		else if (args[opt.argidx] == "-assume-outputs") { | ||||
| 			opt.assume_outputs = true; | ||||
| 			continue; | ||||
| 		} | ||||
| 		else if (args[opt.argidx] == "-sat") { | ||||
| 			opt.sat = true; | ||||
| 			continue; | ||||
| 		} | ||||
| 		else if (args[opt.argidx] == "-unsat") { | ||||
| 			opt.unsat = true; | ||||
| 			continue; | ||||
| 		} | ||||
| 		else if (args[opt.argidx] == "-dump-final-smt2") { | ||||
| 			opt.dump_final_smt2 = true; | ||||
| 			if (args.size() <= opt.argidx + 1) | ||||
|  | @ -403,6 +451,15 @@ struct QbfSatPass : public Pass { | |||
| 		log("    -dump-final-smt2 <file>\n"); | ||||
| 		log("        Pass the --dump-smt2 option to yosys-smtbmc.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -assume-outputs\n"); | ||||
| 		log("        Add an $assume cell for the conjunction of all one-bit module output wires.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -sat\n"); | ||||
| 		log("        Generate an error if the solver does not return \"sat\".\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -unsat\n"); | ||||
| 		log("        Generate an error if the solver does not return \"unsat\".\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -specialize\n"); | ||||
| 		log("        Replace all \"$anyconst\" cells with constant values determined by the solver.\n"); | ||||
| 		log("\n"); | ||||
|  | @ -440,6 +497,8 @@ struct QbfSatPass : public Pass { | |||
| 			//Replace input wires with wires assigned $allconst cells.
 | ||||
| 			std::set<std::string> input_wires = validate_design_and_get_inputs(module); | ||||
| 			allconstify_inputs(module, input_wires); | ||||
| 			if (opt.assume_outputs) | ||||
| 				assume_miter_outputs(module); | ||||
| 
 | ||||
| 			QbfSolutionType ret = qbf_solve(module, opt); | ||||
| 			Pass::call(design, "design -load _qbfsat_tmp"); | ||||
|  | @ -460,7 +519,11 @@ struct QbfSatPass : public Pass { | |||
| 					specialize(module, ret); | ||||
| 					Pass::call(design, "opt_clean"); | ||||
| 				} | ||||
| 				if (opt.unsat) | ||||
| 					log_cmd_error("expected problem to be UNSAT\n"); | ||||
| 			} | ||||
| 			else if (!ret.unknown && !ret.sat && opt.sat) | ||||
| 				log_cmd_error("expected problem to be SAT\n"); | ||||
| 		} else { | ||||
| 			specialize_from_file(module, opt.specialize_soln_file); | ||||
| 			Pass::call(design, "opt_clean"); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue