diff options
Diffstat (limited to 'passes/sat/freduce.cc')
-rw-r--r-- | passes/sat/freduce.cc | 85 |
1 files changed, 48 insertions, 37 deletions
diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index fbca35861..77263f6a2 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -2,11 +2,11 @@ * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> - * + * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -73,7 +73,7 @@ struct FindReducedInputs SigMap &sigmap; drivers_t &drivers; - ezDefaultSAT ez; + ezSatPtr ez; std::set<RTLIL::Cell*> ez_cells; SatGen satgen; @@ -81,7 +81,7 @@ struct FindReducedInputs std::vector<int> sat_pi_uniq_bitvec; FindReducedInputs(SigMap &sigmap, drivers_t &drivers) : - sigmap(sigmap), drivers(drivers), satgen(&ez, &sigmap) + sigmap(sigmap), drivers(drivers), satgen(ez.get(), &sigmap) { satgen.model_undef = true; } @@ -104,30 +104,30 @@ struct FindReducedInputs satgen.setContext(&sigmap, "A"); int sat_a = satgen.importSigSpec(bit).front(); - ez.assume(ez.NOT(satgen.importUndefSigSpec(bit).front())); + ez->assume(ez->NOT(satgen.importUndefSigSpec(bit).front())); satgen.setContext(&sigmap, "B"); int sat_b = satgen.importSigSpec(bit).front(); - ez.assume(ez.NOT(satgen.importUndefSigSpec(bit).front())); + ez->assume(ez->NOT(satgen.importUndefSigSpec(bit).front())); int idx = sat_pi.size(); size_t idx_bits = get_bits(idx); if (sat_pi_uniq_bitvec.size() != idx_bits) { - sat_pi_uniq_bitvec.push_back(ez.frozen_literal(stringf("uniq_%d", int(idx_bits)-1))); + sat_pi_uniq_bitvec.push_back(ez->frozen_literal(stringf("uniq_%d", int(idx_bits)-1))); for (auto &it : sat_pi) - ez.assume(ez.OR(ez.NOT(it.second), ez.NOT(sat_pi_uniq_bitvec.back()))); + ez->assume(ez->OR(ez->NOT(it.second), ez->NOT(sat_pi_uniq_bitvec.back()))); } log_assert(sat_pi_uniq_bitvec.size() == idx_bits); - sat_pi[bit] = ez.frozen_literal(stringf("p, falsei_%s", log_signal(bit))); - ez.assume(ez.IFF(ez.XOR(sat_a, sat_b), sat_pi[bit])); + sat_pi[bit] = ez->frozen_literal(stringf("p, falsei_%s", log_signal(bit))); + ez->assume(ez->IFF(ez->XOR(sat_a, sat_b), sat_pi[bit])); for (size_t i = 0; i < idx_bits; i++) if ((idx & (1 << i)) == 0) - ez.assume(ez.OR(ez.NOT(sat_pi[bit]), ez.NOT(sat_pi_uniq_bitvec[i]))); + ez->assume(ez->OR(ez->NOT(sat_pi[bit]), ez->NOT(sat_pi_uniq_bitvec[i]))); else - ez.assume(ez.OR(ez.NOT(sat_pi[bit]), sat_pi_uniq_bitvec[i])); + ez->assume(ez->OR(ez->NOT(sat_pi[bit]), sat_pi_uniq_bitvec[i])); } void register_cone_worker(std::set<RTLIL::SigBit> &pi, std::set<RTLIL::SigBit> &sigdone, RTLIL::SigBit out) @@ -201,7 +201,7 @@ struct FindReducedInputs model_expr.push_back(sat_pi.at(pi[i])); } - if (!ez.solve(model_expr, model, ez.expression(ezSAT::OpOr, model_expr), ez.XOR(output_a, output_b), ez.NOT(output_undef_a), ez.NOT(output_undef_b))) + if (!ez->solve(model_expr, model, ez->expression(ezSAT::OpOr, model_expr), ez->XOR(output_a, output_b), ez->NOT(output_undef_a), ez->NOT(output_undef_b))) break; int found_count = 0; @@ -229,8 +229,9 @@ struct PerformReduction SigMap &sigmap; drivers_t &drivers; std::set<std::pair<RTLIL::SigBit, RTLIL::SigBit>> &inv_pairs; + pool<SigBit> recursion_guard; - ezDefaultSAT ez; + ezSatPtr ez; SatGen satgen; std::vector<int> sat_pi, sat_out, sat_def; @@ -246,6 +247,15 @@ struct PerformReduction if (sigdepth.count(out) != 0) return sigdepth.at(out); + if (recursion_guard.count(out)) { + string loop_signals; + for (auto loop_bit : recursion_guard) + loop_signals += string(" ") + log_signal(loop_bit); + log_error("Found logic loop:%s\n", loop_signals.c_str()); + } + + recursion_guard.insert(out); + if (drivers.count(out) != 0) { std::pair<RTLIL::Cell*, std::set<RTLIL::SigBit>> &drv = drivers.at(out); if (celldone.count(drv.first) == 0) { @@ -255,20 +265,21 @@ struct PerformReduction } int max_child_depth = 0; for (auto &bit : drv.second) - max_child_depth = std::max(register_cone_worker(celldone, sigdepth, bit), max_child_depth); + max_child_depth = max(register_cone_worker(celldone, sigdepth, bit), max_child_depth); sigdepth[out] = max_child_depth + 1; } else { pi_bits.push_back(out); sat_pi.push_back(satgen.importSigSpec(out).front()); - ez.assume(ez.NOT(satgen.importUndefSigSpec(out).front())); + ez->assume(ez->NOT(satgen.importUndefSigSpec(out).front())); sigdepth[out] = 0; } + recursion_guard.erase(out); return sigdepth.at(out); } PerformReduction(SigMap &sigmap, drivers_t &drivers, std::set<std::pair<RTLIL::SigBit, RTLIL::SigBit>> &inv_pairs, std::vector<RTLIL::SigBit> &bits, int cone_size) : - sigmap(sigmap), drivers(drivers), inv_pairs(inv_pairs), satgen(&ez, &sigmap), out_bits(bits), cone_size(cone_size) + sigmap(sigmap), drivers(drivers), inv_pairs(inv_pairs), satgen(ez.get(), &sigmap), out_bits(bits), cone_size(cone_size) { satgen.model_undef = true; @@ -278,15 +289,15 @@ struct PerformReduction for (auto &bit : bits) { out_depth.push_back(register_cone_worker(celldone, sigdepth, bit)); sat_out.push_back(satgen.importSigSpec(bit).front()); - sat_def.push_back(ez.NOT(satgen.importUndefSigSpec(bit).front())); + sat_def.push_back(ez->NOT(satgen.importUndefSigSpec(bit).front())); } if (inv_mode && cone_size > 0) { - if (!ez.solve(sat_out, out_inverted, ez.expression(ezSAT::OpAnd, sat_def))) + if (!ez->solve(sat_out, out_inverted, ez->expression(ezSAT::OpAnd, sat_def))) log_error("Solving for initial model failed!\n"); for (size_t i = 0; i < sat_out.size(); i++) if (out_inverted.at(i)) - sat_out[i] = ez.NOT(sat_out[i]); + sat_out[i] = ez->NOT(sat_out[i]); } else out_inverted = std::vector<bool>(sat_out.size(), false); } @@ -296,8 +307,8 @@ struct PerformReduction if (verbose_level == 1) log(" Finding const value for %s.\n", log_signal(out_bits[idx])); - bool can_be_set = ez.solve(ez.AND(sat_out[idx], sat_def[idx])); - bool can_be_clr = ez.solve(ez.AND(ez.NOT(sat_out[idx]), sat_def[idx])); + bool can_be_set = ez->solve(ez->AND(sat_out[idx], sat_def[idx])); + bool can_be_clr = ez->solve(ez->AND(ez->NOT(sat_out[idx]), sat_def[idx])); log_assert(!can_be_set || !can_be_clr); RTLIL::SigBit value(RTLIL::State::Sx); @@ -355,8 +366,8 @@ struct PerformReduction std::vector<int> sat_set_list, sat_clr_list; for (int idx : bucket) { - sat_set_list.push_back(ez.AND(sat_out[idx], sat_def[idx])); - sat_clr_list.push_back(ez.AND(ez.NOT(sat_out[idx]), sat_def[idx])); + sat_set_list.push_back(ez->AND(sat_out[idx], sat_def[idx])); + sat_clr_list.push_back(ez->AND(ez->NOT(sat_out[idx]), sat_def[idx])); } std::vector<int> modelVars = sat_out; @@ -366,7 +377,7 @@ struct PerformReduction if (verbose_level >= 2) modelVars.insert(modelVars.end(), sat_pi.begin(), sat_pi.end()); - if (ez.solve(modelVars, model, ez.expression(ezSAT::OpOr, sat_set_list), ez.expression(ezSAT::OpOr, sat_clr_list))) + if (ez->solve(modelVars, model, ez->expression(ezSAT::OpOr, sat_set_list), ez->expression(ezSAT::OpOr, sat_clr_list))) { int iter_count = 1; @@ -379,13 +390,13 @@ struct PerformReduction for (int idx : bucket) if (!model[sat_out.size() + idx]) { - sat_set_list.push_back(ez.AND(sat_out[idx], sat_def[idx])); - sat_clr_list.push_back(ez.AND(ez.NOT(sat_out[idx]), sat_def[idx])); + sat_set_list.push_back(ez->AND(sat_out[idx], sat_def[idx])); + sat_clr_list.push_back(ez->AND(ez->NOT(sat_out[idx]), sat_def[idx])); } else { sat_def_list.push_back(sat_def[idx]); } - if (!ez.solve(modelVars, model, ez.expression(ezSAT::OpOr, sat_set_list), ez.expression(ezSAT::OpOr, sat_clr_list), ez.expression(ezSAT::OpAnd, sat_def_list))) + if (!ez->solve(modelVars, model, ez->expression(ezSAT::OpOr, sat_set_list), ez->expression(ezSAT::OpOr, sat_clr_list), ez->expression(ezSAT::OpAnd, sat_def_list))) break; iter_count++; } @@ -431,7 +442,7 @@ struct PerformReduction for (int idx2 : bucket) if (idx != idx2) sat_def_list.push_back(sat_def[idx2]); - if (ez.solve(ez.NOT(sat_def[idx]), ez.expression(ezSAT::OpOr, sat_def_list))) + if (ez->solve(ez->NOT(sat_def[idx]), ez->expression(ezSAT::OpOr, sat_def_list))) undef_slaves.push_back(idx); } @@ -446,7 +457,7 @@ struct PerformReduction out_depth[idx] = std::numeric_limits<int>::max(); if (verbose_level >= 1) { - log("%s Found %d equivialent signals:", indt, int(bucket.size())); + log("%s Found %d equivalent signals:", indt, int(bucket.size())); for (int idx : bucket) log("%s%s%s", idx == bucket.front() ? " " : ", ", out_inverted[idx] ? "~" : "", log_signal(out_bits[idx])); log("\n"); @@ -495,7 +506,7 @@ struct PerformReduction std::vector<RTLIL::SigBit> r_sigbits; for (int idx : r) r_sigbits.push_back(out_bits[idx]); - log(" Found group of %d equivialent signals: %s\n", int(r.size()), log_signal(r_sigbits)); + log(" Found group of %d equivalent signals: %s\n", int(r.size()), log_signal(r_sigbits)); } std::vector<int> undef_slaves; @@ -505,7 +516,7 @@ struct PerformReduction for (int idx2 : r) if (idx != idx2) sat_def_list.push_back(sat_def[idx2]); - if (ez.solve(ez.NOT(sat_def[idx]), ez.expression(ezSAT::OpOr, sat_def_list))) + if (ez->solve(ez->NOT(sat_def[idx]), ez->expression(ezSAT::OpOr, sat_def_list))) undef_slaves.push_back(idx); } @@ -681,7 +692,7 @@ struct FreduceWorker if (!dump_prefix.empty()) dump(); - log(" Rewiring %d equivialent groups:\n", int(equiv.size())); + log(" Rewiring %d equivalent groups:\n", int(equiv.size())); int rewired_sigbits = 0; for (auto &grp : equiv) { @@ -755,7 +766,7 @@ struct FreducePass : public Pass { log(" freduce [options] [selection]\n"); log("\n"); log("This pass performs functional reduction in the circuit. I.e. if two nodes are\n"); - log("equivialent, they are merged to one node and one of the redundant drivers is\n"); + log("equivalent, they are merged to one node and one of the redundant drivers is\n"); log("disconnected. A subsequent call to 'clean' will remove the redundant drivers.\n"); log("\n"); log(" -v, -vv\n"); @@ -773,7 +784,7 @@ struct FreducePass : public Pass { log(" operation. this is mostly used for debugging the freduce command.\n"); log("\n"); log("This pass is undef-aware, i.e. it considers don't-care values for detecting\n"); - log("equivialent nodes.\n"); + log("equivalent nodes.\n"); log("\n"); log("All selected wires are considered for rewiring. The selected cells cover the\n"); log("circuit that is analyzed.\n"); @@ -787,7 +798,7 @@ struct FreducePass : public Pass { inv_mode = false; dump_prefix = std::string(); - log_header("Executing FREDUCE pass (perform functional reduction).\n"); + log_header(design, "Executing FREDUCE pass (perform functional reduction).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { @@ -825,5 +836,5 @@ struct FreducePass : public Pass { log("Rewired a total of %d signal bits.\n", bitcount); } } FreducePass; - + PRIVATE_NAMESPACE_END |