{
RTLIL::Design *design;
RTLIL::Module *module;
+ bool try_mode;
ezDefaultSAT ez;
SigMap sigmap;
return xorshift32_state;
}
- FreduceHelper(RTLIL::Design *design, RTLIL::Module *module) :
- design(design), module(module), sigmap(module), satgen(&ez, design, &sigmap), ce(module)
+ FreduceHelper(RTLIL::Design *design, RTLIL::Module *module, bool try_mode) :
+ design(design), module(module), try_mode(try_mode),
+ sigmap(module), satgen(&ez, design, &sigmap), ce(module)
{
ct.setup_internals();
ct.setup_stdcells();
xorshift32();
}
- void run_test(RTLIL::SigSpec test_vec)
+ bool run_test(RTLIL::SigSpec test_vec)
{
ce.clear();
ce.set(input_sigs, test_vec.as_const());
for (auto &bit : nodes.bits) {
RTLIL::SigSpec nodesig(bit.first, 1, bit.second), nodeval = nodesig;
- if (!ce.eval(nodeval))
- log_error("Evaluation of node %s failed!\n", log_signal(nodesig));
+ if (!ce.eval(nodeval)) {
+ if (!try_mode)
+ log_error("Evaluation of node %s failed!\n", log_signal(nodesig));
+ log("FAILED: Evaluation of node %s failed!\n", log_signal(nodesig));
+ return false;
+ }
node_to_data[nodesig].bits.push_back(nodeval.as_const().bits.at(0));
}
+
+ return true;
}
void dump_node_data()
log(" %-*s %s\n", max_node_len+5, log_signal(it.first), log_signal(it.second));
}
- void check(RTLIL::SigSpec sig1, RTLIL::SigSpec sig2)
+ bool check(RTLIL::SigSpec sig1, RTLIL::SigSpec sig2)
{
log(" performing SAT proof: %s == %s ->", log_signal(sig1), log_signal(sig2));
testvect_sig.optimize();
log(" failed: %s\n", log_signal(testvect_sig));
test_vectors.push_back(testvect_sig.as_const());
- run_test(testvect_sig);
+ if (!run_test(testvect_sig))
+ return false;
} else {
log(" success.\n");
if (!sig1.is_fully_const())
if (!sig2.is_fully_const())
node_result[sig2].append(sig1);
}
+ return true;
}
- void analyze_const()
+ bool analyze_const()
{
for (auto &it : node_to_data)
{
if (node_result.count(it.first))
continue;
if (it.second == RTLIL::Const(RTLIL::State::S0, it.second.bits.size()))
- check(it.first, RTLIL::SigSpec(RTLIL::State::S0));
+ if (!check(it.first, RTLIL::SigSpec(RTLIL::State::S0)))
+ return false;
if (it.second == RTLIL::Const(RTLIL::State::S1, it.second.bits.size()))
- check(it.first, RTLIL::SigSpec(RTLIL::State::S1));
+ if (!check(it.first, RTLIL::SigSpec(RTLIL::State::S1)))
+ return false;
}
+ return true;
}
- void analyze_alias()
+ bool analyze_alias()
{
restart:
std::map<RTLIL::Const, RTLIL::SigSpec> reverse_map;
continue;
if (node_to_data.at(sig1) != node_to_data.at(sig2))
goto restart;
- check(it.second.chunks.at(i), it.second.chunks.at(j));
+ if (!check(it.second.chunks.at(i), it.second.chunks.at(j)))
+ return false;
}
}
+ return true;
}
bool toproot_helper(RTLIL::SigSpec cursor, RTLIL::SigSpec stoplist, int level)
}
for (auto &test_vec : test_vectors)
- run_test(test_vec);
+ if (!run_test(test_vec))
+ return;
// run the analysis and update design
- analyze_const();
- analyze_alias();
+ if (!analyze_const())
+ return;
+
+ if (!analyze_alias())
+ return;
log(" input vector: %s\n", log_signal(input_sigs));
for (auto &test_vec : test_vectors)
log("equivialent, they are merged to one node and one of the redundant drivers is\n");
log("removed.\n");
log("\n");
+ log(" -try\n");
+ log(" do not issue an error when the analysis fails.\n");
+ log(" (usually beacause of logic loops in the design)\n");
+ log("\n");
// log(" -enable_invert\n");
// log(" also detect nodes that are inverse to each other.\n");
// log("\n");
virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
{
bool enable_invert = false;
+ bool try_mode = false;
log_header("Executing FREDUCE pass (perform functional reduction).\n");
enable_invert = true;
continue;
}
+ if (args[argidx] == "-try") {
+ try_mode = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
{
RTLIL::Module *module = mod_it.second;
if (design->selected(module))
- FreduceHelper(design, module).run();
+ FreduceHelper(design, module, try_mode).run();
}
}
} FreducePass;