diff options
Diffstat (limited to 'passes/sat')
-rw-r--r-- | passes/sat/formalff.cc | 2 | ||||
-rw-r--r-- | passes/sat/miter.cc | 24 | ||||
-rw-r--r-- | passes/sat/qbfsat.cc | 16 | ||||
-rw-r--r-- | passes/sat/qbfsat.h | 50 | ||||
-rw-r--r-- | passes/sat/sim.cc | 36 |
5 files changed, 79 insertions, 49 deletions
diff --git a/passes/sat/formalff.cc b/passes/sat/formalff.cc index 962e350a1..e36379096 100644 --- a/passes/sat/formalff.cc +++ b/passes/sat/formalff.cc @@ -532,12 +532,14 @@ struct FormalFfPass : public Pass { if ((int)bits.size() == ff.val_init.size()) { // This check is only to make the private names more helpful for debugging ff.is_anyinit = true; + ff.is_fine = false; emit = true; break; } auto slice = ff.slice(bits); slice.is_anyinit = is_anyinit; + slice.is_fine = false; slice.emit(); } } diff --git a/passes/sat/miter.cc b/passes/sat/miter.cc index bf33c9ce3..8f27c4c6f 100644 --- a/passes/sat/miter.cc +++ b/passes/sat/miter.cc @@ -30,6 +30,7 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: bool flag_make_outputs = false; bool flag_make_outcmp = false; bool flag_make_assert = false; + bool flag_make_cover = false; bool flag_flatten = false; bool flag_cross = false; @@ -54,6 +55,10 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: flag_make_assert = true; continue; } + if (args[argidx] == "-make_cover") { + flag_make_cover = true; + continue; + } if (args[argidx] == "-flatten") { flag_flatten = true; continue; @@ -139,8 +144,16 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: { if (gold_cross_ports.count(gold_wire)) { - RTLIL::Wire *w = miter_module->addWire("\\cross_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); + SigSpec w = miter_module->addWire("\\cross_" + RTLIL::unescape_id(gold_wire->name), gold_wire->width); gold_cell->setPort(gold_wire->name, w); + if (flag_ignore_gold_x) { + RTLIL::SigSpec w_x = miter_module->addWire(NEW_ID, GetSize(w)); + for (int i = 0; i < GetSize(w); i++) + miter_module->addEqx(NEW_ID, w[i], State::Sx, w_x[i]); + RTLIL::SigSpec w_any = miter_module->And(NEW_ID, miter_module->Anyseq(NEW_ID, GetSize(w)), w_x); + RTLIL::SigSpec w_masked = miter_module->And(NEW_ID, w, miter_module->Not(NEW_ID, w_x)); + w = miter_module->And(NEW_ID, w_any, w_masked); + } gate_cell->setPort(gold_wire->name, w); continue; } @@ -237,6 +250,12 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL: miter_module->connect(RTLIL::SigSig(w_cmp, this_condition)); } + if (flag_make_cover) + { + auto cover_condition = miter_module->Not(NEW_ID, this_condition); + miter_module->addCover("\\cover_" + RTLIL::unescape_id(gold_wire->name), cover_condition, State::S1); + } + all_conditions.append(this_condition); } } @@ -402,6 +421,9 @@ struct MiterPass : public Pass { log(" -make_assert\n"); log(" also create an 'assert' cell that checks if trigger is always low.\n"); log("\n"); + log(" -make_cover\n"); + log(" also create a 'cover' cell for each gold/gate output pair.\n"); + log("\n"); log(" -flatten\n"); log(" call 'flatten -wb; opt_expr -keepdc -undriven;;' on the miter circuit.\n"); log("\n"); diff --git a/passes/sat/qbfsat.cc b/passes/sat/qbfsat.cc index 4580f194e..db6836ea1 100644 --- a/passes/sat/qbfsat.cc +++ b/passes/sat/qbfsat.cc @@ -66,9 +66,9 @@ pool<std::string> validate_design_and_get_inputs(RTLIL::Module *module, bool ass } void specialize_from_file(RTLIL::Module *module, const std::string &file) { - YS_REGEX_TYPE hole_bit_assn_regex = YS_REGEX_COMPILE_WITH_SUBS("^(.+) ([0-9]+) ([^ ]+) \\[([0-9]+)] = ([01])$"); - YS_REGEX_TYPE hole_assn_regex = YS_REGEX_COMPILE_WITH_SUBS("^(.+) ([0-9]+) ([^ ]+) = ([01])$"); //if no index specified - YS_REGEX_MATCH_TYPE bit_m, m; + std::regex hole_bit_assn_regex = YS_REGEX_COMPILE_WITH_SUBS("^(.+) ([0-9]+) ([^ ]+) \\[([0-9]+)] = ([01])$"); + std::regex hole_assn_regex = YS_REGEX_COMPILE_WITH_SUBS("^(.+) ([0-9]+) ([^ ]+) = ([01])$"); //if no index specified + std::smatch bit_m, m; dict<pool<std::string>, RTLIL::Cell*> anyconst_loc_to_cell; dict<RTLIL::SigBit, RTLIL::State> hole_assignments; @@ -83,9 +83,9 @@ void specialize_from_file(RTLIL::Module *module, const std::string &file) { std::string buf; while (std::getline(fin, buf)) { bool bit_assn = true; - if (!YS_REGEX_NS::regex_search(buf, bit_m, hole_bit_assn_regex)) { + if (!std::regex_search(buf, bit_m, hole_bit_assn_regex)) { bit_assn = false; - if (!YS_REGEX_NS::regex_search(buf, m, hole_assn_regex)) + if (!std::regex_search(buf, m, hole_assn_regex)) log_cmd_error("solution file is not formatted correctly: \"%s\"\n", buf.c_str()); } @@ -416,6 +416,8 @@ QbfSolveOptions parse_args(const std::vector<std::string> &args) { opt.solver = opt.Solver::Yices; else if (args[opt.argidx+1] == "cvc4") opt.solver = opt.Solver::CVC4; + else if (args[opt.argidx+1] == "cvc5") + opt.solver = opt.Solver::CVC5; else log_cmd_error("Unknown solver \"%s\".\n", args[opt.argidx+1].c_str()); opt.argidx++; @@ -542,8 +544,8 @@ struct QbfSatPass : public Pass { log(" hope that the solver supports optimizing quantified bitvector problems.\n"); log("\n"); log(" -solver <solver>\n"); - log(" Use a particular solver. Choose one of: \"z3\", \"yices\", and \"cvc4\".\n"); - log(" (default: yices)\n"); + log(" Use a particular solver. Choose one of: \"z3\", \"yices\", \"cvc4\"\n"); + log(" and \"cvc5\". (default: yices)\n"); log("\n"); log(" -solver-option <name> <value>\n"); log(" Set the specified solver option in the SMT-LIBv2 problem file.\n"); diff --git a/passes/sat/qbfsat.h b/passes/sat/qbfsat.h index c96c6f818..253cecce4 100644 --- a/passes/sat/qbfsat.h +++ b/passes/sat/qbfsat.h @@ -29,7 +29,7 @@ struct QbfSolveOptions { bool specialize = false, specialize_from_file = false, write_solution = false, nocleanup = false; bool dump_final_smt2 = false, assume_outputs = false, assume_neg = false, nooptimize = false; bool nobisection = false, sat = false, unsat = false, show_smtbmc = false; - enum Solver{Z3, Yices, CVC4} solver = Yices; + enum Solver{Z3, Yices, CVC4, CVC5} solver = Yices; enum OptimizationLevel{O0, O1, O2} oflag = O0; dict<std::string, std::string> solver_options; int timeout = 0; @@ -45,6 +45,8 @@ struct QbfSolveOptions { return "yices"; else if (solver == Solver::CVC4) return "cvc4"; + else if (solver == Solver::CVC5) + return "cvc5"; log_cmd_error("unknown solver specified.\n"); return ""; @@ -152,67 +154,67 @@ struct QbfSolutionType { } void recover_solution() { - YS_REGEX_TYPE sat_regex = YS_REGEX_COMPILE("Status: PASSED"); - YS_REGEX_TYPE unsat_regex = YS_REGEX_COMPILE("Solver Error.*model is not available"); - YS_REGEX_TYPE unsat_regex2 = YS_REGEX_COMPILE("Status: FAILED"); - YS_REGEX_TYPE timeout_regex = YS_REGEX_COMPILE("No solution found! \\(timeout\\)"); - YS_REGEX_TYPE timeout_regex2 = YS_REGEX_COMPILE("No solution found! \\(interrupted\\)"); - YS_REGEX_TYPE unknown_regex = YS_REGEX_COMPILE("No solution found! \\(unknown\\)"); - YS_REGEX_TYPE unknown_regex2 = YS_REGEX_COMPILE("Unexpected EOF response from solver"); - YS_REGEX_TYPE memout_regex = YS_REGEX_COMPILE("Solver Error:.*error \"out of memory\""); - YS_REGEX_TYPE hole_value_regex = YS_REGEX_COMPILE_WITH_SUBS("Value for anyconst in [a-zA-Z0-9_]* \\(([^:]*:[^\\)]*)\\): (.*)"); + std::regex sat_regex = YS_REGEX_COMPILE("Status: PASSED"); + std::regex unsat_regex = YS_REGEX_COMPILE("Solver Error.*model is not available"); + std::regex unsat_regex2 = YS_REGEX_COMPILE("Status: FAILED"); + std::regex timeout_regex = YS_REGEX_COMPILE("No solution found! \\(timeout\\)"); + std::regex timeout_regex2 = YS_REGEX_COMPILE("No solution found! \\(interrupted\\)"); + std::regex unknown_regex = YS_REGEX_COMPILE("No solution found! \\(unknown\\)"); + std::regex unknown_regex2 = YS_REGEX_COMPILE("Unexpected EOF response from solver"); + std::regex memout_regex = YS_REGEX_COMPILE("Solver Error:.*error \"out of memory\""); + std::regex hole_value_regex = YS_REGEX_COMPILE_WITH_SUBS("Value for anyconst in [a-zA-Z0-9_]* \\(([^:]*:[^\\)]*)\\): (.*)"); #ifndef NDEBUG - YS_REGEX_TYPE hole_loc_regex = YS_REGEX_COMPILE("[^:]*:[0-9]+.[0-9]+-[0-9]+.[0-9]+"); - YS_REGEX_TYPE hole_val_regex = YS_REGEX_COMPILE("[0-9]+"); + std::regex hole_loc_regex = YS_REGEX_COMPILE("[^:]*:[0-9]+.[0-9]+-[0-9]+.[0-9]+"); + std::regex hole_val_regex = YS_REGEX_COMPILE("[0-9]+"); #endif - YS_REGEX_MATCH_TYPE m; + std::smatch m; bool sat_regex_found = false; bool unsat_regex_found = false; dict<std::string, bool> hole_value_recovered; for (const std::string &x : stdout_lines) { - if(YS_REGEX_NS::regex_search(x, m, hole_value_regex)) { + if(std::regex_search(x, m, hole_value_regex)) { std::string loc = m[1].str(); std::string val = m[2].str(); #ifndef NDEBUG - log_assert(YS_REGEX_NS::regex_search(loc, hole_loc_regex)); - log_assert(YS_REGEX_NS::regex_search(val, hole_val_regex)); + log_assert(std::regex_search(loc, hole_loc_regex)); + log_assert(std::regex_search(val, hole_val_regex)); #endif auto locs = split_tokens(loc, "|"); pool<std::string> loc_pool(locs.begin(), locs.end()); hole_to_value[loc_pool] = val; } - else if (YS_REGEX_NS::regex_search(x, sat_regex)) { + else if (std::regex_search(x, sat_regex)) { sat_regex_found = true; sat = true; unknown = false; } - else if (YS_REGEX_NS::regex_search(x, unsat_regex)) { + else if (std::regex_search(x, unsat_regex)) { unsat_regex_found = true; sat = false; unknown = false; } - else if (YS_REGEX_NS::regex_search(x, memout_regex)) { + else if (std::regex_search(x, memout_regex)) { unknown = true; log_warning("solver ran out of memory\n"); } - else if (YS_REGEX_NS::regex_search(x, timeout_regex)) { + else if (std::regex_search(x, timeout_regex)) { unknown = true; log_warning("solver timed out\n"); } - else if (YS_REGEX_NS::regex_search(x, timeout_regex2)) { + else if (std::regex_search(x, timeout_regex2)) { unknown = true; log_warning("solver timed out\n"); } - else if (YS_REGEX_NS::regex_search(x, unknown_regex)) { + else if (std::regex_search(x, unknown_regex)) { unknown = true; log_warning("solver returned \"unknown\"\n"); } - else if (YS_REGEX_NS::regex_search(x, unsat_regex2)) { + else if (std::regex_search(x, unsat_regex2)) { unsat_regex_found = true; sat = false; unknown = false; } - else if (YS_REGEX_NS::regex_search(x, unknown_regex2)) { + else if (std::regex_search(x, unknown_regex2)) { unknown = true; } } diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 1cd1ebc71..0084a1f28 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -509,7 +509,7 @@ struct SimInstance } } - bool update_ph2() + bool update_ph2(bool gclk) { bool did_something = false; @@ -567,7 +567,8 @@ struct SimInstance } if (ff_data.has_gclk) { // $ff - current_q = ff.past_d; + if (gclk) + current_q = ff.past_d; } if (set_state(ff_data.sig_q, current_q)) did_something = true; @@ -616,7 +617,7 @@ struct SimInstance } for (auto it : children) - if (it.second->update_ph2()) { + if (it.second->update_ph2(gclk)) { dirty_children.insert(it.second); did_something = true; } @@ -684,10 +685,11 @@ struct SimInstance void writeback(pool<Module*> &wbmods) { - if (wbmods.count(module)) - log_error("Instance %s of module %s is not unique: Writeback not possible. (Fix by running 'uniquify'.)\n", hiername().c_str(), log_id(module)); - - wbmods.insert(module); + if (!ff_database.empty() || !mem_database.empty()) { + if (wbmods.count(module)) + log_error("Instance %s of module %s is not unique: Writeback not possible. (Fix by running 'uniquify'.)\n", hiername().c_str(), log_id(module)); + wbmods.insert(module); + } for (auto wire : module->wires()) wire->attributes.erase(ID::init); @@ -985,7 +987,7 @@ struct SimWorker : SimShared writer->write(use_signal); } - void update() + void update(bool gclk) { while (1) { @@ -997,7 +999,7 @@ struct SimWorker : SimShared if (debug) log("\n-- ph2 --\n"); - if (!top->update_ph2()) + if (!top->update_ph2(gclk)) break; } @@ -1047,7 +1049,7 @@ struct SimWorker : SimShared set_inports(clock, State::Sx); set_inports(clockn, State::Sx); - update(); + update(false); register_output_step(0); @@ -1060,7 +1062,7 @@ struct SimWorker : SimShared set_inports(clock, State::S0); set_inports(clockn, State::S1); - update(); + update(true); register_output_step(10*cycle + 5); if (debug) @@ -1076,7 +1078,7 @@ struct SimWorker : SimShared set_inports(resetn, State::S1); } - update(); + update(true); register_output_step(10*cycle + 10); } @@ -1193,7 +1195,7 @@ struct SimWorker : SimShared initial = false; } if (did_something) - update(); + update(true); register_output_step(time); bool status = top->checkSignals(); @@ -1342,12 +1344,12 @@ struct SimWorker : SimShared set_inports(clock, State::S0); set_inports(clockn, State::S1); } - update(); + update(true); register_output_step(10*cycle); if (!multiclock && cycle) { set_inports(clock, State::S0); set_inports(clockn, State::S1); - update(); + update(true); register_output_step(10*cycle + 5); } cycle++; @@ -1419,12 +1421,12 @@ struct SimWorker : SimShared log("Simulating cycle %d.\n", cycle); set_inports(clock, State::S1); set_inports(clockn, State::S0); - update(); + update(true); register_output_step(10*cycle+0); if (!multiclock) { set_inports(clock, State::S0); set_inports(clockn, State::S1); - update(); + update(true); register_output_step(10*cycle+5); } cycle++; |