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

Add support for partial matches to muxcover, fixes #1091

Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
Clifford Wolf 2019-06-19 13:15:54 +02:00 committed by Eddie Hung
parent 477e566e8d
commit 40188457d1

View file

@ -57,6 +57,7 @@ struct MuxcoverWorker
bool use_mux8; bool use_mux8;
bool use_mux16; bool use_mux16;
bool nodecode; bool nodecode;
bool nopartial;
int cost_mux2; int cost_mux2;
int cost_mux4; int cost_mux4;
@ -69,6 +70,7 @@ struct MuxcoverWorker
use_mux8 = false; use_mux8 = false;
use_mux16 = false; use_mux16 = false;
nodecode = false; nodecode = false;
nopartial = false;
cost_mux2 = COST_MUX2; cost_mux2 = COST_MUX2;
cost_mux4 = COST_MUX4; cost_mux4 = COST_MUX4;
cost_mux8 = COST_MUX8; cost_mux8 = COST_MUX8;
@ -133,13 +135,20 @@ struct MuxcoverWorker
log(" Finished treeification: Found %d trees.\n", GetSize(tree_list)); log(" Finished treeification: Found %d trees.\n", GetSize(tree_list));
} }
bool follow_muxtree(SigBit &ret_bit, tree_t &tree, SigBit bit, const char *path) bool follow_muxtree(SigBit &ret_bit, tree_t &tree, SigBit bit, const char *path, bool first_layer = true)
{ {
if (*path) { if (*path) {
if (tree.muxes.count(bit) == 0) if (tree.muxes.count(bit) == 0) {
return false; if (first_layer || nopartial)
return false;
if (path[0] == 'S')
ret_bit = State::Sx;
else
ret_bit = bit;
return true;
}
char port_name[3] = {'\\', *path, 0}; char port_name[3] = {'\\', *path, 0};
return follow_muxtree(ret_bit, tree, sigmap(tree.muxes.at(bit)->getPort(port_name)), path+1); return follow_muxtree(ret_bit, tree, sigmap(tree.muxes.at(bit)->getPort(port_name)), path+1, false);
} else { } else {
ret_bit = bit; ret_bit = bit;
return true; return true;
@ -148,7 +157,7 @@ struct MuxcoverWorker
int prepare_decode_mux(SigBit &A, SigBit B, SigBit sel, SigBit bit) int prepare_decode_mux(SigBit &A, SigBit B, SigBit sel, SigBit bit)
{ {
if (A == B) if (A == B || sel == State::Sx)
return 0; return 0;
tuple<SigBit, SigBit, SigBit> key(A, B, sel); tuple<SigBit, SigBit, SigBit> key(A, B, sel);
@ -166,6 +175,9 @@ struct MuxcoverWorker
if (std::get<2>(entry)) if (std::get<2>(entry))
return 0; return 0;
if (A == State::Sx || B == State::Sx)
return 0;
return cost_mux2 / GetSize(std::get<1>(entry)); return cost_mux2 / GetSize(std::get<1>(entry));
} }
@ -183,9 +195,15 @@ struct MuxcoverWorker
implement_decode_mux(std::get<0>(key)); implement_decode_mux(std::get<0>(key));
implement_decode_mux(std::get<1>(key)); implement_decode_mux(std::get<1>(key));
module->addMuxGate(NEW_ID, std::get<0>(key), std::get<1>(key), std::get<2>(key), ctrl_bit); if (std::get<0>(key) == State::Sx) {
module->addBufGate(NEW_ID, std::get<1>(key), ctrl_bit);
} else if (std::get<1>(key) == State::Sx) {
module->addBufGate(NEW_ID, std::get<0>(key), ctrl_bit);
} else {
module->addMuxGate(NEW_ID, std::get<0>(key), std::get<1>(key), std::get<2>(key), ctrl_bit);
decode_mux_counter++;
}
std::get<2>(entry) = true; std::get<2>(entry) = true;
decode_mux_counter++;
} }
int find_best_cover(tree_t &tree, SigBit bit) int find_best_cover(tree_t &tree, SigBit bit)
@ -598,6 +616,7 @@ struct MuxcoverPass : public Pass {
bool use_mux8 = false; bool use_mux8 = false;
bool use_mux16 = false; bool use_mux16 = false;
bool nodecode = false; bool nodecode = false;
bool nopartial = false;
int cost_mux4 = COST_MUX4; int cost_mux4 = COST_MUX4;
int cost_mux8 = COST_MUX8; int cost_mux8 = COST_MUX8;
int cost_mux16 = COST_MUX16; int cost_mux16 = COST_MUX16;
@ -634,6 +653,10 @@ struct MuxcoverPass : public Pass {
nodecode = true; nodecode = true;
continue; continue;
} }
if (arg == "-nopartial") {
nopartial = true;
continue;
}
break; break;
} }
extra_args(args, argidx, design); extra_args(args, argidx, design);
@ -654,6 +677,7 @@ struct MuxcoverPass : public Pass {
worker.cost_mux8 = cost_mux8; worker.cost_mux8 = cost_mux8;
worker.cost_mux16 = cost_mux16; worker.cost_mux16 = cost_mux16;
worker.nodecode = nodecode; worker.nodecode = nodecode;
worker.nopartial = nopartial;
worker.run(); worker.run();
} }
} }