Rename "adders" to "extract_fa"
authorClifford Wolf <clifford@clifford.at>
Fri, 25 Aug 2017 10:04:40 +0000 (12:04 +0200)
committerClifford Wolf <clifford@clifford.at>
Fri, 25 Aug 2017 10:04:40 +0000 (12:04 +0200)
passes/techmap/Makefile.inc
passes/techmap/adders.cc [deleted file]
passes/techmap/extract_fa.cc [new file with mode: 0644]

index 418cc6c2bb066df82a38ea2012a0d3ea3020b015..ce67b711d07effe3d0f4b43a29b5fd182abaecc4 100644 (file)
@@ -16,6 +16,7 @@ ifneq ($(SMALL),1)
 OBJS += passes/techmap/iopadmap.o
 OBJS += passes/techmap/hilomap.o
 OBJS += passes/techmap/extract.o
+OBJS += passes/techmap/extract_fa.o
 OBJS += passes/techmap/alumacc.o
 OBJS += passes/techmap/dff2dffe.o
 OBJS += passes/techmap/dffinit.o
@@ -32,7 +33,6 @@ OBJS += passes/techmap/insbuf.o
 OBJS += passes/techmap/attrmvcp.o
 OBJS += passes/techmap/attrmap.o
 OBJS += passes/techmap/zinit.o
-OBJS += passes/techmap/adders.o
 endif
 
 GENFILES += passes/techmap/techmap.inc
