yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SatPass Struct Reference
+ Inheritance diagram for SatPass:
+ Collaboration diagram for SatPass:

Public Member Functions

 SatPass ()
 
virtual void help ()
 
virtual void execute (std::vector< std::string > args, RTLIL::Design *design)
 
pre_post_exec_state_t pre_execute ()
 
void post_execute (pre_post_exec_state_t state)
 
void cmd_log_args (const std::vector< std::string > &args)
 
void cmd_error (const std::vector< std::string > &args, size_t argidx, std::string msg)
 
void extra_args (std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
 
virtual void run_register ()
 

Static Public Member Functions

static void call (RTLIL::Design *design, std::string command)
 
static void call (RTLIL::Design *design, std::vector< std::string > args)
 
static void call_on_selection (RTLIL::Design *design, const RTLIL::Selection &selection, std::string command)
 
static void call_on_selection (RTLIL::Design *design, const RTLIL::Selection &selection, std::vector< std::string > args)
 
static void call_on_module (RTLIL::Design *design, RTLIL::Module *module, std::string command)
 
static void call_on_module (RTLIL::Design *design, RTLIL::Module *module, std::vector< std::string > args)
 
static void init_register ()
 
static void done_register ()
 

Data Fields

std::string pass_name
 
std::string short_help
 
int call_counter
 
int64_t runtime_ns
 
Passnext_queued_pass
 

Detailed Description

Definition at line 808 of file sat.cc.

Constructor & Destructor Documentation

SatPass::SatPass ( )
inline

Definition at line 809 of file sat.cc.

809 : Pass("sat", "solve a SAT problem in the circuit") { }
Pass(std::string name, std::string short_help="** document me **")
Definition: register.cc:40

Member Function Documentation

void Pass::call ( RTLIL::Design design,
std::string  command 
)
staticinherited

Definition at line 146 of file register.cc.

147 {
148  std::vector<std::string> args;
149 
150  std::string cmd_buf = command;
151  std::string tok = next_token(cmd_buf, " \t\r\n");
152 
153  if (tok.empty() || tok[0] == '#')
154  return;
155 
156  if (tok[0] == '!') {
157  cmd_buf = command.substr(command.find('!') + 1);
158  while (!cmd_buf.empty() && (cmd_buf.back() == ' ' || cmd_buf.back() == '\t' ||
159  cmd_buf.back() == '\r' || cmd_buf.back() == '\n'))
160  cmd_buf.resize(cmd_buf.size()-1);
161  log_header("Shell command: %s\n", cmd_buf.c_str());
162  int retCode = run_command(cmd_buf);
163  if (retCode != 0)
164  log_cmd_error("Shell command returned error code %d.\n", retCode);
165  return;
166  }
167 
168  while (!tok.empty()) {
169  if (tok == "#")
170  break;
171  if (tok.back() == ';') {
172  int num_semikolon = 0;
173  while (!tok.empty() && tok.back() == ';')
174  tok.resize(tok.size()-1), num_semikolon++;
175  if (!tok.empty())
176  args.push_back(tok);
177  call(design, args);
178  args.clear();
179  if (num_semikolon == 2)
180  call(design, "clean");
181  if (num_semikolon == 3)
182  call(design, "clean -purge");
183  } else
184  args.push_back(tok);
185  tok = next_token(cmd_buf, " \t\r\n");
186  }
187 
188  call(design, args);
189 }
static std::string next_token(bool pass_newline=false)
Definition: preproc.cc:96
void log_header(const char *format,...)
Definition: log.cc:188
int run_command(const std::string &command, std::function< void(const std::string &)> process_line)
Definition: yosys.cc:195
void log_cmd_error(const char *format,...)
Definition: log.cc:211
static void call(RTLIL::Design *design, std::string command)
Definition: register.cc:146

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Pass::call ( RTLIL::Design design,
std::vector< std::string >  args 
)
staticinherited

Definition at line 191 of file register.cc.

192 {
193  if (args.size() == 0 || args[0][0] == '#')
194  return;
195 
196  if (echo_mode) {
197  log("%s", create_prompt(design, 0));
198  for (size_t i = 0; i < args.size(); i++)
199  log("%s%s", i ? " " : "", args[i].c_str());
200  log("\n");
201  }
202 
203  if (pass_register.count(args[0]) == 0)
204  log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str());
205 
206  size_t orig_sel_stack_pos = design->selection_stack.size();
207  auto state = pass_register[args[0]]->pre_execute();
208  pass_register[args[0]]->execute(args, design);
209  pass_register[args[0]]->post_execute(state);
210  while (design->selection_stack.size() > orig_sel_stack_pos)
211  design->selection_stack.pop_back();
212 
213  design->check();
214 }
bool echo_mode
Definition: register.cc:30
std::vector< RTLIL::Selection > selection_stack
Definition: rtlil.h:509
const char * create_prompt(RTLIL::Design *design, int recursion_counter)
Definition: yosys.cc:400
void check()
Definition: rtlil.cc:357
void log_cmd_error(const char *format,...)
Definition: log.cc:211
void log(const char *format,...)
Definition: log.cc:180
std::map< std::string, Pass * > pass_register
Definition: register.cc:35

