From 30abdaf3b2e0c3f21af0a7fdf2dc91ea59c7d54f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 7 Jun 2019 08:30:39 -0700 Subject: Allow muxcover costs to be changed --- passes/techmap/muxcover.cc | 54 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 12da9ed0c..32102436d 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -58,12 +58,21 @@ struct MuxcoverWorker bool use_mux16; bool nodecode; + int cost_mux2; + int cost_mux4; + int cost_mux8; + int cost_mux16; + MuxcoverWorker(Module *module) : module(module), sigmap(module) { use_mux4 = false; use_mux8 = false; use_mux16 = false; nodecode = false; + cost_mux2 = COST_MUX2; + cost_mux4 = COST_MUX4; + cost_mux8 = COST_MUX8; + cost_mux16 = COST_MUX16; decode_mux_counter = 0; } @@ -157,7 +166,7 @@ struct MuxcoverWorker if (std::get<2>(entry)) return 0; - return COST_MUX2 / GetSize(std::get<1>(entry)); + return cost_mux2 / GetSize(std::get<1>(entry)); } void implement_decode_mux(SigBit ctrl_bit) @@ -209,7 +218,7 @@ struct MuxcoverWorker mux.inputs.push_back(B); mux.selects.push_back(S1); - mux.cost += COST_MUX2; + mux.cost += cost_mux2; mux.cost += find_best_cover(tree, A); mux.cost += find_best_cover(tree, B); @@ -247,7 +256,7 @@ struct MuxcoverWorker mux.selects.push_back(S1); mux.selects.push_back(T1); - mux.cost += COST_MUX4; + mux.cost += cost_mux4; mux.cost += find_best_cover(tree, A); mux.cost += find_best_cover(tree, B); mux.cost += find_best_cover(tree, C); @@ -310,7 +319,7 @@ struct MuxcoverWorker mux.selects.push_back(T1); mux.selects.push_back(U1); - mux.cost += COST_MUX8; + mux.cost += cost_mux8; mux.cost += find_best_cover(tree, A); mux.cost += find_best_cover(tree, B); mux.cost += find_best_cover(tree, C); @@ -414,7 +423,7 @@ struct MuxcoverWorker mux.selects.push_back(U1); mux.selects.push_back(V1); - mux.cost += COST_MUX16; + mux.cost += cost_mux16; mux.cost += find_best_cover(tree, A); mux.cost += find_best_cover(tree, B); mux.cost += find_best_cover(tree, C); @@ -569,9 +578,11 @@ struct MuxcoverPass : public Pass { log("\n"); log("Cover trees of $_MUX_ cells with $_MUX{4,8,16}_ cells\n"); log("\n"); - log(" -mux4, -mux8, -mux16\n"); - log(" Use the specified types of MUXes. If none of those options are used,\n"); - log(" the effect is the same as if all of them where used.\n"); + log(" -mux4[=cost], -mux8[=cost], -mux16[=cost]\n"); + log(" Use the specified types of MUXes (with optional integer costs). If none\n"); + log(" of these options are given, the effect is the same as if all of them are.\n"); + log(" Default costs: $_MUX_ = %d, $_MUX4_ = %d,\n", COST_MUX2, COST_MUX4); + log(" $_MUX8_ = %d, $_MUX16_ = %d\n", COST_MUX8, COST_MUX16); log("\n"); log(" -nodecode\n"); log(" Do not insert decoder logic. This reduces the number of possible\n"); @@ -587,23 +598,39 @@ struct MuxcoverPass : public Pass { bool use_mux8 = false; bool use_mux16 = false; bool nodecode = false; + int cost_mux4 = COST_MUX4; + int cost_mux8 = COST_MUX8; + int cost_mux16 = COST_MUX16; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-mux4") { + const auto &arg = args[argidx]; + if (arg.size() >= 5 && arg.substr(0,5) == "-mux4") { use_mux4 = true; + if (arg.size() > 5) { + if (arg[5] != '=') break; + cost_mux4 = atoi(arg.substr(5).c_str()); + } continue; } - if (args[argidx] == "-mux8") { + if (arg.size() >= 5 && arg.substr(0,5) == "-mux8") { use_mux8 = true; + if (arg.size() > 5) { + if (arg[5] != '=') break; + cost_mux8 = atoi(arg.substr(5).c_str()); + } continue; } - if (args[argidx] == "-mux16") { + if (arg.size() >= 6 && arg.substr(0,6) == "-mux16") { use_mux16 = true; + if (arg.size() > 6) { + if (arg[6] != '=') break; + cost_mux16 = atoi(arg.substr(6).c_str()); + } continue; } - if (args[argidx] == "-nodecode") { + if (arg == "-nodecode") { nodecode = true; continue; } @@ -623,6 +650,9 @@ struct MuxcoverPass : public Pass { worker.use_mux4 = use_mux4; worker.use_mux8 = use_mux8; worker.use_mux16 = use_mux16; + worker.cost_mux4 = cost_mux4; + worker.cost_mux8 = cost_mux8; + worker.cost_mux16 = cost_mux16; worker.nodecode = nodecode; worker.run(); } -- cgit v1.2.3 From 96ade549932ca48d0e1d3b99389129cdc37524a0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 19 Jun 2019 09:51:11 -0700 Subject: Fix bug in #1078, add entry to CHANGELOG --- passes/techmap/muxcover.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 32102436d..8e44be148 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -610,7 +610,7 @@ struct MuxcoverPass : public Pass { use_mux4 = true; if (arg.size() > 5) { if (arg[5] != '=') break; - cost_mux4 = atoi(arg.substr(5).c_str()); + cost_mux4 = atoi(arg.substr(6).c_str()); } continue; } @@ -618,7 +618,7 @@ struct MuxcoverPass : public Pass { use_mux8 = true; if (arg.size() > 5) { if (arg[5] != '=') break; - cost_mux8 = atoi(arg.substr(5).c_str()); + cost_mux8 = atoi(arg.substr(6).c_str()); } continue; } @@ -626,7 +626,7 @@ struct MuxcoverPass : public Pass { use_mux16 = true; if (arg.size() > 6) { if (arg[6] != '=') break; - cost_mux16 = atoi(arg.substr(6).c_str()); + cost_mux16 = atoi(arg.substr(7).c_str()); } continue; } -- cgit v1.2.3 From 40188457d1af9bd4d905c83b29a3bf696b8666f0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 19 Jun 2019 13:15:54 +0200 Subject: Add support for partial matches to muxcover, fixes #1091 Signed-off-by: Clifford Wolf --- passes/techmap/muxcover.cc | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 8e44be148..78272b0c4 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -57,6 +57,7 @@ struct MuxcoverWorker bool use_mux8; bool use_mux16; bool nodecode; + bool nopartial; int cost_mux2; int cost_mux4; @@ -69,6 +70,7 @@ struct MuxcoverWorker use_mux8 = false; use_mux16 = false; nodecode = false; + nopartial = false; cost_mux2 = COST_MUX2; cost_mux4 = COST_MUX4; cost_mux8 = COST_MUX8; @@ -133,13 +135,20 @@ struct MuxcoverWorker 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 (tree.muxes.count(bit) == 0) - return false; + if (tree.muxes.count(bit) == 0) { + 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}; - 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 { ret_bit = bit; return true; @@ -148,7 +157,7 @@ struct MuxcoverWorker int prepare_decode_mux(SigBit &A, SigBit B, SigBit sel, SigBit bit) { - if (A == B) + if (A == B || sel == State::Sx) return 0; tuple key(A, B, sel); @@ -166,6 +175,9 @@ struct MuxcoverWorker if (std::get<2>(entry)) return 0; + if (A == State::Sx || B == State::Sx) + return 0; + 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<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; - decode_mux_counter++; } int find_best_cover(tree_t &tree, SigBit bit) @@ -598,6 +616,7 @@ struct MuxcoverPass : public Pass { bool use_mux8 = false; bool use_mux16 = false; bool nodecode = false; + bool nopartial = false; int cost_mux4 = COST_MUX4; int cost_mux8 = COST_MUX8; int cost_mux16 = COST_MUX16; @@ -634,6 +653,10 @@ struct MuxcoverPass : public Pass { nodecode = true; continue; } + if (arg == "-nopartial") { + nopartial = true; + continue; + } break; } extra_args(args, argidx, design); @@ -654,6 +677,7 @@ struct MuxcoverPass : public Pass { worker.cost_mux8 = cost_mux8; worker.cost_mux16 = cost_mux16; worker.nodecode = nodecode; + worker.nopartial = nopartial; worker.run(); } } -- cgit v1.2.3 From 891ea6512e5254803b36a2a22121bc2733ac8b9e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 20 Jun 2019 11:30:27 +0200 Subject: Improvements in muxcover - Slightly under-estimate cost of decoder muxes - Prefer larger muxes at tree root at same cost - Don't double-count input cost for partial muxes - Add debug log output --- passes/techmap/muxcover.cc | 93 +++++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 38 deletions(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 78272b0c4..e952b04b6 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -178,7 +178,7 @@ struct MuxcoverWorker if (A == State::Sx || B == State::Sx) return 0; - return cost_mux2 / GetSize(std::get<1>(entry)); + return std::max((cost_mux2 / GetSize(std::get<1>(entry))) - 1, 1); } void implement_decode_mux(SigBit ctrl_bit) @@ -206,6 +206,23 @@ struct MuxcoverWorker std::get<2>(entry) = true; } + void find_best_covers(tree_t &tree, const vector &bits) + { + for (auto bit : bits) + find_best_cover(tree, bit); + } + + int sum_best_covers(tree_t &tree, const vector &bits) + { + int sum = 0; + for (auto bit : pool(bits.begin(), bits.end())) { + int cost = tree.newmuxes.at(bit).cost; + log_debug(" Best cost for %s: %d\n", log_signal(bit), cost); + sum += cost; + } + return sum; + } + int find_best_cover(tree_t &tree, SigBit bit) { if (tree.newmuxes.count(bit)) { @@ -236,9 +253,13 @@ struct MuxcoverWorker mux.inputs.push_back(B); mux.selects.push_back(S1); + find_best_covers(tree, mux.inputs); + log_debug(" Decode cost for mux2 at %s: %d\n", log_signal(bit), mux.cost); + mux.cost += cost_mux2; - mux.cost += find_best_cover(tree, A); - mux.cost += find_best_cover(tree, B); + mux.cost += sum_best_covers(tree, mux.inputs); + + log_debug(" Cost of mux2 at %s: %d\n", log_signal(bit), mux.cost); best_mux = mux; } @@ -274,13 +295,15 @@ struct MuxcoverWorker mux.selects.push_back(S1); mux.selects.push_back(T1); + find_best_covers(tree, mux.inputs); + log_debug(" Decode cost for mux4 at %s: %d\n", log_signal(bit), mux.cost); + mux.cost += cost_mux4; - mux.cost += find_best_cover(tree, A); - mux.cost += find_best_cover(tree, B); - mux.cost += find_best_cover(tree, C); - mux.cost += find_best_cover(tree, D); + mux.cost += sum_best_covers(tree, mux.inputs); - if (best_mux.cost > mux.cost) + log_debug(" Cost of mux4 at %s: %d\n", log_signal(bit), mux.cost); + + if (best_mux.cost >= mux.cost) best_mux = mux; } } @@ -337,17 +360,15 @@ struct MuxcoverWorker mux.selects.push_back(T1); mux.selects.push_back(U1); + find_best_covers(tree, mux.inputs); + log_debug(" Decode cost for mux8 at %s: %d\n", log_signal(bit), mux.cost); + mux.cost += cost_mux8; - mux.cost += find_best_cover(tree, A); - mux.cost += find_best_cover(tree, B); - mux.cost += find_best_cover(tree, C); - mux.cost += find_best_cover(tree, D); - mux.cost += find_best_cover(tree, E); - mux.cost += find_best_cover(tree, F); - mux.cost += find_best_cover(tree, G); - mux.cost += find_best_cover(tree, H); - - if (best_mux.cost > mux.cost) + mux.cost += sum_best_covers(tree, mux.inputs); + + log_debug(" Cost of mux8 at %s: %d\n", log_signal(bit), mux.cost); + + if (best_mux.cost >= mux.cost) best_mux = mux; } } @@ -441,25 +462,15 @@ struct MuxcoverWorker mux.selects.push_back(U1); mux.selects.push_back(V1); + find_best_covers(tree, mux.inputs); + log_debug(" Decode cost for mux16 at %s: %d\n", log_signal(bit), mux.cost); + mux.cost += cost_mux16; - mux.cost += find_best_cover(tree, A); - mux.cost += find_best_cover(tree, B); - mux.cost += find_best_cover(tree, C); - mux.cost += find_best_cover(tree, D); - mux.cost += find_best_cover(tree, E); - mux.cost += find_best_cover(tree, F); - mux.cost += find_best_cover(tree, G); - mux.cost += find_best_cover(tree, H); - mux.cost += find_best_cover(tree, I); - mux.cost += find_best_cover(tree, J); - mux.cost += find_best_cover(tree, K); - mux.cost += find_best_cover(tree, L); - mux.cost += find_best_cover(tree, M); - mux.cost += find_best_cover(tree, N); - mux.cost += find_best_cover(tree, O); - mux.cost += find_best_cover(tree, P); - - if (best_mux.cost > mux.cost) + mux.cost += sum_best_covers(tree, mux.inputs); + + log_debug(" Cost of mux16 at %s: %d\n", log_signal(bit), mux.cost); + + if (best_mux.cost >= mux.cost) best_mux = mux; } } @@ -555,6 +566,7 @@ struct MuxcoverWorker void treecover(tree_t &tree) { int count_muxes_by_type[4] = {0, 0, 0, 0}; + log_debug(" Searching for best cover for tree at %s.\n", log_signal(tree.root)); find_best_cover(tree, tree.root); implement_best_cover(tree, tree.root, count_muxes_by_type); log(" Replaced tree at %s: %d MUX2, %d MUX4, %d MUX8, %d MUX16\n", log_signal(tree.root), @@ -571,12 +583,13 @@ struct MuxcoverWorker log(" Covering trees:\n"); - // pre-fill cache of decoder muxes - if (!nodecode) + if (!nodecode) { + log_debug(" Populating cache of decoder muxes.\n"); for (auto &tree : tree_list) { find_best_cover(tree, tree.root); tree.newmuxes.clear(); } + } for (auto &tree : tree_list) treecover(tree); @@ -607,6 +620,10 @@ struct MuxcoverPass : public Pass { log(" substitutions, but guarantees that the resulting circuit is not\n"); log(" less efficient than the original circuit.\n"); log("\n"); + log(" -nopartial\n"); + log(" Do not consider mappings that use $_MUX_ to select from less\n"); + log(" than different signals.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { -- cgit v1.2.3 From 9286b6f013db06b473d009dfabb5e7c1526387b1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Jun 2019 10:02:10 +0200 Subject: Add "muxcover -freedecode" Signed-off-by: Clifford Wolf --- passes/techmap/muxcover.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index e952b04b6..7fa89bbe3 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -57,6 +57,7 @@ struct MuxcoverWorker bool use_mux8; bool use_mux16; bool nodecode; + bool freedecode; bool nopartial; int cost_mux2; @@ -70,6 +71,7 @@ struct MuxcoverWorker use_mux8 = false; use_mux16 = false; nodecode = false; + freedecode = false; nopartial = false; cost_mux2 = COST_MUX2; cost_mux4 = COST_MUX4; @@ -178,6 +180,9 @@ struct MuxcoverWorker if (A == State::Sx || B == State::Sx) return 0; + if (freedecode) + return 0; + return std::max((cost_mux2 / GetSize(std::get<1>(entry))) - 1, 1); } @@ -620,6 +625,9 @@ struct MuxcoverPass : public Pass { log(" substitutions, but guarantees that the resulting circuit is not\n"); log(" less efficient than the original circuit.\n"); log("\n"); + log(" -freedecode\n"); + log(" Do not count cost for generated decode logic\n"); + log("\n"); log(" -nopartial\n"); log(" Do not consider mappings that use $_MUX_ to select from less\n"); log(" than different signals.\n"); @@ -633,6 +641,7 @@ struct MuxcoverPass : public Pass { bool use_mux8 = false; bool use_mux16 = false; bool nodecode = false; + bool freedecode = false; bool nopartial = false; int cost_mux4 = COST_MUX4; int cost_mux8 = COST_MUX8; @@ -670,6 +679,10 @@ struct MuxcoverPass : public Pass { nodecode = true; continue; } + if (arg == "-freedecode") { + freedecode = true; + continue; + } if (arg == "-nopartial") { nopartial = true; continue; @@ -694,6 +707,7 @@ struct MuxcoverPass : public Pass { worker.cost_mux8 = cost_mux8; worker.cost_mux16 = cost_mux16; worker.nodecode = nodecode; + worker.freedecode = freedecode; worker.nopartial = nopartial; worker.run(); } -- cgit v1.2.3 From ec979475e7f6bce65a4b6768cc3488a3ab02826d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 21 Jun 2019 19:24:41 +0200 Subject: Replace "muxcover -freedecode" with "muxcover -dmux=cost" Signed-off-by: Clifford Wolf --- passes/techmap/muxcover.cc | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 7fa89bbe3..b0722134e 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -23,6 +23,7 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +#define COST_DMUX 90 #define COST_MUX2 100 #define COST_MUX4 220 #define COST_MUX8 460 @@ -57,9 +58,9 @@ struct MuxcoverWorker bool use_mux8; bool use_mux16; bool nodecode; - bool freedecode; bool nopartial; + int cost_dmux; int cost_mux2; int cost_mux4; int cost_mux8; @@ -71,8 +72,8 @@ struct MuxcoverWorker use_mux8 = false; use_mux16 = false; nodecode = false; - freedecode = false; nopartial = false; + cost_dmux = COST_DMUX; cost_mux2 = COST_MUX2; cost_mux4 = COST_MUX4; cost_mux8 = COST_MUX8; @@ -180,10 +181,7 @@ struct MuxcoverWorker if (A == State::Sx || B == State::Sx) return 0; - if (freedecode) - return 0; - - return std::max((cost_mux2 / GetSize(std::get<1>(entry))) - 1, 1); + return cost_dmux / GetSize(std::get<1>(entry)); } void implement_decode_mux(SigBit ctrl_bit) @@ -620,14 +618,15 @@ struct MuxcoverPass : public Pass { log(" Default costs: $_MUX_ = %d, $_MUX4_ = %d,\n", COST_MUX2, COST_MUX4); log(" $_MUX8_ = %d, $_MUX16_ = %d\n", COST_MUX8, COST_MUX16); log("\n"); + log(" -dmux=cost\n"); + log(" Use the specified cost for $_MUX_ cells used in decoders.\n"); + log(" Default cost: %d\n", COST_DMUX); + log("\n"); log(" -nodecode\n"); log(" Do not insert decoder logic. This reduces the number of possible\n"); log(" substitutions, but guarantees that the resulting circuit is not\n"); log(" less efficient than the original circuit.\n"); log("\n"); - log(" -freedecode\n"); - log(" Do not count cost for generated decode logic\n"); - log("\n"); log(" -nopartial\n"); log(" Do not consider mappings that use $_MUX_ to select from less\n"); log(" than different signals.\n"); @@ -641,8 +640,8 @@ struct MuxcoverPass : public Pass { bool use_mux8 = false; bool use_mux16 = false; bool nodecode = false; - bool freedecode = false; bool nopartial = false; + int cost_dmux = COST_DMUX; int cost_mux4 = COST_MUX4; int cost_mux8 = COST_MUX8; int cost_mux16 = COST_MUX16; @@ -675,12 +674,12 @@ struct MuxcoverPass : public Pass { } continue; } - if (arg == "-nodecode") { - nodecode = true; + if (arg.size() >= 6 && arg.substr(0,6) == "-dmux=") { + cost_dmux = atoi(arg.substr(6).c_str()); continue; } - if (arg == "-freedecode") { - freedecode = true; + if (arg == "-nodecode") { + nodecode = true; continue; } if (arg == "-nopartial") { @@ -703,11 +702,11 @@ struct MuxcoverPass : public Pass { worker.use_mux4 = use_mux4; worker.use_mux8 = use_mux8; worker.use_mux16 = use_mux16; + worker.cost_dmux = cost_dmux; worker.cost_mux4 = cost_mux4; worker.cost_mux8 = cost_mux8; worker.cost_mux16 = cost_mux16; worker.nodecode = nodecode; - worker.freedecode = freedecode; worker.nopartial = nopartial; worker.run(); } -- cgit v1.2.3 From 69d810e4a831fc1f17d886d7f371d9785e9022e7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 27 Jun 2019 09:42:49 +0200 Subject: Fix handling of partial covers in muxcover, fixes #1132 Signed-off-by: Clifford Wolf --- passes/techmap/muxcover.cc | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index b0722134e..c84cfc39a 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -81,6 +81,23 @@ struct MuxcoverWorker decode_mux_counter = 0; } + bool xcmp(std::initializer_list list) + { + auto cursor = list.begin(), end = list.end(); + log_assert(cursor != end); + SigBit tmp = *(cursor++); + while (cursor != end) { + SigBit bit = *(cursor++); + if (bit == State::Sx) + continue; + if (tmp == State::Sx) + tmp = bit; + if (bit != tmp) + return false; + } + return true; + } + void treeify() { pool roots; @@ -144,6 +161,8 @@ struct MuxcoverWorker if (tree.muxes.count(bit) == 0) { if (first_layer || nopartial) return false; + while (path[0] && path[1]) + path++; if (path[0] == 'S') ret_bit = State::Sx; else @@ -280,7 +299,7 @@ struct MuxcoverWorker ok = ok && follow_muxtree(S2, tree, bit, "BS"); if (nodecode) - ok = ok && S1 == S2; + ok = ok && xcmp({S1, S2}); ok = ok && follow_muxtree(T1, tree, bit, "S"); @@ -330,13 +349,13 @@ struct MuxcoverWorker ok = ok && follow_muxtree(S4, tree, bit, "BBS"); if (nodecode) - ok = ok && S1 == S2 && S2 == S3 && S3 == S4; + ok = ok && xcmp({S1, S2, S3, S4}); ok = ok && follow_muxtree(T1, tree, bit, "AS"); ok = ok && follow_muxtree(T2, tree, bit, "BS"); if (nodecode) - ok = ok && T1 == T2; + ok = ok && xcmp({T1, T2}); ok = ok && follow_muxtree(U1, tree, bit, "S"); @@ -407,7 +426,7 @@ struct MuxcoverWorker ok = ok && follow_muxtree(S8, tree, bit, "BBBS"); if (nodecode) - ok = ok && S1 == S2 && S2 == S3 && S3 == S4 && S4 == S5 && S5 == S6 && S6 == S7 && S7 == S8; + ok = ok && xcmp({S1, S2, S3, S4, S5, S6, S7, S8}); ok = ok && follow_muxtree(T1, tree, bit, "AAS"); ok = ok && follow_muxtree(T2, tree, bit, "ABS"); @@ -415,13 +434,13 @@ struct MuxcoverWorker ok = ok && follow_muxtree(T4, tree, bit, "BBS"); if (nodecode) - ok = ok && T1 == T2 && T2 == T3 && T3 == T4; + ok = ok && xcmp({T1, T2, T3, T4}); ok = ok && follow_muxtree(U1, tree, bit, "AS"); ok = ok && follow_muxtree(U2, tree, bit, "BS"); if (nodecode) - ok = ok && U1 == U2; + ok = ok && xcmp({U1, U2}); ok = ok && follow_muxtree(V1, tree, bit, "S"); -- cgit v1.2.3 From a34c5612e702d481798fa7fc27cf2fef06a2b544 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 10:59:12 -0700 Subject: Add muxcover -mux2=cost option --- passes/techmap/muxcover.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index c84cfc39a..4d9c111e7 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -631,7 +631,7 @@ struct MuxcoverPass : public Pass { log("\n"); log("Cover trees of $_MUX_ cells with $_MUX{4,8,16}_ cells\n"); log("\n"); - log(" -mux4[=cost], -mux8[=cost], -mux16[=cost]\n"); + log(" -mux2=cost, -mux4[=cost], -mux8[=cost], -mux16[=cost]\n"); log(" Use the specified types of MUXes (with optional integer costs). If none\n"); log(" of these options are given, the effect is the same as if all of them are.\n"); log(" Default costs: $_MUX_ = %d, $_MUX4_ = %d,\n", COST_MUX2, COST_MUX4); @@ -661,6 +661,7 @@ struct MuxcoverPass : public Pass { bool nodecode = false; bool nopartial = false; int cost_dmux = COST_DMUX; + int cost_mux2 = COST_MUX2; int cost_mux4 = COST_MUX4; int cost_mux8 = COST_MUX8; int cost_mux16 = COST_MUX16; @@ -669,6 +670,10 @@ struct MuxcoverPass : public Pass { for (argidx = 1; argidx < args.size(); argidx++) { const auto &arg = args[argidx]; + if (arg.size() >= 6 && arg.substr(0,6) == "-mux2=") { + cost_mux2 = atoi(arg.substr(6).c_str()); + continue; + } if (arg.size() >= 5 && arg.substr(0,5) == "-mux4") { use_mux4 = true; if (arg.size() > 5) { @@ -722,6 +727,7 @@ struct MuxcoverPass : public Pass { worker.use_mux8 = use_mux8; worker.use_mux16 = use_mux16; worker.cost_dmux = cost_dmux; + worker.cost_mux2 = cost_mux2; worker.cost_mux4 = cost_mux4; worker.cost_mux8 = cost_mux8; worker.cost_mux16 = cost_mux16; -- cgit v1.2.3 From 3681162c8d6826cf5ccf5de485ba14b4200a5221 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 11:00:06 -0700 Subject: atoi -> stoi --- passes/techmap/muxcover.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index 4d9c111e7..fa97239f5 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -671,14 +671,14 @@ struct MuxcoverPass : public Pass { { const auto &arg = args[argidx]; if (arg.size() >= 6 && arg.substr(0,6) == "-mux2=") { - cost_mux2 = atoi(arg.substr(6).c_str()); + cost_mux2 = std::stoi(arg.substr(6)); continue; } if (arg.size() >= 5 && arg.substr(0,5) == "-mux4") { use_mux4 = true; if (arg.size() > 5) { if (arg[5] != '=') break; - cost_mux4 = atoi(arg.substr(6).c_str()); + cost_mux4 = std::stoi(arg.substr(6)); } continue; } @@ -686,7 +686,7 @@ struct MuxcoverPass : public Pass { use_mux8 = true; if (arg.size() > 5) { if (arg[5] != '=') break; - cost_mux8 = atoi(arg.substr(6).c_str()); + cost_mux8 = std::stoi(arg.substr(6)); } continue; } @@ -694,12 +694,12 @@ struct MuxcoverPass : public Pass { use_mux16 = true; if (arg.size() > 6) { if (arg[6] != '=') break; - cost_mux16 = atoi(arg.substr(7).c_str()); + cost_mux16 = std::stoi(arg.substr(7)); } continue; } if (arg.size() >= 6 && arg.substr(0,6) == "-dmux=") { - cost_dmux = atoi(arg.substr(6).c_str()); + cost_dmux = std::stoi(arg.substr(6)); continue; } if (arg == "-nodecode") { -- cgit v1.2.3 From b5072256f2c6b94423adb0ac1e2aec965230afe3 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 8 Jul 2019 12:50:59 -0700 Subject: Update muxcover doc as per @ZirconiumX --- passes/techmap/muxcover.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'passes/techmap/muxcover.cc') diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index fa97239f5..d53378a29 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -631,11 +631,16 @@ struct MuxcoverPass : public Pass { log("\n"); log("Cover trees of $_MUX_ cells with $_MUX{4,8,16}_ cells\n"); log("\n"); - log(" -mux2=cost, -mux4[=cost], -mux8[=cost], -mux16[=cost]\n"); - log(" Use the specified types of MUXes (with optional integer costs). If none\n"); - log(" of these options are given, the effect is the same as if all of them are.\n"); - log(" Default costs: $_MUX_ = %d, $_MUX4_ = %d,\n", COST_MUX2, COST_MUX4); - log(" $_MUX8_ = %d, $_MUX16_ = %d\n", COST_MUX8, COST_MUX16); + log(" -mux4[=cost], -mux8[=cost], -mux16[=cost]\n"); + log(" Cover $_MUX_ trees using the specified types of MUXes (with optional\n"); + log(" integer costs). If none of these options are given, the effect is the\n"); + log(" same as if all of them are.\n"); + log(" Default costs: $_MUX4_ = %d, $_MUX8_ = %d, \n", COST_MUX4, COST_MUX8); + log(" $_MUX16_ = %d\n", COST_MUX16); + log("\n"); + log(" -mux2=cost\n"); + log(" Use the specified cost for $_MUX_ cells when making covering decisions.\n"); + log(" Default cost: $_MUX_ = %d\n", COST_MUX2); log("\n"); log(" -dmux=cost\n"); log(" Use the specified cost for $_MUX_ cells used in decoders.\n"); -- cgit v1.2.3