diff --git a/passes/techmap/adders.cc b/passes/techmap/adders.cc
deleted file mode 100644 (file)
index 9428206..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- *  yosys -- Yosys Open SYnthesis Suite
- *
- *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
- *
- *  Permission to use, copy, modify, and/or distribute this software for any
- *  purpose with or without fee is hereby granted, provided that the above
- *  copyright notice and this permission notice appear in all copies.
- *
- *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-#include "kernel/yosys.h"
-#include "kernel/sigtools.h"
-#include "kernel/consteval.h"
-
-USING_YOSYS_NAMESPACE
-PRIVATE_NAMESPACE_BEGIN
-
-struct AddersConfig
-{
-       bool enable_fa = false;
-       bool enable_ha = false;
-       bool enable_fs = false;
-       bool enable_hs = false;
-};
-
-// http://svn.clifford.at/handicraft/2016/bindec/bindec.c
-int bindec(unsigned char v)
-{
-       int r = v & 1;
-       r += (~((v & 2) - 1)) & 10;
-       r += (~((v & 4) - 1)) & 100;
-       r += (~((v & 8) - 1)) & 1000;
-       r += (~((v & 16) - 1)) & 10000;
-       r += (~((v & 32) - 1)) & 100000;
-       r += (~((v & 64) - 1)) & 1000000;
-       r += (~((v & 128) - 1)) & 10000000;
-       return r;
-}
-
-struct AddersWorker
-{
-       const AddersConfig &config;
-       Module *module;
-       ConstEval ce;
-       SigMap &sigmap;
-
-       dict<SigBit, Cell*> driver;
-       pool<SigBit> handled_bits;
-
-       pool<tuple<SigBit, SigBit>> xorxnor2;
-       pool<tuple<SigBit, SigBit, SigBit>> xorxnor3;
-
-       dict<tuple<SigBit, SigBit>, dict<int, pool<SigBit>>> func2;
-       dict<tuple<SigBit, SigBit, SigBit>, dict<int, pool<SigBit>>> func3;
-
-       AddersWorker(const AddersConfig &config, Module *module) :
-                       config(config), module(module), ce(module), sigmap(ce.assign_map)
-       {
-               for (auto cell : module->selected_cells())
-               {
-                       if (cell->type.in( "$_BUF_", "$_NOT_", "$_AND_", "$_NAND_", "$_OR_", "$_NOR_",
-                                       "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$_MUX_",
-                                       "$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_"))
-                       {
-                               SigBit y = sigmap(SigBit(cell->getPort("\\Y")));
-                               log_assert(driver.count(y) == 0);
-                               driver[y] = cell;
-                       }
-               }
-       }
-
-       void check_partition(SigBit root, pool<SigBit> &leaves)
-       {
-               if (GetSize(leaves) == 2)
-               {
-                       leaves.sort();
-
-                       SigBit A = SigSpec(leaves)[0];
-                       SigBit B = SigSpec(leaves)[1];
-
-                       int func = 0;
-                       for (int i = 0; i < 4; i++)
-                       {
-                               bool a_value = (i & 1) != 0;
-                               bool b_value = (i & 2) != 0;
-
-                               ce.push();
-                               ce.set(A, a_value ? State::S1 : State::S0);
-                               ce.set(B, b_value ? State::S1 : State::S0);
-
-                               SigSpec sig = root;
-
-                               if (!ce.eval(sig))
-                                       log_abort();
-
-                               if (sig == State::S1)
-                                       func |= 1 << i;
-
-                               ce.pop();
-                       }
-
-                       // log("%04d %s %s -> %s\n", bindec(func), log_signal(A), log_signal(B), log_signal(root));
-
-                       if (func == 0x6 || func == 0x9)
-                               xorxnor2.insert(tuple<SigBit, SigBit>(A, B));
-
-                       func2[tuple<SigBit, SigBit>(A, B)][func].insert(root);
-               }
-
-               if (GetSize(leaves) == 3)
-               {
-                       leaves.sort();
-
-                       SigBit A = SigSpec(leaves)[0];
-                       SigBit B = SigSpec(leaves)[1];
-                       SigBit C = SigSpec(leaves)[2];
-
-                       int func = 0;
-                       for (int i = 0; i < 8; i++)
-                       {
-                               bool a_value = (i & 1) != 0;
-                               bool b_value = (i & 2) != 0;
-                               bool c_value = (i & 4) != 0;
-
-                               ce.push();
-                               ce.set(A, a_value ? State::S1 : State::S0);
-                               ce.set(B, b_value ? State::S1 : State::S0);
-                               ce.set(C, c_value ? State::S1 : State::S0);
-
-                               SigSpec sig = root;
-
-                               if (!ce.eval(sig))
-                                       log_abort();
-
-                               if (sig == State::S1)
-                                       func |= 1 << i;
-
-                               ce.pop();
-                       }
-
-                       // log("%08d %s %s %s -> %s\n", bindec(func), log_signal(A), log_signal(B), log_signal(C), log_signal(root));
-
-                       if (func == 0x69 || func == 0x96)
-                               xorxnor3.insert(tuple<SigBit, SigBit, SigBit>(A, B, C));
-
-                       func3[tuple<SigBit, SigBit, SigBit>(A, B, C)][func].insert(root);
-               }
-       }
-
-       void find_partitions(SigBit root, pool<SigBit> &leaves, pool<pool<SigBit>> &cache, int maxdepth, int maxbreadth)
-       {
-               if (cache.count(leaves))
-                       return;
-
-               cache.insert(leaves);
-               check_partition(root, leaves);
-
-               if (maxdepth == 0)
-                       return;
-
-               for (SigBit bit : leaves)
-               {
-                       if (driver.count(bit) == 0)
-                               continue;
-
-                       Cell *cell = driver.at(bit);
-                       pool<SigBit> new_leaves = leaves;
-
-                       new_leaves.erase(bit);
-                       if (cell->hasPort("\\A")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\A"))));
-                       if (cell->hasPort("\\B")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\B"))));
-                       if (cell->hasPort("\\C")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\C"))));
-                       if (cell->hasPort("\\D")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\D"))));
-
-                       if (GetSize(new_leaves) > maxbreadth)
-                               continue;
-
-                       find_partitions(root, new_leaves, cache, maxdepth-1, maxbreadth);
-               }
-       }
-
-       void run()
-       {
-               for (auto it : driver)
-               {
-                       SigBit root = it.first;
-                       pool<SigBit> leaves = { root };
-                       pool<pool<SigBit>> cache;
-
-                       find_partitions(root, leaves, cache, 5, 10);
-               }
-
-               for (auto &key : xorxnor3)
-               {
-                       SigBit A = get<0>(key);
-                       SigBit B = get<1>(key);
-                       SigBit C = get<2>(key);
-
-                       log("3-Input XOR/XNOR %s %s %s:\n", log_signal(A), log_signal(B), log_signal(C));
-
-                       for (auto &it : func3.at(key)) {
-                               log("    %08d ->", bindec(it.first));
-                               for (auto bit : it.second)
-                                       log(" %s", log_signal(bit));
-                               log("\n");
-                       }
-               }
-
-               for (auto &key : xorxnor2)
-               {
-                       SigBit A = get<0>(key);
-                       SigBit B = get<1>(key);
-
-                       log("2-Input XOR/XNOR %s %s:\n", log_signal(A), log_signal(B));
-
-                       for (auto &it : func2.at(key)) {
-                               log("    %04d ->", bindec(it.first));
-                               for (auto bit : it.second)
-                                       log(" %s", log_signal(bit));
-                               log("\n");
-                       }
-               }
-       }
-};
-
-struct AddersPass : public Pass {
-       AddersPass() : Pass("adders", "find and extract full/half adders/subtractors") { }
-       virtual void help()
-       {
-               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
-               log("\n");
-               log("    adders [options] [selection]\n");
-               log("\n");
-               log("This pass extracts full/half adders/subtractors from a gate-level design.\n");
-               log("\n");
-               log("    -fa, -ha, -fs, -hs\n");
-               log("        Enable cell types (f=full, h=half, a=adder, s=subtractor)\n");
-               log("        All types are enabled if none of this options is used\n");
-               log("\n");
-       }
-       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
-       {
-               AddersConfig config;
-
-               log_header(design, "Executing ADDERS pass (find and extract full/half adders/subtractors).\n");
-               log_push();
-
-               size_t argidx;
-               for (argidx = 1; argidx < args.size(); argidx++)
-               {
-                       if (args[argidx] == "-fa") {
-                               config.enable_fa = true;
-                               continue;
-                       }
-                       if (args[argidx] == "-ha") {
-                               config.enable_ha = true;
-                               continue;
-                       }
-                       if (args[argidx] == "-fs") {
-                               config.enable_fs = true;
-                               continue;
-                       }
-                       if (args[argidx] == "-hs") {
-                               config.enable_hs = true;
-                               continue;
-                       }
-                       break;
-               }
-               extra_args(args, argidx, design);
-
-               if (!config.enable_fa && !config.enable_ha && !config.enable_fs && !config.enable_hs) {
-                       config.enable_fa = true;
-                       config.enable_ha = true;
-                       config.enable_fs = true;
-                       config.enable_hs = true;
-               }
-
-               for (auto module : design->selected_modules())
-               {
-                       AddersWorker worker(config, module);
-                       worker.run();
-               }
-
-               log_pop();
-       }
-} AddersPass;
-
-PRIVATE_NAMESPACE_END
diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc
new file mode 100644 (file)
index 0000000..3f040e0
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+#include "kernel/consteval.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct ExtractFaConfig
+{
+       bool enable_fa = false;
+       bool enable_ha = false;
+};
+
+// http://svn.clifford.at/handicraft/2016/bindec/bindec.c
+int bindec(unsigned char v)
+{
+       int r = v & 1;
+       r += (~((v & 2) - 1)) & 10;
+       r += (~((v & 4) - 1)) & 100;
+       r += (~((v & 8) - 1)) & 1000;
+       r += (~((v & 16) - 1)) & 10000;
+       r += (~((v & 32) - 1)) & 100000;
+       r += (~((v & 64) - 1)) & 1000000;
+       r += (~((v & 128) - 1)) & 10000000;
+       return r;
+}
+
+struct ExtractFaWorker
+{
+       const ExtractFaConfig &config;
+       Module *module;
+       ConstEval ce;
+       SigMap &sigmap;
+
+       dict<SigBit, Cell*> driver;
+       pool<SigBit> handled_bits;
+
+       pool<tuple<SigBit, SigBit>> xorxnor2;
+       pool<tuple<SigBit, SigBit, SigBit>> xorxnor3;
+
+       dict<tuple<SigBit, SigBit>, dict<int, pool<SigBit>>> func2;
+       dict<tuple<SigBit, SigBit, SigBit>, dict<int, pool<SigBit>>> func3;
+
+       ExtractFaWorker(const ExtractFaConfig &config, Module *module) :
+                       config(config), module(module), ce(module), sigmap(ce.assign_map)
+       {
+               for (auto cell : module->selected_cells())
+               {
+                       if (cell->type.in( "$_BUF_", "$_NOT_", "$_AND_", "$_NAND_", "$_OR_", "$_NOR_",
+                                       "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_", "$_MUX_",
+                                       "$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_"))
+                       {
+                               SigBit y = sigmap(SigBit(cell->getPort("\\Y")));
+                               log_assert(driver.count(y) == 0);
+                               driver[y] = cell;
+                       }
+               }
+       }
+
+       void check_partition(SigBit root, pool<SigBit> &leaves)
+       {
+               if (GetSize(leaves) == 2)
+               {
+                       leaves.sort();
+
+                       SigBit A = SigSpec(leaves)[0];
+                       SigBit B = SigSpec(leaves)[1];
+
+                       int func = 0;
+                       for (int i = 0; i < 4; i++)
+                       {
+                               bool a_value = (i & 1) != 0;
+                               bool b_value = (i & 2) != 0;
+
+                               ce.push();
+                               ce.set(A, a_value ? State::S1 : State::S0);
+                               ce.set(B, b_value ? State::S1 : State::S0);
+
+                               SigSpec sig = root;
+
+                               if (!ce.eval(sig))
+                                       log_abort();
+
+                               if (sig == State::S1)
+                                       func |= 1 << i;
+
+                               ce.pop();
+                       }
+
+                       // log("%04d %s %s -> %s\n", bindec(func), log_signal(A), log_signal(B), log_signal(root));
+
+                       if (func == 0x6 || func == 0x9)
+                               xorxnor2.insert(tuple<SigBit, SigBit>(A, B));
+
+                       func2[tuple<SigBit, SigBit>(A, B)][func].insert(root);
+               }
+
+               if (GetSize(leaves) == 3)
+               {
+                       leaves.sort();
+
+                       SigBit A = SigSpec(leaves)[0];
+                       SigBit B = SigSpec(leaves)[1];
+                       SigBit C = SigSpec(leaves)[2];
+
+                       int func = 0;
+                       for (int i = 0; i < 8; i++)
+                       {
+                               bool a_value = (i & 1) != 0;
+                               bool b_value = (i & 2) != 0;
+                               bool c_value = (i & 4) != 0;
+
+                               ce.push();
+                               ce.set(A, a_value ? State::S1 : State::S0);
+                               ce.set(B, b_value ? State::S1 : State::S0);
+                               ce.set(C, c_value ? State::S1 : State::S0);
+
+                               SigSpec sig = root;
+
+                               if (!ce.eval(sig))
+                                       log_abort();
+
+                               if (sig == State::S1)
+                                       func |= 1 << i;
+
+                               ce.pop();
+                       }
+
+                       // log("%08d %s %s %s -> %s\n", bindec(func), log_signal(A), log_signal(B), log_signal(C), log_signal(root));
+
+                       if (func == 0x69 || func == 0x96)
+                               xorxnor3.insert(tuple<SigBit, SigBit, SigBit>(A, B, C));
+
+                       func3[tuple<SigBit, SigBit, SigBit>(A, B, C)][func].insert(root);
+               }
+       }
+
+       void find_partitions(SigBit root, pool<SigBit> &leaves, pool<pool<SigBit>> &cache, int maxdepth, int maxbreadth)
+       {
+               if (cache.count(leaves))
+                       return;
+
+               cache.insert(leaves);
+               check_partition(root, leaves);
+
+               if (maxdepth == 0)
+                       return;
+
+               for (SigBit bit : leaves)
+               {
+                       if (driver.count(bit) == 0)
+                               continue;
+
+                       Cell *cell = driver.at(bit);
+                       pool<SigBit> new_leaves = leaves;
+
+                       new_leaves.erase(bit);
+                       if (cell->hasPort("\\A")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\A"))));
+                       if (cell->hasPort("\\B")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\B"))));
+                       if (cell->hasPort("\\C")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\C"))));
+                       if (cell->hasPort("\\D")) new_leaves.insert(sigmap(SigBit(cell->getPort("\\D"))));
+
+                       if (GetSize(new_leaves) > maxbreadth)
+                               continue;
+
+                       find_partitions(root, new_leaves, cache, maxdepth-1, maxbreadth);
+               }
+       }
+
+       void run()
+       {
+               for (auto it : driver)
+               {
+                       SigBit root = it.first;
+                       pool<SigBit> leaves = { root };
+                       pool<pool<SigBit>> cache;
+
+                       find_partitions(root, leaves, cache, 5, 10);
+               }
+
+               for (auto &key : xorxnor3)
+               {
+                       SigBit A = get<0>(key);
+                       SigBit B = get<1>(key);
+                       SigBit C = get<2>(key);
+
+                       log("3-Input XOR/XNOR %s %s %s:\n", log_signal(A), log_signal(B), log_signal(C));
+
+                       for (auto &it : func3.at(key)) {
+                               log("    %08d ->", bindec(it.first));
+                               for (auto bit : it.second)
+                                       log(" %s", log_signal(bit));
+                               log("\n");
+                       }
+               }
+
+               for (auto &key : xorxnor2)
+               {
+                       SigBit A = get<0>(key);
+                       SigBit B = get<1>(key);
+
+                       log("2-Input XOR/XNOR %s %s:\n", log_signal(A), log_signal(B));
+
+                       for (auto &it : func2.at(key)) {
+                               log("    %04d ->", bindec(it.first));
+                               for (auto bit : it.second)
+                                       log(" %s", log_signal(bit));
+                               log("\n");
+                       }
+               }
+       }
+};
+
+struct ExtractFaPass : public Pass {
+       ExtractFaPass() : Pass("extract_fa", "find and extract full/half adders") { }
+       virtual void help()
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    extract_fa [options] [selection]\n");
+               log("\n");
+               log("This pass extracts full/half adders from a gate-level design.\n");
+               log("\n");
+               log("    -fa, -ha\n");
+               log("        Enable cell types (fa=full adder, ha=half adder)\n");
+               log("        All types are enabled if none of this options is used\n");
+               log("\n");
+       }
+       virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+       {
+               ExtractFaConfig config;
+
+               log_header(design, "Executing EXTRACT_FA pass (find and extract full/half adders).\n");
+               log_push();
+
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       if (args[argidx] == "-fa") {
+                               config.enable_fa = true;
+                               continue;
+                       }
+                       if (args[argidx] == "-ha") {
+                               config.enable_ha = true;
+                               continue;
+                       }
+                       break;
+               }
+               extra_args(args, argidx, design);
+
+               if (!config.enable_fa && !config.enable_ha) {
+                       config.enable_fa = true;
+                       config.enable_ha = true;
+               }
+
+               for (auto module : design->selected_modules())
+               {
+                       ExtractFaWorker worker(config, module);
+                       worker.run();
+               }
+
+               log_pop();
+       }
+} ExtractFaPass;
+
+PRIVATE_NAMESPACE_END