+ Here is the call graph for this function:

void Pass::call_on_module ( RTLIL::Design design,
RTLIL::Module module,
std::string  command 
)
staticinherited

Definition at line 240 of file register.cc.

241 {
242  std::string backup_selected_active_module = design->selected_active_module;
243  design->selected_active_module = module->name.str();
244  design->selection_stack.push_back(RTLIL::Selection(false));
245  design->selection_stack.back().select(module);
246 
247  Pass::call(design, command);
248 
249  design->selection_stack.pop_back();
250  design->selected_active_module = backup_selected_active_module;
251 }
std::string str() const
Definition: rtlil.h:182
std::vector< RTLIL::Selection > selection_stack
Definition: rtlil.h:509
RTLIL::IdString name
Definition: rtlil.h:599
std::string selected_active_module
Definition: rtlil.h:511
static void call(RTLIL::Design *design, std::string command)
Definition: register.cc:146

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Pass::call_on_module ( RTLIL::Design design,
RTLIL::Module module,
std::vector< std::string >  args 
)
staticinherited

Definition at line 253 of file register.cc.

254 {
255  std::string backup_selected_active_module = design->selected_active_module;
256  design->selected_active_module = module->name.str();
257  design->selection_stack.push_back(RTLIL::Selection(false));
258  design->selection_stack.back().select(module);
259 
260  Pass::call(design, args);
261 
262  design->selection_stack.pop_back();
263  design->selected_active_module = backup_selected_active_module;
264 }
std::string str() const
Definition: rtlil.h:182
std::vector< RTLIL::Selection > selection_stack
Definition: rtlil.h:509
RTLIL::IdString name
Definition: rtlil.h:599
std::string selected_active_module
Definition: rtlil.h:511
static void call(RTLIL::Design *design, std::string command)
Definition: register.cc:146

+ Here is the call graph for this function:

void Pass::call_on_selection ( RTLIL::Design design,
const RTLIL::Selection selection,
std::string  command 
)
staticinherited

Definition at line 216 of file register.cc.

217 {
218  std::string backup_selected_active_module = design->selected_active_module;
219  design->selected_active_module.clear();
220  design->selection_stack.push_back(selection);
221 
222  Pass::call(design, command);
223 
224  design->selection_stack.pop_back();
225  design->selected_active_module = backup_selected_active_module;
226 }
std::vector< RTLIL::Selection > selection_stack
Definition: rtlil.h:509
std::string selected_active_module
Definition: rtlil.h:511
static void call(RTLIL::Design *design, std::string command)
Definition: register.cc:146

+ Here is the call graph for this function:

void Pass::call_on_selection ( RTLIL::Design design,
const RTLIL::Selection selection,
std::vector< std::string >  args 
)
staticinherited

Definition at line 228 of file register.cc.

229 {
230  std::string backup_selected_active_module = design->selected_active_module;
231  design->selected_active_module.clear();
232  design->selection_stack.push_back(selection);
233 
234  Pass::call(design, args);
235 
236  design->selection_stack.pop_back();
237  design->selected_active_module = backup_selected_active_module;
238 }
std::vector< RTLIL::Selection > selection_stack
Definition: rtlil.h:509
std::string selected_active_module
Definition: rtlil.h:511
static void call(RTLIL::Design *design, std::string command)
Definition: register.cc:146

+ Here is the call graph for this function:

void Pass::cmd_error ( const std::vector< std::string > &  args,
size_t  argidx,
std::string  msg 
)
inherited

Definition at line 110 of file register.cc.

