51 std::map<int, std::vector<std::pair<std::string, std::string>>>
sets_at;
87 for (
size_t i = 0; i < sigbits.size(); i++)
94 log (
"\nSetting up initial state:\n");
100 if (it.second->attributes.count(
"\\init") == 0)
108 for (
int i = 0; i < lhs.
size(); i++) {
118 if (removed_bits.size())
123 big_lhs.
remove2(lhs, &big_rhs);
134 log_cmd_error(
"Failed to parse lhs set expression `%s'.\n", s.first.c_str());
136 log_cmd_error(
"Failed to parse rhs set expression `%s'.\n", s.second.c_str());
141 log_cmd_error(
"Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n",
145 big_lhs.
remove2(lhs, &big_rhs);
175 if (big_lhs.
size() == 0) {
176 log(
"No constraints for initial state found.\n\n");
188 log (
"\nSetting up time step %d:\n", timestep);
190 log (
"\nSetting up SAT problem:\n");
202 log_cmd_error(
"Failed to parse lhs set expression `%s'.\n", s.first.c_str());
204 log_cmd_error(
"Failed to parse rhs set expression `%s'.\n", s.second.c_str());
209 log_cmd_error(
"Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n",
213 big_lhs.
remove2(lhs, &big_rhs);
218 for (
auto &s :
sets_at[timestep])
223 log_cmd_error(
"Failed to parse lhs set expression `%s'.\n", s.first.c_str());
225 log_cmd_error(
"Failed to parse rhs set expression `%s'.\n", s.second.c_str());
230 log_cmd_error(
"Set expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n",
234 big_lhs.
remove2(lhs, &big_rhs);
244 log_cmd_error(
"Failed to parse lhs set expression `%s'.\n", s.c_str());
247 log(
"Import unset-constraint for this timestep: %s\n",
log_signal(lhs));
248 big_lhs.
remove2(lhs, &big_rhs);
258 std::set<RTLIL::SigSpec> sets_def_undef[3];
263 log_cmd_error(
"Failed to parse set-def expression `%s'.\n", s.c_str());
264 sets_def_undef[0].insert(sig);
270 log_cmd_error(
"Failed to parse set-def expression `%s'.\n", s.c_str());
271 sets_def_undef[1].insert(sig);
277 log_cmd_error(
"Failed to parse set-def expression `%s'.\n", s.c_str());
278 sets_def_undef[2].insert(sig);
284 log_cmd_error(
"Failed to parse set-def expression `%s'.\n", s.c_str());
285 sets_def_undef[0].insert(sig);
286 sets_def_undef[1].erase(sig);
287 sets_def_undef[2].erase(sig);
293 log_cmd_error(
"Failed to parse set-def expression `%s'.\n", s.c_str());
294 sets_def_undef[0].erase(sig);
295 sets_def_undef[1].insert(sig);
296 sets_def_undef[2].erase(sig);
302 log_cmd_error(
"Failed to parse set-def expression `%s'.\n", s.c_str());
303 sets_def_undef[0].erase(sig);
304 sets_def_undef[1].erase(sig);
305 sets_def_undef[2].insert(sig);
308 for (
int t = 0; t < 3; t++)
309 for (
auto &sig : sets_def_undef[t]) {
310 log(
"Import %s constraint for this timestep: %s\n", t == 0 ?
"def" : t == 1 ?
"any_undef" :
"all_undef",
log_signal(sig));
320 int import_cell_counter = 0;
325 for (
auto &p : c.second->connections())
328 import_cell_counter++;
334 log(
"Imported %d cells to SAT database.\n", import_cell_counter);
342 std::vector<int> prove_bits;
344 if (
prove.size() > 0)
346 for (
auto &s :
prove)
351 log_cmd_error(
"Failed to parse lhs proof expression `%s'.\n", s.first.c_str());
353 log_cmd_error(
"Failed to parse rhs proof expression `%s'.\n", s.second.c_str());
358 log_cmd_error(
"Proof expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n",
362 big_lhs.remove2(lhs, &big_rhs);
379 log_cmd_error(
"Failed to parse lhs proof-x expression `%s'.\n", s.first.c_str());
381 log_cmd_error(
"Failed to parse rhs proof-x expression `%s'.\n", s.second.c_str());
386 log_cmd_error(
"Proof-x expression with different lhs and rhs sizes: %s (%s, %d bits) vs. %s (%s, %d bits)\n",
390 big_lhs.remove2(lhs, &big_rhs);
403 for (
size_t i = 0; i < value_lhs.size(); i++)
404 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))))));
410 for (
int i = 0; i <
GetSize(asserts_a); i++)
421 for (
int i = timestep_from; i < timestep_to; i++)
425 bool solve(
const std::vector<int> &assumptions)
430 if (
ez.getSolverTimoutStatus())
435 bool solve(
int a = 0,
int b = 0,
int c = 0,
int d = 0,
int e = 0,
int f = 0)
440 if (
ez.getSolverTimoutStatus())
468 std::vector<bool> backupValues;
472 std::vector<int> must_undef, maybe_undef;
496 if (
shows.size() == 0)
498 SigPool queued_signals, handled_signals, final_signals;
500 while (queued_signals.
size() > 0) {
502 queued_signals.
del(sig);
503 handled_signals.
add(sig);
505 if (drivers.size() == 0) {
506 final_signals.
add(sig);
508 for (
auto &d : drivers)
509 for (
auto &p : d->connections()) {
510 if (d->type ==
"$dff" && p.first ==
"\\CLK")
512 if (d->type.substr(0, 6) ==
"$_DFF_" && p.first ==
"\\C")
526 for (
auto &s :
shows) {
529 log_cmd_error(
"Failed to parse show expression `%s'.\n", s.c_str());
538 std::vector<int> modelUndefExpressions;
540 for (
auto &c : modelSig.
chunks())
548 for (
int timestep = -1; timestep <=
max_timestep; timestep++)
550 if ((timestep == -1 &&
max_timestep > 0) || timestep == 0)
562 modelUndefExpressions.insert(modelUndefExpressions.end(), undef_vec.begin(), undef_vec.end());
570 for (
auto &c : modelSig.
chunks())
587 modelUndefExpressions.insert(modelUndefExpressions.end(), undef_vec.begin(), undef_vec.end());
596 int maxModelName = 10;
597 int maxModelWidth = 10;
600 maxModelName = std::max(maxModelName,
int(info.description.size()));
601 maxModelWidth = std::max(maxModelWidth, info.width);
606 int last_timestep = -2;
607 for (
auto &info : modelInfo)
610 bool found_undef =
false;
612 for (
int i = 0; i < info.width; i++) {
618 if (info.timestep != last_timestep) {
619 const char *hline =
"---------------------------------------------------------------------------------------------------"
620 "---------------------------------------------------------------------------------------------------"
621 "---------------------------------------------------------------------------------------------------";
622 if (last_timestep == -2) {
624 log(
"%-*s %10s %10s %*s\n", maxModelName+10,
"Signal Name",
"Dec",
"Hex", maxModelWidth+5,
"Bin");
627 log(
"%*.*s %10.10s %10.10s %*.*s\n", maxModelName+10, maxModelName+10,
628 hline, hline, hline, maxModelWidth+5, maxModelWidth+5, hline);
629 last_timestep = info.timestep;
633 if (info.timestep > 0)
634 log(
" %4d ", info.timestep);
640 if (info.width <= 32 && !found_undef)
641 log(
"%-*s %10d %10x %*s\n", maxModelName+10, info.description.c_str(), value.
as_int(), value.
as_int(), maxModelWidth+5, value.
as_string().c_str());
643 log(
"%-*s %10s %10s %*s\n", maxModelName+10, info.description.c_str(),
"--",
"--", maxModelWidth+5, value.
as_string().c_str());
646 if (last_timestep == -2)
647 log(
" no model variables selected for display.\n");
652 FILE *f = fopen(vcd_file_name.c_str(),
"w");
654 log_cmd_error(
"Can't open output file `%s' for writing: %s\n", vcd_file_name.c_str(), strerror(errno));
656 log(
"Dumping SAT model to VCD file %s\n", vcd_file_name.c_str());
660 char stime[128] = {};
662 now = localtime(×tamp);
663 strftime(stime,
sizeof(stime),
"%c", now);
665 std::string module_fname =
"unknown";
666 auto apos =
module->attributes.find(
"\\src");
667 if(apos !=
module->attributes.end())
668 module_fname =
module->attributes[
"\\src"].decode_string();
670 fprintf(f,
"$date\n");
671 fprintf(f,
" %s\n", stime);
672 fprintf(f,
"$end\n");
673 fprintf(f,
"$version\n");
675 fprintf(f,
"$end\n");
676 fprintf(f,
"$comment\n");
677 fprintf(f,
" Generated from SAT problem in module %s (declared at %s)\n",
679 fprintf(f,
"$end\n");
682 std::map<std::string, std::string> vcdnames;
684 fprintf(f,
"$timescale 1ns\n");
688 if (vcdnames.find(info.description) != vcdnames.end())
692 snprintf(namebuf,
sizeof(namebuf),
"v%d", static_cast<int>(vcdnames.size()));
693 vcdnames[info.description] = namebuf;
696 std::string legal_desc = info.description.c_str();
697 for (
auto &c : legal_desc) {
704 fprintf(f,
"$var wire %d %s %s $end\n", info.width, namebuf, legal_desc.c_str());
709 if(info.timestep > 1)
712 fprintf(f,
"$upscope $end\n");
713 fprintf(f,
"$enddefinitions $end\n");
714 fprintf(f,
"$dumpvars\n");
716 static const char bitvals[] =
"01xzxx";
718 int last_timestep = -2;
719 for (
auto &info : modelInfo)
723 for (
int i = 0; i < info.width; i++) {
729 if (info.timestep != last_timestep) {
730 if(last_timestep == 0)
731 fprintf(f,
"$end\n");
733 fprintf(f,
"#%d\n", info.timestep);
734 last_timestep = info.timestep;
737 if(info.width == 1) {
738 fprintf(f,
"%c%s\n", bitvals[value.
bits[0]], vcdnames[info.description].c_str());
741 for(
int k=info.width-1; k >= 0; k --)
742 fprintf(f,
"%c", bitvals[value.
bits[k]]);
743 fprintf(f,
" %s\n", vcdnames[info.description].c_str());
747 if (last_timestep == -2)
748 log(
" no model variables selected for display.\n");
755 std::vector<int> clause;
760 if (!max_undef || !val_undef)
761 clause.push_back(val_undef ?
ez.NOT(bit_undef) : val ?
ez.NOT(bit) : bit);
773 log(
" ______ ___ ___ _ _ _ _ \n");
774 log(
" (_____ \\ / __) / __) (_) | | | |\n");
775 log(
" _____) )___ ___ ___ _| |__ _| |__ _____ _| | _____ __| | |\n");
776 log(
" | ____/ ___) _ \\ / _ (_ __) (_ __|____ | | || ___ |/ _ |_|\n");
777 log(
" | | | | | |_| | |_| || | | | / ___ | | || ____( (_| |_ \n");
778 log(
" |_| |_| \\___/ \\___/ |_| |_| \\_____|_|\\_)_____)\\____|_|\n");
785 log(
" _____ _ _ _____ ____ _ _____\n");
786 log(
" /__ __\\/ \\/ \\__/|/ __// _ \\/ \\ /\\/__ __\\\n");
787 log(
" / \\ | || |\\/||| \\ | / \\|| | || / \\\n");
788 log(
" | | | || | ||| /_ | \\_/|| \\_/| | |\n");
789 log(
" \\_/ \\_/\\_/ \\|\\____\\\\____/\\____/ \\_/\n");
796 log(
" /$$$$$$ /$$$$$$$$ /$$$$$$$ \n");
797 log(
" /$$__ $$ | $$_____/ | $$__ $$ \n");
798 log(
" | $$ \\ $$ | $$ | $$ \\ $$ \n");
799 log(
" | $$ | $$ | $$$$$ | $$ | $$ \n");
800 log(
" | $$ | $$ | $$__/ | $$ | $$ \n");
801 log(
" | $$/$$ $$ | $$ | $$ | $$ \n");
802 log(
" | $$$$$$/ /$$| $$$$$$$$ /$$| $$$$$$$//$$\n");
803 log(
" \\____ $$$|__/|________/|__/|_______/|__/\n");
814 log(
" sat [options] [selection]\n");
816 log(
"This command solves a SAT problem defined over the currently selected circuit\n");
817 log(
"and additional constraints passed as parameters.\n");
820 log(
" show all solutions to the problem (this can grow exponentially, use\n");
821 log(
" -max <N> instead to get <N> solutions)\n");
824 log(
" like -all, but limit number of solutions to <N>\n");
826 log(
" -enable_undef\n");
827 log(
" enable modeling of undef value (aka 'x-bits')\n");
828 log(
" this option is implied by -set-def, -set-undef et. cetera\n");
830 log(
" -max_undef\n");
831 log(
" maximize the number of undef bits in solutions, giving a better\n");
832 log(
" picture of which input bits are actually vital to the solution.\n");
834 log(
" -set <signal> <value>\n");
835 log(
" set the specified signal to the specified value.\n");
837 log(
" -set-def <signal>\n");
838 log(
" add a constraint that all bits of the given signal must be defined\n");
840 log(
" -set-any-undef <signal>\n");
841 log(
" add a constraint that at least one bit of the given signal is undefined\n");
843 log(
" -set-all-undef <signal>\n");
844 log(
" add a constraint that all bits of the given signal are undefined\n");
846 log(
" -set-def-inputs\n");
847 log(
" add -set-def constraints for all module inputs\n");
849 log(
" -show <signal>\n");
850 log(
" show the model for the specified signal. if no -show option is\n");
851 log(
" passed then a set of signals to be shown is automatically selected.\n");
853 log(
" -show-inputs, -show-outputs\n");
854 log(
" add all module input (output) ports to the list of shown signals\n");
856 log(
" -ignore_div_by_zero\n");
857 log(
" ignore all solutions that involve a division by zero\n");
859 log(
" -ignore_unknown_cells\n");
860 log(
" ignore all cells that can not be matched to a SAT model\n");
862 log(
"The following options can be used to set up a sequential problem:\n");
865 log(
" set up a sequential problem with <N> time steps. The steps will\n");
866 log(
" be numbered from 1 to N.\n");
868 log(
" -set-at <N> <signal> <value>\n");
869 log(
" -unset-at <N> <signal>\n");
870 log(
" set or unset the specified signal to the specified value in the\n");
871 log(
" given timestep. this has priority over a -set for the same signal.\n");
873 log(
" -set-def-at <N> <signal>\n");
874 log(
" -set-any-undef-at <N> <signal>\n");
875 log(
" -set-all-undef-at <N> <signal>\n");
876 log(
" add undef constraints in the given timestep.\n");
878 log(
" -set-init <signal> <value>\n");
879 log(
" set the initial value for the register driving the signal to the value\n");
881 log(
" -set-init-undef\n");
882 log(
" set all initial states (not set using -set-init) to undef\n");
884 log(
" -set-init-def\n");
885 log(
" do not force a value for the initial state but do not allow undef\n");
887 log(
" -set-init-zero\n");
888 log(
" set all initial states (not set using -set-init) to zero\n");
890 log(
" -dump_vcd <vcd-file-name>\n");
891 log(
" dump SAT model (counter example in proof) to VCD file\n");
893 log(
" -dump_cnf <cnf-file-name>\n");
894 log(
" dump CNF of SAT problem (in DIMACS format). in temporal induction\n");
895 log(
" proofs this is the CNF of the first induction step.\n");
897 log(
"The following additional options can be used to set up a proof. If also -seq\n");
898 log(
"is passed, a temporal induction proof is performed.\n");
900 log(
" -tempinduct\n");
901 log(
" Perform a temporal induction proof. In a temporalinduction proof it is\n");
902 log(
" proven that the condition holds forever after the number of time steps\n");
903 log(
" specified using -seq.\n");
905 log(
" -tempinduct-def\n");
906 log(
" Perform a temporal induction proof. Assume an initial state with all\n");
907 log(
" registers set to defined values for the induction step.\n");
909 log(
" -prove <signal> <value>\n");
910 log(
" Attempt to proof that <signal> is always <value>.\n");
912 log(
" -prove-x <signal> <value>\n");
913 log(
" Like -prove, but an undef (x) bit in the lhs matches any value on\n");
914 log(
" the right hand side. Useful for equivialence checking.\n");
916 log(
" -prove-asserts\n");
917 log(
" Prove that all asserts in the design hold.\n");
919 log(
" -prove-skip <N>\n");
920 log(
" Do not enforce the prove-condition for the first <N> time steps.\n");
922 log(
" -maxsteps <N>\n");
923 log(
" Set a maximum length for the induction.\n");
925 log(
" -initsteps <N>\n");
926 log(
" Set initial length for the induction.\n");
928 log(
" -timeout <N>\n");
929 log(
" Maximum number of seconds a single SAT instance may take.\n");
932 log(
" Return an error and stop the synthesis script if the proof fails.\n");
934 log(
" -verify-no-timeout\n");
935 log(
" Like -verify but do not return an error for timeouts.\n");
938 log(
" Return an error and stop the synthesis script if the proof succeeds.\n");
940 log(
" -falsify-no-timeout\n");
941 log(
" Like -falsify but do not return an error for timeouts.\n");
946 std::vector<std::pair<std::string, std::string>> sets, sets_init, prove, prove_x;
947 std::map<int, std::vector<std::pair<std::string, std::string>>> sets_at;
948 std::map<int, std::vector<std::string>> unsets_at, sets_def_at, sets_any_undef_at, sets_all_undef_at;
949 std::vector<std::string> shows, sets_def, sets_any_undef, sets_all_undef;
950 int loopcount = 0, seq_len = 0, maxsteps = 0, initsteps = 0, timeout = 0, prove_skip = 0;
951 bool verify =
false, fail_on_timeout =
false, enable_undef =
false, set_def_inputs =
false;
952 bool ignore_div_by_zero =
false, set_init_undef =
false, set_init_zero =
false, max_undef =
false;
953 bool tempinduct =
false, prove_asserts =
false, show_inputs =
false, show_outputs =
false;
954 bool ignore_unknown_cells =
false, falsify =
false, tempinduct_def =
false, set_init_def =
false;
955 std::string vcd_file_name, cnf_file_name;
957 log_header(
"Executing SAT pass (solving SAT problems in the circuit).\n");
960 for (argidx = 1; argidx < args.size(); argidx++) {
961 if (args[argidx] ==
"-all") {
965 if (args[argidx] ==
"-verify") {
966 fail_on_timeout =
true;
970 if (args[argidx] ==
"-verify-no-timeout") {
974 if (args[argidx] ==
"-falsify") {
975 fail_on_timeout =
true;
979 if (args[argidx] ==
"-falsify-no-timeout") {
983 if (args[argidx] ==
"-timeout" && argidx+1 < args.size()) {
984 timeout = atoi(args[++argidx].c_str());
987 if (args[argidx] ==
"-max" && argidx+1 < args.size()) {
988 loopcount = atoi(args[++argidx].c_str());
991 if (args[argidx] ==
"-maxsteps" && argidx+1 < args.size()) {
992 maxsteps = atoi(args[++argidx].c_str());
995 if (args[argidx] ==
"-initsteps" && argidx+1 < args.size()) {
996 initsteps = atoi(args[++argidx].c_str());
999 if (args[argidx] ==
"-ignore_div_by_zero") {
1000 ignore_div_by_zero =
true;
1003 if (args[argidx] ==
"-enable_undef") {
1004 enable_undef =
true;
1007 if (args[argidx] ==
"-max_undef") {
1008 enable_undef =
true;
1012 if (args[argidx] ==
"-set-def-inputs") {
1013 enable_undef =
true;
1014 set_def_inputs =
true;
1017 if (args[argidx] ==
"-set" && argidx+2 < args.size()) {
1018 std::string lhs = args[++argidx];
1019 std::string rhs = args[++argidx];
1020 sets.push_back(std::pair<std::string, std::string>(lhs, rhs));
1023 if (args[argidx] ==
"-set-def" && argidx+1 < args.size()) {
1024 sets_def.push_back(args[++argidx]);
1025 enable_undef =
true;
1028 if (args[argidx] ==
"-set-any-undef" && argidx+1 < args.size()) {
1029 sets_any_undef.push_back(args[++argidx]);
1030 enable_undef =
true;
1033 if (args[argidx] ==
"-set-all-undef" && argidx+1 < args.size()) {
1034 sets_all_undef.push_back(args[++argidx]);
1035 enable_undef =
true;
1038 if (args[argidx] ==
"-tempinduct") {
1042 if (args[argidx] ==
"-tempinduct-def") {
1044 tempinduct_def =
true;
1047 if (args[argidx] ==
"-prove" && argidx+2 < args.size()) {
1048 std::string lhs = args[++argidx];
1049 std::string rhs = args[++argidx];
1050 prove.push_back(std::pair<std::string, std::string>(lhs, rhs));
1053 if (args[argidx] ==
"-prove-x" && argidx+2 < args.size()) {
1054 std::string lhs = args[++argidx];
1055 std::string rhs = args[++argidx];
1056 prove_x.push_back(std::pair<std::string, std::string>(lhs, rhs));
1057 enable_undef =
true;
1060 if (args[argidx] ==
"-prove-asserts") {
1061 prove_asserts =
true;
1064 if (args[argidx] ==
"-prove-skip" && argidx+1 < args.size()) {
1065 prove_skip = atoi(args[++argidx].c_str());
1068 if (args[argidx] ==
"-seq" && argidx+1 < args.size()) {
1069 seq_len = atoi(args[++argidx].c_str());
1072 if (args[argidx] ==
"-set-at" && argidx+3 < args.size()) {
1073 int timestep = atoi(args[++argidx].c_str());
1074 std::string lhs = args[++argidx];
1075 std::string rhs = args[++argidx];
1076 sets_at[timestep].push_back(std::pair<std::string, std::string>(lhs, rhs));
1079 if (args[argidx] ==
"-unset-at" && argidx+2 < args.size()) {
1080 int timestep = atoi(args[++argidx].c_str());
1081 unsets_at[timestep].push_back(args[++argidx]);
1084 if (args[argidx] ==
"-set-def-at" && argidx+2 < args.size()) {
1085 int timestep = atoi(args[++argidx].c_str());
1086 sets_def_at[timestep].push_back(args[++argidx]);
1087 enable_undef =
true;
1090 if (args[argidx] ==
"-set-any-undef-at" && argidx+2 < args.size()) {
1091 int timestep = atoi(args[++argidx].c_str());
1092 sets_any_undef_at[timestep].push_back(args[++argidx]);
1093 enable_undef =
true;
1096 if (args[argidx] ==
"-set-all-undef-at" && argidx+2 < args.size()) {
1097 int timestep = atoi(args[++argidx].c_str());
1098 sets_all_undef_at[timestep].push_back(args[++argidx]);
1099 enable_undef =
true;
1102 if (args[argidx] ==
"-set-init" && argidx+2 < args.size()) {
1103 std::string lhs = args[++argidx];
1104 std::string rhs = args[++argidx];
1105 sets_init.push_back(std::pair<std::string, std::string>(lhs, rhs));
1108 if (args[argidx] ==
"-set-init-undef") {
1109 set_init_undef =
true;
1110 enable_undef =
true;
1113 if (args[argidx] ==
"-set-init-def") {
1114 set_init_def =
true;
1117 if (args[argidx] ==
"-set-init-zero") {
1118 set_init_zero =
true;
1121 if (args[argidx] ==
"-show" && argidx+1 < args.size()) {
1122 shows.push_back(args[++argidx]);
1125 if (args[argidx] ==
"-show-inputs") {
1129 if (args[argidx] ==
"-show-outputs") {
1130 show_outputs =
true;
1133 if (args[argidx] ==
"-ignore_unknown_cells") {
1134 ignore_unknown_cells =
true;
1137 if (args[argidx] ==
"-dump_vcd" && argidx+1 < args.size()) {
1138 vcd_file_name = args[++argidx];
1141 if (args[argidx] ==
"-dump_cnf" && argidx+1 < args.size()) {
1142 cnf_file_name = args[++argidx];
1150 for (
auto &mod_it : design->
modules_)
1151 if (design->
selected(mod_it.second)) {
1153 log_cmd_error(
"Only one module must be selected for the SAT pass! (selected: %s and %s)\n",
1155 module = mod_it.second;
1158 log_cmd_error(
"Can't perform SAT on an empty selection!\n");
1160 if (!prove.size() && !prove_x.size() && !prove_asserts && tempinduct)
1163 if (prove_skip && tempinduct)
1164 log_cmd_error(
"Options -prove-skip and -tempinduct don't work with each other.\n");
1166 if (prove_skip >= seq_len && prove_skip > 0)
1167 log_cmd_error(
"The value of -prove-skip must be smaller than the one of -seq.\n");
1169 if (set_init_undef + set_init_zero + set_init_def > 1)
1170 log_cmd_error(
"The options -set-init-undef, -set-init-def, and -set-init-zero are exclusive!\n");
1172 if (set_def_inputs) {
1173 for (
auto &it : module->
wires_)
1174 if (it.second->port_input)
1175 sets_def.push_back(it.second->name.str());
1179 for (
auto &it : module->
wires_)
1180 if (it.second->port_input)
1181 shows.push_back(it.second->name.str());
1185 for (
auto &it : module->
wires_)
1186 if (it.second->port_output)
1187 shows.push_back(it.second->name.str());
1192 if (loopcount > 0 || max_undef)
1193 log_cmd_error(
"The options -max, -all, and -max_undef are not supported for temporal induction proofs!\n");
1195 SatHelper basecase(design, module, enable_undef);
1196 SatHelper inductstep(design, module, enable_undef);
1198 basecase.
sets = sets;
1199 basecase.
prove = prove;
1204 basecase.
shows = shows;
1219 for (
int timestep = 1; timestep <= seq_len; timestep++)
1220 basecase.
setup(timestep);
1223 inductstep.
sets = sets;
1224 inductstep.
prove = prove;
1227 inductstep.
shows = shows;
1235 inductstep.
setup(1);
1238 if (tempinduct_def) {
1240 inductstep.
ez.assume(inductstep.
ez.NOT(inductstep.
ez.expression(
ezSAT::OpOr, undef_state)));
1243 for (
int inductlen = 1; inductlen <= maxsteps || maxsteps == 0; inductlen++)
1245 log(
"\n** Trying induction with length %d **\n", inductlen);
1249 basecase.
setup(seq_len + inductlen);
1250 int property = basecase.
setup_proof(seq_len + inductlen);
1256 log(
"\n[base case] Solving problem with %d variables and %d clauses..\n",
1257 basecase.
ez.numCnfVariables(), basecase.
ez.numCnfClauses());
1259 if (basecase.
solve(basecase.
ez.NOT(property))) {
1260 log(
"SAT temporal induction proof finished - model found for base case: FAIL!\n");
1263 if(!vcd_file_name.empty())
1271 log(
"Base case for induction length %d proven.\n", inductlen);
1272 basecase.
ez.assume(property);
1276 inductstep.
setup(inductlen + 1);
1283 if (inductlen < initsteps)
1285 log(
"\n[induction step] Skipping problem with %d variables and %d clauses (below initsteps).\n",
1286 inductstep.
ez.numCnfVariables(), inductstep.
ez.numCnfClauses());
1287 inductstep.
ez.assume(property);
1291 if (!cnf_file_name.empty())
1293 FILE *f = fopen(cnf_file_name.c_str(),
"w");
1295 log_cmd_error(
"Can't open output file `%s' for writing: %s\n", cnf_file_name.c_str(), strerror(errno));
1297 log(
"Dumping CNF to file `%s'.\n", cnf_file_name.c_str());
1298 cnf_file_name.clear();
1300 inductstep.
ez.printDIMACS(f,
false);
1304 log(
"\n[induction step] Solving problem with %d variables and %d clauses..\n",
1305 inductstep.
ez.numCnfVariables(), inductstep.
ez.numCnfClauses());
1307 if (!inductstep.
solve(inductstep.
ez.NOT(property))) {
1310 log(
"Induction step proven: SUCCESS!\n");
1315 log(
"Induction step failed. Incrementing induction length.\n");
1316 inductstep.
ez.assume(property);
1321 log(
"\nReached maximum number of time steps -> proof failed.\n");
1322 if(!vcd_file_name.empty())
1329 log_error(
"Called with -verify and proof did fail!\n");
1336 log_error(
"Called with -falsify and proof did succeed!\n");
1342 log_cmd_error(
"The options -maxsteps is only supported for temporal induction proofs!\n");
1344 SatHelper sathelper(design, module, enable_undef);
1346 sathelper.
sets = sets;
1347 sathelper.
prove = prove;
1352 sathelper.
shows = shows;
1372 std::vector<int> prove_bits;
1373 for (
int timestep = 1; timestep <= seq_len; timestep++) {
1374 sathelper.
setup(timestep);
1376 if (timestep > prove_skip)
1377 prove_bits.push_back(sathelper.
setup_proof(timestep));
1380 sathelper.
ez.assume(sathelper.
ez.NOT(sathelper.
ez.expression(
ezSAT::OpAnd, prove_bits)));
1385 if (!cnf_file_name.empty())
1387 FILE *f = fopen(cnf_file_name.c_str(),
"w");
1389 log_cmd_error(
"Can't open output file `%s' for writing: %s\n", cnf_file_name.c_str(), strerror(errno));
1391 log(
"Dumping CNF to file `%s'.\n", cnf_file_name.c_str());
1392 cnf_file_name.clear();
1394 sathelper.
ez.printDIMACS(f,
false);
1398 int rerun_counter = 0;
1401 log(
"\nSolving problem with %d variables and %d clauses..\n",
1402 sathelper.
ez.numCnfVariables(), sathelper.
ez.numCnfClauses());
1404 if (sathelper.
solve())
1407 log(
"SAT model found. maximizing number of undefs.\n");
1411 if (!prove.size() && !prove_x.size() && !prove_asserts) {
1412 log(
"SAT solving finished - model found:\n");
1414 log(
"SAT proof finished - model found: FAIL!\n");
1420 if(!vcd_file_name.empty())
1423 if (loopcount != 0) {
1424 loopcount--, rerun_counter++;
1429 if (!prove.size() && !prove_x.size() && !prove_asserts) {
1432 log_error(
"Called with -falsify and found a model!\n");
1437 log_error(
"Called with -verify and proof did fail!\n");
1446 log(
"SAT solving finished - no more models found (after %d distinct solutions).\n", rerun_counter);
1447 else if (!prove.size() && !prove_x.size() && !prove_asserts) {
1448 log(
"SAT solving finished - no model found.\n");
1451 log_error(
"Called with -verify and found no model!\n");
1454 log(
"SAT proof finished - no model found: SUCCESS!\n");
1458 log_error(
"Called with -falsify and proof did succeed!\n");
1463 if (!prove.size() && !prove_x.size() && !prove_asserts) {
1464 if (falsify && rerun_counter) {
1466 log_error(
"Called with -falsify and found a model!\n");
1469 if (verify && rerun_counter) {
1471 log_error(
"Called with -verify and proof did fail!\n");
1478 log(
"Interrupted SAT solver: TIMEOUT!\n");
1480 if (fail_on_timeout)
1481 log_error(
"Called with -verify and proof did time out!\n");
const char * yosys_version_str
const char * c_str() const
bool selected(T1 *module) const
int setup_proof(int timestep=-1)
void print_proof_failed()
void log_warning(const char *format,...)
RTLIL::SigSpec export_one()
int importAsserts(int timestep=-1)
static bool parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL::Module *module, std::string str)
void log_header(const char *format,...)
std::vector< std::pair< std::string, std::string > > sets_init
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
SatHelper(RTLIL::Design *design, RTLIL::Module *module, bool enable_undef)
std::vector< int > importSigSpec(RTLIL::SigSpec sig, int timestep=-1)
std::vector< std::string > sets_all_undef
void log_error(const char *format,...)
void dump_model_to_vcd(std::string vcd_file_name)
void remove(const RTLIL::SigSpec &pattern)
void getAsserts(RTLIL::SigSpec &sig_a, RTLIL::SigSpec &sig_en, int timestep=-1)
std::vector< std::string > shows
bool ignore_unknown_cells
std::map< int, std::vector< std::pair< std::string, std::string > > > sets_at
SigSet< RTLIL::Cell * > show_drivers
std::vector< bool > modelValues
void force_unique_state(int timestep_from, int timestep_to)
std::vector< int > importUndefSigSpec(RTLIL::SigSpec sig, int timestep=-1)
std::vector< int > modelExpressions
YOSYS_NAMESPACE_BEGIN typedef ezMiniSAT ezDefaultSAT
std::vector< std::string > sets_any_undef
bool solve(const std::vector< int > &assumptions)
std::vector< int > importDefSigSpec(RTLIL::SigSpec sig, int timestep=-1)
std::string as_string() const
#define PRIVATE_NAMESPACE_BEGIN
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
int GetSize(RTLIL::Wire *wire)
void setup(int timestep=-1)
#define log_assert(_assert_expr_)
RTLIL::SigSpec export_all()
std::map< int, std::vector< std::string > > sets_any_undef_at
void remove2(const RTLIL::SigSpec &pattern, RTLIL::SigSpec *other)
#define PRIVATE_NAMESPACE_END
bool check_all(RTLIL::SigSpec sig)
static const char * id2cstr(const RTLIL::IdString &str)
std::vector< std::pair< std::string, std::string > > sets
RTLIL::SigSpec remove(RTLIL::SigSpec sig)
void log_cmd_error(const char *format,...)
int as_int(bool is_signed=false) const
void add(RTLIL::SigSpec sig)
#define USING_YOSYS_NAMESPACE
std::map< RTLIL::IdString, RTLIL::Module * > modules_
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
void log(const char *format,...)
bool solve(int a=0, int b=0, int c=0, int d=0, int e=0, int f=0)
bool importCell(RTLIL::Cell *cell, int timestep=-1)
std::map< int, std::vector< std::string > > sets_def_at
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
std::vector< RTLIL::State > bits
void append(const RTLIL::SigSpec &signal)
static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str)
std::vector< std::pair< std::string, std::string > > prove_x
void del(RTLIL::SigSpec sig)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
bool operator<(const ModelBlockInfo &other) const
std::set< ModelBlockInfo > modelInfo
std::map< int, std::vector< std::string > > unsets_at
std::vector< std::pair< std::string, std::string > > prove
void find(RTLIL::SigSpec sig, std::set< T > &result)
void insert(RTLIL::SigSpec sig, T data)
std::vector< RTLIL::SigBit > to_sigbit_vector() const
std::vector< std::string > sets_def
int signals_eq(RTLIL::SigSpec lhs, RTLIL::SigSpec rhs, int timestep_lhs=-1, int timestep_rhs=-1)
const std::vector< RTLIL::SigChunk > & chunks() const
std::map< int, std::vector< std::string > > sets_all_undef_at
void check_undef_enabled(const RTLIL::SigSpec &sig)
void invalidate_model(bool max_undef)