Improve net priorities in EDIF back-end
authorClaire Wolf <claire@symbioticeda.com>
Tue, 21 Apr 2020 10:35:25 +0000 (12:35 +0200)
committerClaire Wolf <claire@symbioticeda.com>
Tue, 21 Apr 2020 10:35:25 +0000 (12:35 +0200)
Signed-off-by: Claire Wolf <claire@symbioticeda.com>
backends/edif/edif.cc

index d07e0fa12e08dd01a8c550568f55194ea648516b..7e24468c03d8fb1d2f07b1024954a3e9e6dffff0 100644 (file)
@@ -345,6 +345,70 @@ struct EdifBackend : public Backend {
                        *f << stringf("        (viewType NETLIST)\n");
                        *f << stringf("        (interface\n");
 
+                       for (auto cell : module->cells()) {
+                               for (auto &conn : cell->connections())
+                                       if (cell->output(conn.first))
+                                               sigmap.add(conn.second);
+                       }
+
+                       for (auto wire : module->wires())
+                               for (auto b1 : SigSpec(wire))
+                               {
+                                       auto b2 = sigmap(b1);
+
+                                       if (b1 == b2 || !b2.wire)
+                                               continue;
+
+                                       log_assert(b1.wire != nullptr);
+
+                                       Wire *w1 = b1.wire;
+                                       Wire *w2 = b2.wire;
+
+                                       {
+                                               int c1 = w1->get_bool_attribute(ID::keep);
+                                               int c2 = w2->get_bool_attribute(ID::keep);
+
+                                               if (c1 > c2) goto promote;
+                                               if (c1 < c2) goto nopromote;
+                                       }
+
+                                       {
+                                               int c1 = w1->name[0] == '\\';
+                                               int c2 = w2->name[0] == '\\';
+
+                                               if (c1 > c2) goto promote;
+                                               if (c1 < c2) goto nopromote;
+                                       }
+
+                                       {
+                                               auto count_nontrivial_attr = [](Wire *w) {
+                                                       int count = w->attributes.size();
+                                                       count -= w->attributes.count(ID::src);
+                                                       count -= w->attributes.count(ID::unused_bits);
+                                                       return count;
+                                               };
+
+                                               int c1 = count_nontrivial_attr(w1);
+                                               int c2 = count_nontrivial_attr(w2);
+
+                                               if (c1 > c2) goto promote;
+                                               if (c1 < c2) goto nopromote;
+                                       }
+
+                                       {
+                                               int c1 = w1->port_id ? INT_MAX - w1->port_id : 0;
+                                               int c2 = w2->port_id ? INT_MAX - w2->port_id : 0;
+
+                                               if (c1 > c2) goto promote;
+                                               if (c1 < c2) goto nopromote;
+                                       }
+
+                               nopromote:
+                                       if (0)
+                               promote:
+                                               sigmap.add(b1);
+                               }
+
                        for (auto wire : module->wires()) {
                                if (wire->port_id == 0)
                                        continue;