111 {
112  std::string command_text;
113  int error_pos = 0;
114 
115  for (size_t i = 0; i < args.size(); i++) {
116  if (i < argidx)
117  error_pos += args[i].size() + 1;
118  command_text = command_text + (command_text.empty() ? "" : " ") + args[i];
119  }
120 
121  log("\nSyntax error in command `%s':\n", command_text.c_str());
122  help();
123 
124  log_cmd_error("Command syntax error: %s\n> %s\n> %*s^\n",
125  msg.c_str(), command_text.c_str(), error_pos, "");
126 }
virtual void help()
Definition: register.cc:93
void log_cmd_error(const char *format,...)
Definition: log.cc:211
void log(const char *format,...)
Definition: log.cc:180

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Pass::cmd_log_args ( const std::vector< std::string > &  args)
inherited

Definition at line 100 of file register.cc.

101 {
102  if (args.size() <= 1)
103  return;
104  log("Full command line:");
105  for (size_t i = 0; i < args.size(); i++)
106  log(" %s", args[i].c_str());
107  log("\n");
108 }
void log(const char *format,...)
Definition: log.cc:180

+ Here is the call graph for this function:

void Pass::done_register ( )
staticinherited

Definition at line 62 of file register.cc.

63 {
64  frontend_register.clear();
65  pass_register.clear();
66  backend_register.clear();
68 }
std::map< std::string, Frontend * > frontend_register
Definition: register.cc:34
Pass * first_queued_pass
Definition: register.cc:31
#define log_assert(_assert_expr_)
Definition: log.h:85
#define NULL
std::map< std::string, Pass * > pass_register
Definition: register.cc:35
std::map< std::string, Backend * > backend_register
Definition: register.cc:36

+ Here is the caller graph for this function:

virtual void SatPass::execute ( std::vector< std::string >  args,
RTLIL::Design design 
)
inlinevirtual

Implements Pass.

Definition at line 944 of file sat.cc.

