Add "autoname" pass and use it in "synth_ice40"
authorClifford Wolf <clifford@clifford.at>
Wed, 13 Nov 2019 12:41:16 +0000 (13:41 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 13 Nov 2019 12:41:16 +0000 (13:41 +0100)
Signed-off-by: Clifford Wolf <clifford@clifford.at>
passes/cmds/Makefile.inc
passes/cmds/autoname.cc [new file with mode: 0644]
techlibs/ice40/synth_ice40.cc

index cf9663d1d207a6c714d95b71e70d631243e3ba53..c7edc30fbdbfe56531bdef8138bcebcb8c308f68 100644 (file)
@@ -5,6 +5,7 @@ OBJS += passes/cmds/design.o
 OBJS += passes/cmds/select.o
 OBJS += passes/cmds/show.o
 OBJS += passes/cmds/rename.o
+OBJS += passes/cmds/autoname.o
 OBJS += passes/cmds/connect.o
 OBJS += passes/cmds/scatter.o
 OBJS += passes/cmds/setundef.o
diff --git a/passes/cmds/autoname.cc b/passes/cmds/autoname.cc
new file mode 100644 (file)
index 0000000..4614a81
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ *  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"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+int autoname_worker(Module *module)
+{
+       dict<Cell*, pair<int, IdString>> proposed_cell_names;
+       dict<Wire*, pair<int, IdString>> proposed_wire_names;
+       dict<Wire*, int> wire_score;
+       int best_score = -1;
+
+       for (auto cell : module->selected_cells())
+       for (auto &conn : cell->connections())
+       for (auto bit : conn.second)
+               if (bit.wire != nullptr)
+                       wire_score[bit.wire]++;
+
+       for (auto cell : module->selected_cells()) {
+               if (cell->name[0] == '$') {
+                       for (auto &conn : cell->connections()) {
+                               string suffix = stringf("_%s_%s", log_id(cell->type), log_id(conn.first));
+                               for (auto bit : conn.second)
+                                       if (bit.wire != nullptr && bit.wire->name[0] != '$') {
+                                               IdString new_name(bit.wire->name.str() + suffix);
+                                               int score = wire_score.at(bit.wire);
+                                               if (cell->output(conn.first)) score = 0;
+                                               score = 10000*score + new_name.size();
+                                               if (!proposed_cell_names.count(cell) || score < proposed_cell_names.at(cell).first) {
+                                                       if (best_score < 0 || score < best_score)
+                                                               best_score = score;
+                                                       proposed_cell_names[cell] = make_pair(score, new_name);
+                                               }
+                                       }
+                       }
+               } else {
+                       for (auto &conn : cell->connections()) {
+                               string suffix = stringf("_%s", log_id(conn.first));
+                               for (auto bit : conn.second)
+                                       if (bit.wire != nullptr && bit.wire->name[0] == '$') {
+                                               IdString new_name(cell->name.str() + suffix);
+                                               int score = wire_score.at(bit.wire);
+                                               if (cell->output(conn.first)) score = 0;
+                                               score = 10000*score + new_name.size();
+                                               if (!proposed_wire_names.count(bit.wire) || score < proposed_wire_names.at(bit.wire).first) {
+                                                       if (best_score < 0 || score < best_score)
+                                                               best_score = score;
+                                                       proposed_wire_names[bit.wire] = make_pair(score, new_name);
+                                               }
+                                       }
+                       }
+               }
+       }
+
+       for (auto &it : proposed_cell_names) {
+               if (best_score*2 < it.second.first)
+                       continue;
+               IdString n = module->uniquify(it.second.second);
+               log_debug("Rename cell %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
+               module->rename(it.first, n);
+       }
+
+       for (auto &it : proposed_wire_names) {
+               if (best_score*2 < it.second.first)
+                       continue;
+               IdString n = module->uniquify(it.second.second);
+               log_debug("Rename wire %s in %s to %s.\n", log_id(it.first), log_id(module), log_id(n));
+               module->rename(it.first, n);
+       }
+
+       return proposed_cell_names.size() + proposed_wire_names.size();
+}
+
+struct AutonamePass : public Pass {
+       AutonamePass() : Pass("autoname", "automatically assign names to objects") { }
+       void help() YS_OVERRIDE
+       {
+               //   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+               log("\n");
+               log("    autoname [selection]\n");
+               log("\n");
+               log("Assign auto-generated public names to objects with private names (the ones\n");
+               log("with $-prefix).\n");
+               log("\n");
+       }
+       void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+       {
+               size_t argidx;
+               for (argidx = 1; argidx < args.size(); argidx++)
+               {
+                       // if (args[argidx] == "-foo") {
+                       //      foo = true;
+                       //      continue;
+                       // }
+                       break;
+               }
+
+               log_header(design, "Executing AUTONAME pass.\n");
+
+               for (auto module : design->selected_modules())
+               {
+                       int count = 0, iter = 0;
+                       while (1) {
+                               iter++;
+                               int n = autoname_worker(module);
+                               if (!n) break;
+                               count += n;
+                       }
+                       if (count > 0)
+                               log("Renamed %d objects in module %s (%d iterations).\n", count, log_id(module), iter);
+               }
+       }
+} AutonamePass;
+
+PRIVATE_NAMESPACE_END
index c942126e1b250bc163f62315f92e58bccfa86d3d..901194b06385bd9ff7bfe0931e055b6d45598000 100644 (file)
@@ -380,6 +380,7 @@ struct SynthIce40Pass : public ScriptPass
 
                if (check_label("check"))
                {
+                       run("autoname");
                        run("hierarchy -check");
                        run("stat");
                        run("check -noinit");