mirror of https://github.com/YosysHQ/yosys.git
Added sat -tempinduc and sat -prove-asserts
This commit is contained in:
parent
c36bac0e10
commit
03a876c7e8
|
@ -47,6 +47,7 @@ struct SatHelper
|
||||||
std::vector<std::pair<std::string, std::string>> sets, prove, prove_x, sets_init;
|
std::vector<std::pair<std::string, std::string>> sets, prove, prove_x, sets_init;
|
||||||
std::map<int, std::vector<std::pair<std::string, std::string>>> sets_at;
|
std::map<int, std::vector<std::pair<std::string, std::string>>> sets_at;
|
||||||
std::map<int, std::vector<std::string>> unsets_at;
|
std::map<int, std::vector<std::string>> unsets_at;
|
||||||
|
bool prove_asserts;
|
||||||
|
|
||||||
// undef constraints
|
// undef constraints
|
||||||
bool enable_undef, set_init_undef;
|
bool enable_undef, set_init_undef;
|
||||||
|
@ -284,7 +285,7 @@ struct SatHelper
|
||||||
|
|
||||||
int setup_proof(int timestep = -1)
|
int setup_proof(int timestep = -1)
|
||||||
{
|
{
|
||||||
assert(prove.size() + prove_x.size() > 0);
|
assert(prove.size() || prove_x.size() || prove_asserts);
|
||||||
|
|
||||||
RTLIL::SigSpec big_lhs, big_rhs;
|
RTLIL::SigSpec big_lhs, big_rhs;
|
||||||
std::vector<int> prove_bits;
|
std::vector<int> prove_bits;
|
||||||
|
@ -352,6 +353,9 @@ struct SatHelper
|
||||||
prove_bits.push_back(ez.OR(undef_lhs.at(i), ez.AND(ez.NOT(undef_rhs.at(i)), ez.NOT(ez.XOR(value_lhs.at(i), value_rhs.at(i))))));
|
prove_bits.push_back(ez.OR(undef_lhs.at(i), ez.AND(ez.NOT(undef_rhs.at(i)), ez.NOT(ez.XOR(value_lhs.at(i), value_rhs.at(i))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prove_asserts)
|
||||||
|
prove_bits.push_back(satgen.importAsserts(timestep));
|
||||||
|
|
||||||
return ez.expression(ezSAT::OpAnd, prove_bits);
|
return ez.expression(ezSAT::OpAnd, prove_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,15 +721,21 @@ struct SatPass : public Pass {
|
||||||
log("The following additional options can be used to set up a proof. If also -seq\n");
|
log("The following additional options can be used to set up a proof. If also -seq\n");
|
||||||
log("is passed, a temporal induction proof is performed.\n");
|
log("is passed, a temporal induction proof is performed.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -tempinduct\n");
|
||||||
|
log(" Perform a temporal induction proof. In a temporalinduction proof it is\n");
|
||||||
|
log(" proven that the condition holds forever after the number of time steps\n");
|
||||||
|
log(" specified using -seq.\n");
|
||||||
|
log("\n");
|
||||||
log(" -prove <signal> <value>\n");
|
log(" -prove <signal> <value>\n");
|
||||||
log(" Attempt to proof that <signal> is always <value>. In a temporal\n");
|
log(" Attempt to proof that <signal> is always <value>.\n");
|
||||||
log(" induction proof it is proven that the condition holds forever after\n");
|
|
||||||
log(" the number of time steps passed using -seq.\n");
|
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -prove-x <signal> <value>\n");
|
log(" -prove-x <signal> <value>\n");
|
||||||
log(" Like -prove, but an undef (x) bit in the lhs matches any value on\n");
|
log(" Like -prove, but an undef (x) bit in the lhs matches any value on\n");
|
||||||
log(" the right hand side. Useful for equivialence checking.\n");
|
log(" the right hand side. Useful for equivialence checking.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -prove-asserts\n");
|
||||||
|
log(" Prove that all asserts in the design hold.\n");
|
||||||
|
log("\n");
|
||||||
log(" -maxsteps <N>\n");
|
log(" -maxsteps <N>\n");
|
||||||
log(" Set a maximum length for the induction.\n");
|
log(" Set a maximum length for the induction.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
@ -748,6 +758,7 @@ struct SatPass : public Pass {
|
||||||
int loopcount = 0, seq_len = 0, maxsteps = 0, timeout = 0;
|
int loopcount = 0, seq_len = 0, maxsteps = 0, timeout = 0;
|
||||||
bool verify = false, fail_on_timeout = false, enable_undef = false, set_def_inputs = false;
|
bool verify = false, fail_on_timeout = false, enable_undef = false, set_def_inputs = false;
|
||||||
bool ignore_div_by_zero = false, set_init_undef = false, max_undef = false;
|
bool ignore_div_by_zero = false, set_init_undef = false, max_undef = false;
|
||||||
|
bool tempinduct = false, prove_asserts = false;
|
||||||
|
|
||||||
log_header("Executing SAT pass (solving SAT problems in the circuit).\n");
|
log_header("Executing SAT pass (solving SAT problems in the circuit).\n");
|
||||||
|
|
||||||
|
@ -817,6 +828,10 @@ struct SatPass : public Pass {
|
||||||
enable_undef = true;
|
enable_undef = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-tempinduct") {
|
||||||
|
tempinduct = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (args[argidx] == "-prove" && argidx+2 < args.size()) {
|
if (args[argidx] == "-prove" && argidx+2 < args.size()) {
|
||||||
std::string lhs = args[++argidx];
|
std::string lhs = args[++argidx];
|
||||||
std::string rhs = args[++argidx];
|
std::string rhs = args[++argidx];
|
||||||
|
@ -830,6 +845,10 @@ struct SatPass : public Pass {
|
||||||
enable_undef = true;
|
enable_undef = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-prove-asserts") {
|
||||||
|
prove_asserts = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (args[argidx] == "-seq" && argidx+1 < args.size()) {
|
if (args[argidx] == "-seq" && argidx+1 < args.size()) {
|
||||||
seq_len = atoi(args[++argidx].c_str());
|
seq_len = atoi(args[++argidx].c_str());
|
||||||
continue;
|
continue;
|
||||||
|
@ -894,16 +913,22 @@ struct SatPass : public Pass {
|
||||||
if (module == NULL)
|
if (module == NULL)
|
||||||
log_cmd_error("Can't perform SAT on an empty selection!\n");
|
log_cmd_error("Can't perform SAT on an empty selection!\n");
|
||||||
|
|
||||||
if (prove.size() + prove_x.size() == 0 && verify)
|
if (!prove.size() && !prove_x.size() && !prove_asserts && verify)
|
||||||
log_cmd_error("Got -verify but nothing to prove!\n");
|
log_cmd_error("Got -verify but nothing to prove!\n");
|
||||||
|
|
||||||
|
if (!prove.size() && !prove_x.size() && !prove_asserts && tempinduct)
|
||||||
|
log_cmd_error("Got -tempinduct but nothing to prove!\n");
|
||||||
|
|
||||||
|
if (seq_len == 0 && tempinduct)
|
||||||
|
log_cmd_error("Got -tempinduct but no -seq argument!\n");
|
||||||
|
|
||||||
if (set_def_inputs) {
|
if (set_def_inputs) {
|
||||||
for (auto &it : module->wires)
|
for (auto &it : module->wires)
|
||||||
if (it.second->port_input)
|
if (it.second->port_input)
|
||||||
sets_def.push_back(it.second->name);
|
sets_def.push_back(it.second->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prove.size() + prove_x.size() > 0 && seq_len > 0)
|
if (tempinduct)
|
||||||
{
|
{
|
||||||
if (loopcount > 0 || max_undef)
|
if (loopcount > 0 || max_undef)
|
||||||
log_cmd_error("The options -max, -all, and -max_undef are not supported for temporal induction proofs!\n");
|
log_cmd_error("The options -max, -all, and -max_undef are not supported for temporal induction proofs!\n");
|
||||||
|
@ -914,6 +939,7 @@ struct SatPass : public Pass {
|
||||||
basecase.sets = sets;
|
basecase.sets = sets;
|
||||||
basecase.prove = prove;
|
basecase.prove = prove;
|
||||||
basecase.prove_x = prove_x;
|
basecase.prove_x = prove_x;
|
||||||
|
basecase.prove_asserts = prove_asserts;
|
||||||
basecase.sets_at = sets_at;
|
basecase.sets_at = sets_at;
|
||||||
basecase.unsets_at = unsets_at;
|
basecase.unsets_at = unsets_at;
|
||||||
basecase.shows = shows;
|
basecase.shows = shows;
|
||||||
|
@ -935,6 +961,7 @@ struct SatPass : public Pass {
|
||||||
inductstep.sets = sets;
|
inductstep.sets = sets;
|
||||||
inductstep.prove = prove;
|
inductstep.prove = prove;
|
||||||
inductstep.prove_x = prove_x;
|
inductstep.prove_x = prove_x;
|
||||||
|
inductstep.prove_asserts = prove_asserts;
|
||||||
inductstep.shows = shows;
|
inductstep.shows = shows;
|
||||||
inductstep.timeout = timeout;
|
inductstep.timeout = timeout;
|
||||||
inductstep.sets_def = sets_def;
|
inductstep.sets_def = sets_def;
|
||||||
|
@ -1021,6 +1048,7 @@ struct SatPass : public Pass {
|
||||||
sathelper.sets = sets;
|
sathelper.sets = sets;
|
||||||
sathelper.prove = prove;
|
sathelper.prove = prove;
|
||||||
sathelper.prove_x = prove_x;
|
sathelper.prove_x = prove_x;
|
||||||
|
sathelper.prove_asserts = prove_asserts;
|
||||||
sathelper.sets_at = sets_at;
|
sathelper.sets_at = sets_at;
|
||||||
sathelper.unsets_at = unsets_at;
|
sathelper.unsets_at = unsets_at;
|
||||||
sathelper.shows = shows;
|
sathelper.shows = shows;
|
||||||
|
@ -1037,11 +1065,14 @@ struct SatPass : public Pass {
|
||||||
|
|
||||||
if (seq_len == 0) {
|
if (seq_len == 0) {
|
||||||
sathelper.setup();
|
sathelper.setup();
|
||||||
if (sathelper.prove.size() + sathelper.prove_x.size() > 0)
|
if (sathelper.prove.size() || sathelper.prove_x.size() || sathelper.prove_asserts)
|
||||||
sathelper.ez.assume(sathelper.ez.NOT(sathelper.setup_proof()));
|
sathelper.ez.assume(sathelper.ez.NOT(sathelper.setup_proof()));
|
||||||
} else {
|
} else {
|
||||||
for (int timestep = 1; timestep <= seq_len; timestep++)
|
for (int timestep = 1; timestep <= seq_len; timestep++) {
|
||||||
sathelper.setup(timestep);
|
sathelper.setup(timestep);
|
||||||
|
if (sathelper.prove.size() || sathelper.prove_x.size() || sathelper.prove_asserts)
|
||||||
|
sathelper.ez.assume(sathelper.ez.NOT(sathelper.setup_proof(timestep)));
|
||||||
|
}
|
||||||
sathelper.setup_init();
|
sathelper.setup_init();
|
||||||
}
|
}
|
||||||
sathelper.generate_model();
|
sathelper.generate_model();
|
||||||
|
@ -1064,7 +1095,7 @@ struct SatPass : public Pass {
|
||||||
sathelper.maximize_undefs();
|
sathelper.maximize_undefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prove.size() + prove_x.size() == 0) {
|
if (!prove.size() && !prove_x.size() && !prove_asserts) {
|
||||||
log("SAT solving finished - model found:\n");
|
log("SAT solving finished - model found:\n");
|
||||||
} else {
|
} else {
|
||||||
log("SAT proof finished - model found: FAIL!\n");
|
log("SAT proof finished - model found: FAIL!\n");
|
||||||
|
@ -1090,7 +1121,7 @@ struct SatPass : public Pass {
|
||||||
goto timeout;
|
goto timeout;
|
||||||
if (rerun_counter)
|
if (rerun_counter)
|
||||||
log("SAT solving finished - no more models found (after %d distinct solutions).\n", rerun_counter);
|
log("SAT solving finished - no more models found (after %d distinct solutions).\n", rerun_counter);
|
||||||
else if (prove.size() + prove_x.size() == 0)
|
else if (!prove.size() && !prove_x.size() && !prove_asserts)
|
||||||
log("SAT solving finished - no model found.\n");
|
log("SAT solving finished - no model found.\n");
|
||||||
else {
|
else {
|
||||||
log("SAT proof finished - no model found: SUCCESS!\n");
|
log("SAT proof finished - no model found: SUCCESS!\n");
|
||||||
|
|
Loading…
Reference in New Issue