945  {
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;
956 
957  log_header("Executing SAT pass (solving SAT problems in the circuit).\n");
958 
959  size_t argidx;
960  for (argidx = 1; argidx < args.size(); argidx++) {
961  if (args[argidx] == "-all") {
962  loopcount = -1;
963  continue;
964  }
965  if (args[argidx] == "-verify") {
966  fail_on_timeout = true;
967  verify = true;
968  continue;
969  }
970  if (args[argidx] == "-verify-no-timeout") {
971  verify = true;
972  continue;
973  }
974  if (args[argidx] == "-falsify") {
975  fail_on_timeout = true;
976  falsify = true;
977  continue;
978  }
979  if (args[argidx] == "-falsify-no-timeout") {
980  falsify = true;
981  continue;
982  }
983  if (args[argidx] == "-timeout" && argidx+1 < args.size()) {
984  timeout = atoi(args[++argidx].c_str());
985  continue;
986  }
987  if (args[argidx] == "-max" && argidx+1 < args.size()) {
988  loopcount = atoi(args[++argidx].c_str());
989  continue;
990  }
991  if (args[argidx] == "-maxsteps" && argidx+1 < args.size()) {
992  maxsteps = atoi(args[++argidx].c_str());
993  continue;
994  }
995  if (args[argidx] == "-initsteps" && argidx+1 < args.size()) {
996  initsteps = atoi(args[++argidx].c_str());
997  continue;
998  }
999  if (args[argidx] == "-ignore_div_by_zero") {
1000  ignore_div_by_zero = true;
1001  continue;
1002  }
1003  if (args[argidx] == "-enable_undef") {
1004  enable_undef = true;
1005  continue;
1006  }
1007  if (args[argidx] == "-max_undef") {
1008  enable_undef = true;
1009  max_undef = true;
1010  continue;
1011  }
1012  if (args[argidx] == "-set-def-inputs") {
1013  enable_undef = true;
1014  set_def_inputs = true;
1015  continue;
1016  }
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));
1021  continue;
1022  }
1023  if (args[argidx] == "-set-def" && argidx+1 < args.size()) {
1024  sets_def.push_back(args[++argidx]);
1025  enable_undef = true;
1026  continue;
1027  }
1028  if (args[argidx] == "-set-any-undef" && argidx+1 < args.size()) {
1029  sets_any_undef.push_back(args[++argidx]);
1030  enable_undef = true;
1031  continue;
1032  }
1033  if (args[argidx] == "-set-all-undef" && argidx+1 < args.size()) {
1034  sets_all_undef.push_back(args[++argidx]);
1035  enable_undef = true;
1036  continue;
1037  }
1038  if (args[argidx] == "-tempinduct") {
1039  tempinduct = true;
1040  continue;
1041  }
1042  if (args[argidx] == "-tempinduct-def") {
1043  tempinduct = true;
1044  tempinduct_def = true;
1045  continue;
1046  }
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));
1051  continue;
1052  }
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;
1058  continue;
1059  }
1060  if (args[argidx] == "-prove-asserts") {
1061  prove_asserts = true;
1062  continue;
1063  }
1064  if (args[argidx] == "-prove-skip" && argidx+1 < args.size()) {
1065  prove_skip = atoi(args[++argidx].c_str());
1066  continue;
1067  }
1068  if (args[argidx] == "-seq" && argidx+1 < args.size()) {
1069  seq_len = atoi(args[++argidx].c_str());
1070  continue;
1071  }
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));
1077  continue;
1078  }
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]);
1082  continue;
1083  }
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;
1088  continue;
1089  }
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;
1094  continue;
1095  }
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;
1100  continue;
1101  }
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));
1106  continue;
1107  }
1108  if (args[argidx] == "-set-init-undef") {
1109  set_init_undef = true;
1110  enable_undef = true;
1111  continue;
1112  }
1113  if (args[argidx] == "-set-init-def") {
1114  set_init_def = true;
1115  continue;
1116  }
1117  if (args[argidx] == "-set-init-zero") {
1118  set_init_zero = true;
1119  continue;
1120  }
1121  if (args[argidx] == "-show" && argidx+1 < args.size()) {
1122  shows.push_back(args[++argidx]);
1123  continue;
1124  }
1125  if (args[argidx] == "-show-inputs") {
1126  show_inputs = true;
1127  continue;
1128  }
1129  if (args[argidx] == "-show-outputs") {
1130  show_outputs = true;
1131  continue;
1132  }
1133  if (args[argidx] == "-ignore_unknown_cells") {
1134  ignore_unknown_cells = true;
1135  continue;
1136  }
1137  if (args[argidx] == "-dump_vcd" && argidx+1 < args.size()) {
1138  vcd_file_name = args[++argidx];
1139  continue;
1140  }
1141  if (args[argidx] == "-dump_cnf" && argidx+1 < args.size()) {
1142  cnf_file_name = args[++argidx];
1143  continue;
1144  }
1145  break;
1146  }
1147  extra_args(args, argidx, design);
1148 
1150  for (auto &mod_it : design->modules_)
1151  if (design->selected(mod_it.second)) {
1152  if (module)
1153  log_cmd_error("Only one module must be selected for the SAT pass! (selected: %s and %s)\n",
1154  RTLIL::id2cstr(module->name), RTLIL::id2cstr(mod_it.first));
1155  module = mod_it.second;
1156  }
1157  if (module == NULL)
1158  log_cmd_error("Can't perform SAT on an empty selection!\n");
1159 
1160  if (!prove.size() && !prove_x.size() && !prove_asserts && tempinduct)
1161  log_cmd_error("Got -tempinduct but nothing to prove!\n");
1162 
1163  if (prove_skip && tempinduct)
1164  log_cmd_error("Options -prove-skip and -tempinduct don't work with each other.\n");
1165 
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");
1168 
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");
1171 
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());
1176  }
1177 
1178  if (show_inputs) {
1179  for (auto &it : module->wires_)
1180  if (it.second->port_input)
1181  shows.push_back(it.second->name.str());
1182  }
1183 
1184  if (show_outputs) {
1185  for (auto &it : module->wires_)
1186  if (it.second->port_output)
1187  shows.push_back(it.second->name.str());
1188  }
1189 
1190  if (tempinduct)
1191  {
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");
1194 
1195  SatHelper basecase(design, module, enable_undef);
1196  SatHelper inductstep(design, module, enable_undef);
1197 
1198  basecase.sets = sets;
1199  basecase.prove = prove;
1200  basecase.prove_x = prove_x;
1201  basecase.prove_asserts = prove_asserts;
1202  basecase.sets_at = sets_at;
1203  basecase.unsets_at = unsets_at;
1204  basecase.shows = shows;
1205  basecase.timeout = timeout;
1206  basecase.sets_def = sets_def;
1207  basecase.sets_any_undef = sets_any_undef;
1208  basecase.sets_all_undef = sets_all_undef;
1209  basecase.sets_def_at = sets_def_at;
1210  basecase.sets_any_undef_at = sets_any_undef_at;
1211  basecase.sets_all_undef_at = sets_all_undef_at;
1212  basecase.sets_init = sets_init;
1213  basecase.set_init_def = set_init_def;
1214  basecase.set_init_undef = set_init_undef;
1215  basecase.set_init_zero = set_init_zero;
1216  basecase.satgen.ignore_div_by_zero = ignore_div_by_zero;
1217  basecase.ignore_unknown_cells = ignore_unknown_cells;
1218 
1219  for (int timestep = 1; timestep <= seq_len; timestep++)
1220  basecase.setup(timestep);
1221  basecase.setup_init();
1222 
1223  inductstep.sets = sets;
1224  inductstep.prove = prove;
1225  inductstep.prove_x = prove_x;
1226  inductstep.prove_asserts = prove_asserts;
1227  inductstep.shows = shows;
1228  inductstep.timeout = timeout;
1229  inductstep.sets_def = sets_def;
1230  inductstep.sets_any_undef = sets_any_undef;
1231  inductstep.sets_all_undef = sets_all_undef;
1232  inductstep.satgen.ignore_div_by_zero = ignore_div_by_zero;
1233  inductstep.ignore_unknown_cells = ignore_unknown_cells;
1234 
1235  inductstep.setup(1);
1236  inductstep.ez.assume(inductstep.setup_proof(1));
1237 
1238  if (tempinduct_def) {
1239  std::vector<int> undef_state = inductstep.satgen.importUndefSigSpec(inductstep.satgen.initial_state.export_all(), 1);
1240  inductstep.ez.assume(inductstep.ez.NOT(inductstep.ez.expression(ezSAT::OpOr, undef_state)));
1241  }
1242 
1243  for (int inductlen = 1; inductlen <= maxsteps || maxsteps == 0; inductlen++)
1244  {
1245  log("\n** Trying induction with length %d **\n", inductlen);
1246 
1247  // phase 1: proving base case
1248 
1249  basecase.setup(seq_len + inductlen);
1250  int property = basecase.setup_proof(seq_len + inductlen);
1251  basecase.generate_model();
1252 
1253  if (inductlen > 1)
1254  basecase.force_unique_state(seq_len + 1, seq_len + inductlen);
1255 
1256  log("\n[base case] Solving problem with %d variables and %d clauses..\n",
1257  basecase.ez.numCnfVariables(), basecase.ez.numCnfClauses());
1258 
1259  if (basecase.solve(basecase.ez.NOT(property))) {
1260  log("SAT temporal induction proof finished - model found for base case: FAIL!\n");
1262  basecase.print_model();
1263  if(!vcd_file_name.empty())
1264  basecase.dump_model_to_vcd(vcd_file_name);
1265  goto tip_failed;
1266  }
1267 
1268  if (basecase.gotTimeout)
1269  goto timeout;
1270 
1271  log("Base case for induction length %d proven.\n", inductlen);
1272  basecase.ez.assume(property);
1273 
1274  // phase 2: proving induction step
1275 
1276  inductstep.setup(inductlen + 1);
1277  property = inductstep.setup_proof(inductlen + 1);
1278  inductstep.generate_model();
1279 
1280  if (inductlen > 1)
1281  inductstep.force_unique_state(1, inductlen + 1);
1282 
1283  if (inductlen < initsteps)
1284  {
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);
1288  }
1289  else
1290  {
1291  if (!cnf_file_name.empty())
1292  {
1293  FILE *f = fopen(cnf_file_name.c_str(), "w");
1294  if (!f)
1295  log_cmd_error("Can't open output file `%s' for writing: %s\n", cnf_file_name.c_str(), strerror(errno));
1296 
1297  log("Dumping CNF to file `%s'.\n", cnf_file_name.c_str());
1298  cnf_file_name.clear();
1299 
1300  inductstep.ez.printDIMACS(f, false);
1301  fclose(f);
1302  }
1303 
1304  log("\n[induction step] Solving problem with %d variables and %d clauses..\n",
1305  inductstep.ez.numCnfVariables(), inductstep.ez.numCnfClauses());
1306 
1307  if (!inductstep.solve(inductstep.ez.NOT(property))) {
1308  if (inductstep.gotTimeout)
1309  goto timeout;
1310  log("Induction step proven: SUCCESS!\n");
1311  print_qed();
1312  goto tip_success;
1313  }
1314 
1315  log("Induction step failed. Incrementing induction length.\n");
1316  inductstep.ez.assume(property);
1317  inductstep.print_model();
1318  }
1319  }
1320 
1321  log("\nReached maximum number of time steps -> proof failed.\n");
1322  if(!vcd_file_name.empty())
1323  inductstep.dump_model_to_vcd(vcd_file_name);
1325 
1326  tip_failed:
1327  if (verify) {
1328  log("\n");
1329  log_error("Called with -verify and proof did fail!\n");
1330  }
1331 
1332  if (0)
1333  tip_success:
1334  if (falsify) {
1335  log("\n");
1336  log_error("Called with -falsify and proof did succeed!\n");
1337  }
1338  }
1339  else
1340  {
1341  if (maxsteps > 0)
1342  log_cmd_error("The options -maxsteps is only supported for temporal induction proofs!\n");
1343 
1344  SatHelper sathelper(design, module, enable_undef);
1345 
1346  sathelper.sets = sets;
1347  sathelper.prove = prove;
1348  sathelper.prove_x = prove_x;
1349  sathelper.prove_asserts = prove_asserts;
1350  sathelper.sets_at = sets_at;
1351  sathelper.unsets_at = unsets_at;
1352  sathelper.shows = shows;
1353  sathelper.timeout = timeout;
1354  sathelper.sets_def = sets_def;
1355  sathelper.sets_any_undef = sets_any_undef;
1356  sathelper.sets_all_undef = sets_all_undef;
1357  sathelper.sets_def_at = sets_def_at;
1358  sathelper.sets_any_undef_at = sets_any_undef_at;
1359  sathelper.sets_all_undef_at = sets_all_undef_at;
1360  sathelper.sets_init = sets_init;
1361  sathelper.set_init_def = set_init_def;
1362  sathelper.set_init_undef = set_init_undef;
1363  sathelper.set_init_zero = set_init_zero;
1364  sathelper.satgen.ignore_div_by_zero = ignore_div_by_zero;
1365  sathelper.ignore_unknown_cells = ignore_unknown_cells;
1366 
1367  if (seq_len == 0) {
1368  sathelper.setup();
1369  if (sathelper.prove.size() || sathelper.prove_x.size() || sathelper.prove_asserts)
1370  sathelper.ez.assume(sathelper.ez.NOT(sathelper.setup_proof()));
1371  } else {
1372  std::vector<int> prove_bits;
1373  for (int timestep = 1; timestep <= seq_len; timestep++) {
1374  sathelper.setup(timestep);
1375  if (sathelper.prove.size() || sathelper.prove_x.size() || sathelper.prove_asserts)
1376  if (timestep > prove_skip)
1377  prove_bits.push_back(sathelper.setup_proof(timestep));
1378  }
1379  if (sathelper.prove.size() || sathelper.prove_x.size() || sathelper.prove_asserts)
1380  sathelper.ez.assume(sathelper.ez.NOT(sathelper.ez.expression(ezSAT::OpAnd, prove_bits)));
1381  sathelper.setup_init();
1382  }
1383  sathelper.generate_model();
1384 
1385  if (!cnf_file_name.empty())
1386  {
1387  FILE *f = fopen(cnf_file_name.c_str(), "w");
1388  if (!f)
1389  log_cmd_error("Can't open output file `%s' for writing: %s\n", cnf_file_name.c_str(), strerror(errno));
1390 
1391  log("Dumping CNF to file `%s'.\n", cnf_file_name.c_str());
1392  cnf_file_name.clear();
1393 
1394  sathelper.ez.printDIMACS(f, false);
1395  fclose(f);
1396  }
1397 
1398  int rerun_counter = 0;
1399 
1400  rerun_solver:
1401  log("\nSolving problem with %d variables and %d clauses..\n",
1402  sathelper.ez.numCnfVariables(), sathelper.ez.numCnfClauses());
1403 
1404  if (sathelper.solve())
1405  {
1406  if (max_undef) {
1407  log("SAT model found. maximizing number of undefs.\n");
1408  sathelper.maximize_undefs();
1409  }
1410 
1411  if (!prove.size() && !prove_x.size() && !prove_asserts) {
1412  log("SAT solving finished - model found:\n");
1413  } else {
1414  log("SAT proof finished - model found: FAIL!\n");
1416  }
1417 
1418  sathelper.print_model();
1419 
1420  if(!vcd_file_name.empty())
1421  sathelper.dump_model_to_vcd(vcd_file_name);
1422 
1423  if (loopcount != 0) {
1424  loopcount--, rerun_counter++;
1425  sathelper.invalidate_model(max_undef);
1426  goto rerun_solver;
1427  }
1428 
1429  if (!prove.size() && !prove_x.size() && !prove_asserts) {
1430  if (falsify) {
1431  log("\n");
1432  log_error("Called with -falsify and found a model!\n");
1433  }
1434  } else {
1435  if (verify) {
1436  log("\n");
1437  log_error("Called with -verify and proof did fail!\n");
1438  }
1439  }
1440  }
1441  else
1442  {
1443  if (sathelper.gotTimeout)
1444  goto timeout;
1445  if (rerun_counter)
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");
1449  if (verify) {
1450  log("\n");
1451  log_error("Called with -verify and found no model!\n");
1452  }
1453  } else {
1454  log("SAT proof finished - no model found: SUCCESS!\n");
1455  print_qed();
1456  if (falsify) {
1457  log("\n");
1458  log_error("Called with -falsify and proof did succeed!\n");
1459  }
1460  }
1461  }
1462 
1463  if (!prove.size() && !prove_x.size() && !prove_asserts) {
1464  if (falsify && rerun_counter) {
1465  log("\n");
1466  log_error("Called with -falsify and found a model!\n");
1467  }
1468  } else {
1469  if (verify && rerun_counter) {
1470  log("\n");
1471  log_error("Called with -verify and proof did fail!\n");
1472  }
1473  }
1474  }
1475 
1476  if (0) {
1477  timeout:
1478  log("Interrupted SAT solver: TIMEOUT!\n");
1479  print_timeout();
1480  if (fail_on_timeout)
1481  log_error("Called with -verify and proof did time out!\n");
1482  }
1483  }
bool selected(T1 *module) const
Definition: rtlil.h:551
void print_proof_failed()
Definition: sat.cc:770
void log_header(const char *format,...)
Definition: log.cc:188
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
void log_error(const char *format,...)
Definition: log.cc:204
RTLIL::Module * module
Definition: abc.cc:94
Definition: sat.cc:39
void print_timeout()
Definition: sat.cc:782
RTLIL::IdString name
Definition: rtlil.h:599
static const char * id2cstr(const RTLIL::IdString &str)
Definition: rtlil.h:267
void log_cmd_error(const char *format,...)
Definition: log.cc:211
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
void print_qed()
Definition: sat.cc:793
#define NULL
void log(const char *format,...)
Definition: log.cc:180
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128

