3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-12 20:18:20 +00:00

Added -try option to freduce pass

This commit is contained in:
Clifford Wolf 2013-08-08 10:56:27 +02:00
parent 8cd153612e
commit 6a40e46a04

View file

@ -36,6 +36,7 @@ struct FreduceHelper
{ {
RTLIL::Design *design; RTLIL::Design *design;
RTLIL::Module *module; RTLIL::Module *module;
bool try_mode;
ezDefaultSAT ez; ezDefaultSAT ez;
SigMap sigmap; SigMap sigmap;
@ -60,8 +61,9 @@ struct FreduceHelper
return xorshift32_state; return xorshift32_state;
} }
FreduceHelper(RTLIL::Design *design, RTLIL::Module *module) : FreduceHelper(RTLIL::Design *design, RTLIL::Module *module, bool try_mode) :
design(design), module(module), sigmap(module), satgen(&ez, design, &sigmap), ce(module) design(design), module(module), try_mode(try_mode),
sigmap(module), satgen(&ez, design, &sigmap), ce(module)
{ {
ct.setup_internals(); ct.setup_internals();
ct.setup_stdcells(); ct.setup_stdcells();
@ -72,17 +74,23 @@ struct FreduceHelper
xorshift32(); xorshift32();
} }
void run_test(RTLIL::SigSpec test_vec) bool run_test(RTLIL::SigSpec test_vec)
{ {
ce.clear(); ce.clear();
ce.set(input_sigs, test_vec.as_const()); ce.set(input_sigs, test_vec.as_const());
for (auto &bit : nodes.bits) { for (auto &bit : nodes.bits) {
RTLIL::SigSpec nodesig(bit.first, 1, bit.second), nodeval = nodesig; RTLIL::SigSpec nodesig(bit.first, 1, bit.second), nodeval = nodesig;
if (!ce.eval(nodeval)) if (!ce.eval(nodeval)) {
log_error("Evaluation of node %s failed!\n", log_signal(nodesig)); 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)); node_to_data[nodesig].bits.push_back(nodeval.as_const().bits.at(0));
} }
return true;
} }
void dump_node_data() 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)); 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)); log(" performing SAT proof: %s == %s ->", log_signal(sig1), log_signal(sig2));
@ -111,7 +119,8 @@ struct FreduceHelper
testvect_sig.optimize(); testvect_sig.optimize();
log(" failed: %s\n", log_signal(testvect_sig)); log(" failed: %s\n", log_signal(testvect_sig));
test_vectors.push_back(testvect_sig.as_const()); test_vectors.push_back(testvect_sig.as_const());
run_test(testvect_sig); if (!run_test(testvect_sig))
return false;
} else { } else {
log(" success.\n"); log(" success.\n");
if (!sig1.is_fully_const()) if (!sig1.is_fully_const())
@ -119,22 +128,26 @@ struct FreduceHelper
if (!sig2.is_fully_const()) if (!sig2.is_fully_const())
node_result[sig2].append(sig1); node_result[sig2].append(sig1);
} }
return true;
} }
void analyze_const() bool analyze_const()
{ {
for (auto &it : node_to_data) for (auto &it : node_to_data)
{ {
if (node_result.count(it.first)) if (node_result.count(it.first))
continue; continue;
if (it.second == RTLIL::Const(RTLIL::State::S0, it.second.bits.size())) 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())) 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: restart:
std::map<RTLIL::Const, RTLIL::SigSpec> reverse_map; std::map<RTLIL::Const, RTLIL::SigSpec> reverse_map;
@ -158,9 +171,11 @@ struct FreduceHelper
continue; continue;
if (node_to_data.at(sig1) != node_to_data.at(sig2)) if (node_to_data.at(sig1) != node_to_data.at(sig2))
goto restart; 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) bool toproot_helper(RTLIL::SigSpec cursor, RTLIL::SigSpec stoplist, int level)
@ -323,12 +338,16 @@ struct FreduceHelper
} }
for (auto &test_vec : test_vectors) for (auto &test_vec : test_vectors)
run_test(test_vec); if (!run_test(test_vec))
return;
// run the analysis and update design // run the analysis and update design
analyze_const(); if (!analyze_const())
analyze_alias(); return;
if (!analyze_alias())
return;
log(" input vector: %s\n", log_signal(input_sigs)); log(" input vector: %s\n", log_signal(input_sigs));
for (auto &test_vec : test_vectors) 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("equivialent, they are merged to one node and one of the redundant drivers is\n");
log("removed.\n"); log("removed.\n");
log("\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(" -enable_invert\n");
// log(" also detect nodes that are inverse to each other.\n"); // log(" also detect nodes that are inverse to each other.\n");
// log("\n"); // log("\n");
@ -360,6 +383,7 @@ struct FreducePass : public Pass {
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
{ {
bool enable_invert = false; bool enable_invert = false;
bool try_mode = false;
log_header("Executing FREDUCE pass (perform functional reduction).\n"); log_header("Executing FREDUCE pass (perform functional reduction).\n");
@ -369,6 +393,10 @@ struct FreducePass : public Pass {
enable_invert = true; enable_invert = true;
continue; continue;
} }
if (args[argidx] == "-try") {
try_mode = true;
continue;
}
break; break;
} }
extra_args(args, argidx, design); extra_args(args, argidx, design);
@ -377,7 +405,7 @@ struct FreducePass : public Pass {
{ {
RTLIL::Module *module = mod_it.second; RTLIL::Module *module = mod_it.second;
if (design->selected(module)) if (design->selected(module))
FreduceHelper(design, module).run(); FreduceHelper(design, module, try_mode).run();
} }
} }
} FreducePass; } FreducePass;