diff options
author | Clifford Wolf <clifford@clifford.at> | 2013-08-08 10:56:27 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2013-08-08 10:56:27 +0200 |
commit | 6a40e46a042ace384cabd78c7db967a271aadae7 (patch) | |
tree | 02aae8c873def0158a66a08c11e7d604d09b6934 /passes/sat/freduce.cc | |
parent | 8cd153612e92fbbb216d78e19dee105b58148f42 (diff) | |
download | yosys-6a40e46a042ace384cabd78c7db967a271aadae7.tar.gz yosys-6a40e46a042ace384cabd78c7db967a271aadae7.tar.bz2 yosys-6a40e46a042ace384cabd78c7db967a271aadae7.zip |
Added -try option to freduce pass
Diffstat (limited to 'passes/sat/freduce.cc')
-rw-r--r-- | passes/sat/freduce.cc | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/passes/sat/freduce.cc b/passes/sat/freduce.cc index c19f25294..00968c730 100644 --- a/passes/sat/freduce.cc +++ b/passes/sat/freduce.cc @@ -36,6 +36,7 @@ struct FreduceHelper { RTLIL::Design *design; RTLIL::Module *module; + bool try_mode; ezDefaultSAT ez; SigMap sigmap; @@ -60,8 +61,9 @@ struct FreduceHelper 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(); @@ -72,17 +74,23 @@ struct FreduceHelper 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() @@ -95,7 +103,7 @@ struct FreduceHelper 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)); @@ -111,7 +119,8 @@ struct FreduceHelper 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()) @@ -119,22 +128,26 @@ struct FreduceHelper 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; @@ -158,9 +171,11 @@ struct FreduceHelper 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) @@ -323,12 +338,16 @@ struct FreduceHelper } 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) @@ -353,6 +372,10 @@ struct FreducePass : public Pass { 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"); @@ -360,6 +383,7 @@ struct FreducePass : public Pass { 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"); @@ -369,6 +393,10 @@ struct FreducePass : public Pass { enable_invert = true; continue; } + if (args[argidx] == "-try") { + try_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -377,7 +405,7 @@ struct FreducePass : public Pass { { RTLIL::Module *module = mod_it.second; if (design->selected(module)) - FreduceHelper(design, module).run(); + FreduceHelper(design, module, try_mode).run(); } } } FreducePass; |