+ Here is the call graph for this function:

void Pass::extra_args ( std::vector< std::string >  args,
size_t  argidx,
RTLIL::Design design,
bool  select = true 
)
inherited

Definition at line 128 of file register.cc.

129 {
130  for (; argidx < args.size(); argidx++)
131  {
132  std::string arg = args[argidx];
133 
134  if (arg.substr(0, 1) == "-")
135  cmd_error(args, argidx, "Unknown option or option in arguments.");
136 
137  if (!select)
138  cmd_error(args, argidx, "Extra argument.");
139 
140  handle_extra_select_args(this, args, argidx, args.size(), design);
141  break;
142  }
143  // cmd_log_args(args);
144 }
void cmd_error(const std::vector< std::string > &args, size_t argidx, std::string msg)
Definition: register.cc:110
void handle_extra_select_args(Pass *pass, std::vector< std::string > args, size_t argidx, size_t args_size, RTLIL::Design *design)
Definition: select.cc:803

+ Here is the call graph for this function:

virtual void SatPass::help ( )
inlinevirtual

Reimplemented from Pass.

Definition at line 810 of file sat.cc.

811  {
812  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
813  log("\n");
814  log(" sat [options] [selection]\n");
815  log("\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");
818  log("\n");
819  log(" -all\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");
822  log("\n");
823  log(" -max <N>\n");
824  log(" like -all, but limit number of solutions to <N>\n");
825  log("\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");
829  log("\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");
833  log("\n");
834  log(" -set <signal> <value>\n");
835  log(" set the specified signal to the specified value.\n");
836  log("\n");
837  log(" -set-def <signal>\n");
838  log(" add a constraint that all bits of the given signal must be defined\n");
839  log("\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");
842  log("\n");
843  log(" -set-all-undef <signal>\n");
844  log(" add a constraint that all bits of the given signal are undefined\n");
845  log("\n");
846  log(" -set-def-inputs\n");
847  log(" add -set-def constraints for all module inputs\n");
848  log("\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");
852  log("\n");
853  log(" -show-inputs, -show-outputs\n");
854  log(" add all module input (output) ports to the list of shown signals\n");
855  log("\n");
856  log(" -ignore_div_by_zero\n");
857  log(" ignore all solutions that involve a division by zero\n");
858  log("\n");
859  log(" -ignore_unknown_cells\n");
860  log(" ignore all cells that can not be matched to a SAT model\n");
861  log("\n");
862  log("The following options can be used to set up a sequential problem:\n");
863  log("\n");
864  log(" -seq <N>\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");
867  log("\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");
872  log("\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");
877  log("\n");
878  log(" -set-init <signal> <value>\n");
879  log(" set the initial value for the register driving the signal to the value\n");
880  log("\n");
881  log(" -set-init-undef\n");
882  log(" set all initial states (not set using -set-init) to undef\n");
883  log("\n");
884  log(" -set-init-def\n");
885  log(" do not force a value for the initial state but do not allow undef\n");
886  log("\n");
887  log(" -set-init-zero\n");
888  log(" set all initial states (not set using -set-init) to zero\n");
889  log("\n");
890  log(" -dump_vcd <vcd-file-name>\n");
891  log(" dump SAT model (counter example in proof) to VCD file\n");
892  log("\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");
896  log("\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");
899  log("\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");
904  log("\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");
908  log("\n");
909  log(" -prove <signal> <value>\n");
910  log(" Attempt to proof that <signal> is always <value>.\n");
911  log("\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");
915  log("\n");
916  log(" -prove-asserts\n");
917  log(" Prove that all asserts in the design hold.\n");
918  log("\n");
919  log(" -prove-skip <N>\n");
920  log(" Do not enforce the prove-condition for the first <N> time steps.\n");
921  log("\n");
922  log(" -maxsteps <N>\n");
923  log(" Set a maximum length for the induction.\n");
924  log("\n");
925  log(" -initsteps <N>\n");
926  log(" Set initial length for the induction.\n");
927  log("\n");
928  log(" -timeout <N>\n");
929  log(" Maximum number of seconds a single SAT instance may take.\n");
930  log("\n");
931  log(" -verify\n");
932  log(" Return an error and stop the synthesis script if the proof fails.\n");
933  log("\n");
934  log(" -verify-no-timeout\n");
935  log(" Like -verify but do not return an error for timeouts.\n");
936  log("\n");
937  log(" -falsify\n");
938  log(" Return an error and stop the synthesis script if the proof succeeds.\n");
939  log("\n");
940  log(" -falsify-no-timeout\n");
941  log(" Like -falsify but do not return an error for timeouts.\n");
942  log("\n");
943  }
void log(const char *format,...)
Definition: log.cc:180

+ Here is the call graph for this function:

void Pass::init_register ( )
staticinherited

Definition at line 54 of file register.cc.

55 {
56  while (first_queued_pass) {
59  }
60 }
Pass * first_queued_pass
Definition: register.cc:31
Pass * next_queued_pass
Definition: register.h:60
virtual void run_register()
Definition: register.cc:48

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Pass::post_execute ( Pass::pre_post_exec_state_t  state)
inherited

Definition at line 84 of file register.cc.

85 {
86  int64_t time_ns = PerformanceTimer::query() - state.begin_ns;
87  runtime_ns += time_ns;
88  current_pass = state.parent_pass;
89  if (current_pass)
90  current_pass->runtime_ns -= time_ns;
91 }
static int64_t query()
Definition: log.h:151
int64_t runtime_ns
Definition: register.h:37
Pass * current_pass
Definition: register.cc:32
Pass * parent_pass
Definition: register.h:40
int64_t begin_ns
Definition: register.h:41

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Pass::pre_post_exec_state_t Pass::pre_execute ( )
inherited

Definition at line 74 of file register.cc.

75 {
76  pre_post_exec_state_t state;
77  call_counter++;
78  state.begin_ns = PerformanceTimer::query();
79  state.parent_pass = current_pass;
80  current_pass = this;
81  return state;
82 }
static int64_t query()
Definition: log.h:151
Pass * current_pass
Definition: register.cc:32
int call_counter
Definition: register.h:36

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void Pass::run_register ( )
virtualinherited

Reimplemented in Backend, and Frontend.

Definition at line 48 of file register.cc.

49 {
50  log_assert(pass_register.count(pass_name) == 0);
51  pass_register[pass_name] = this;
52 }
std::string pass_name
Definition: register.h:29
#define log_assert(_assert_expr_)
Definition: log.h:85
std::map< std::string, Pass * > pass_register
Definition: register.cc:35

+ Here is the caller graph for this function:

Field Documentation

int Pass::call_counter
inherited

Definition at line 36 of file register.h.

Pass* Pass::next_queued_pass
inherited

Definition at line 60 of file register.h.

std::string Pass::pass_name
inherited

Definition at line 29 of file register.h.

int64_t Pass::runtime_ns
inherited

Definition at line 37 of file register.h.

std::string Pass::short_help
inherited

Definition at line 29 of file register.h.


The documentation for this struct was generated from the following file: